Skip to content

Commit 088e6af

Browse files
authored
Merge branch 'master' into no-reenter
2 parents bf1d42a + 3118f8c commit 088e6af

File tree

14 files changed

+1830
-303
lines changed

14 files changed

+1830
-303
lines changed

chronos/asyncloop.nim

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,15 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
152152
defined(openbsd) or defined(dragonfly) or defined(macos) or
153153
defined(linux) or defined(android) or defined(solaris):
154154
import "."/selectors2
155-
from posix import EINTR, EAGAIN, EINPROGRESS, EWOULDBLOCK, MSG_PEEK,
156-
MSG_NOSIGNAL,
155+
import "."/oserrno
156+
from posix import MSG_PEEK, MSG_NOSIGNAL,
157157
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
158158
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
159159
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE
160160
export SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
161161
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
162162
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE
163+
export oserrno
163164

164165
type
165166
CallbackFunc* = proc (arg: pointer) {.gcsafe, raises: [Defect].}
@@ -285,6 +286,12 @@ proc raiseOsDefect*(error: OSErrorCode, msg = "") {.noreturn, noinline.} =
285286
raise (ref Defect)(msg: msg & "\n[" & $int(error) & "] " & osErrorMsg(error) &
286287
"\n" & getStackTrace())
287288

289+
func toPointer(error: OSErrorCode): pointer =
290+
when sizeof(int) == 8:
291+
cast[pointer](uint64(uint32(error)))
292+
else:
293+
cast[pointer](uint32(error))
294+
288295
func toException*(v: OSErrorCode): ref OSError = newOSError(v)
289296
# This helper will allow to use `tryGet()` and raise OSError for
290297
# Result[T, OSErrorCode] values.
@@ -511,27 +518,30 @@ when defined(windows):
511518
## Closes a socket and ensures that it is unregistered.
512519
let loop = getThreadDispatcher()
513520
loop.handles.excl(fd)
514-
let param =
515-
if closeFd(SocketHandle(fd)) == 0:
516-
OSErrorCode(0)
517-
else:
518-
osLastError()
519-
if not isNil(aftercb):
520-
var acb = AsyncCallback(function: aftercb, udata: cast[pointer](param))
521-
loop.callbacks.addLast(acb)
521+
let
522+
param = toPointer(
523+
if closeFd(SocketHandle(fd)) == 0:
524+
OSErrorCode(0)
525+
else:
526+
osLastError()
527+
)
528+
if not(isNil(aftercb)):
529+
loop.callbacks.addLast(AsyncCallback(function: aftercb, udata: param))
522530

523531
proc closeHandle*(fd: AsyncFD, aftercb: CallbackFunc = nil) =
524532
## Closes a (pipe/file) handle and ensures that it is unregistered.
525533
let loop = getThreadDispatcher()
526534
loop.handles.excl(fd)
527-
let param =
528-
if closeFd(HANDLE(fd)) == 0:
529-
OSErrorCode(0)
530-
else:
531-
osLastError()
532-
if not isNil(aftercb):
533-
var acb = AsyncCallback(function: aftercb, udata: cast[pointer](param))
534-
loop.callbacks.addLast(acb)
535+
let
536+
param = toPointer(
537+
if closeFd(HANDLE(fd)) == 0:
538+
OSErrorCode(0)
539+
else:
540+
osLastError()
541+
)
542+
543+
if not(isNil(aftercb)):
544+
loop.callbacks.addLast(AsyncCallback(function: aftercb, udata: param))
535545

536546
proc contains*(disp: PDispatcher, fd: AsyncFD): bool =
537547
## Returns ``true`` if ``fd`` is registered in thread's dispatcher.
@@ -712,21 +722,22 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
712722
let loop = getThreadDispatcher()
713723
714724
proc continuation(udata: pointer) =
715-
let param =
716-
if SocketHandle(fd) in loop.selector:
717-
let ures = unregister2(fd)
718-
if ures.isErr():
719-
discard closeFd(cint(fd))
720-
ures.error()
721-
else:
722-
if closeFd(cint(fd)) != 0:
723-
osLastError()
725+
let
726+
param = toPointer(
727+
if SocketHandle(fd) in loop.selector:
728+
let ures = unregister2(fd)
729+
if ures.isErr():
730+
discard closeFd(cint(fd))
731+
ures.error()
724732
else:
725-
OSErrorCode(0)
726-
else:
727-
OSErrorCode(osdefs.EBADF)
728-
if not isNil(aftercb):
729-
aftercb(cast[pointer](param))
733+
if closeFd(cint(fd)) != 0:
734+
osLastError()
735+
else:
736+
OSErrorCode(0)
737+
else:
738+
OSErrorCode(osdefs.EBADF)
739+
)
740+
if not(isNil(aftercb)): aftercb(param)
730741
731742
withData(loop.selector, cint(fd), adata) do:
732743
# We are scheduling reader and writer callbacks to be called

chronos/asyncsync.nim

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,10 @@ proc wakeUpFirst(lock: AsyncLock): bool {.inline.} =
154154
res = true
155155
break
156156
if i > 0:
157-
lock.waiters.delete(0, i - 1)
157+
when compiles(lock.waiters.delete(0 .. (i - 1))):
158+
lock.waiters.delete(0 .. (i - 1))
159+
else:
160+
lock.waiters.delete(0, i - 1)
158161
res
159162

160163
proc checkAll(lock: AsyncLock): bool {.inline.} =
@@ -272,7 +275,10 @@ proc wakeupNext(waiters: var seq[Future[void]]) {.inline.} =
272275
break
273276

274277
if i > 0:
275-
waiters.delete(0, i - 1)
278+
when compiles(waiters.delete(0 .. (i - 1))):
279+
waiters.delete(0 .. (i - 1))
280+
else:
281+
waiters.delete(0, i - 1)
276282

277283
proc full*[T](aq: AsyncQueue[T]): bool {.inline.} =
278284
## Return ``true`` if there are ``maxsize`` items in the queue.

chronos/ioselects/ioselectors_epoll.nim

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ proc getVirtualId[T](s: Selector[T]): SelectResult[int32] =
4242
ok(s.virtualHoles.popLast())
4343
else:
4444
if s.virtualId == low(int32):
45-
err(OSErrorCode(EMFILE))
45+
err(oserrno.EMFILE)
4646
else:
4747
dec(s.virtualId)
4848
ok(s.virtualId)
@@ -139,7 +139,7 @@ proc trigger2*(event: SelectEvent): SelectResult[void] =
139139
if res == -1:
140140
err(osLastError())
141141
elif res != sizeof(uint64):
142-
err(OSErrorCode(osdefs.EINVAL))
142+
err(oserrno.EINVAL)
143143
else:
144144
ok()
145145
@@ -521,11 +521,11 @@ proc prepareKey[T](s: Selector[T], event: EpollEvent): Opt[ReadyKey] =
521521
522522
if (event.events and EPOLLERR) != 0:
523523
rkey.events.incl(Event.Error)
524-
rkey.errorCode = OSErrorCode(ECONNRESET)
524+
rkey.errorCode = oserrno.ECONNRESET
525525
526526
if (event.events and EPOLLHUP) != 0 or (event.events and EPOLLRDHUP) != 0:
527527
rkey.events.incl(Event.Error)
528-
rkey.errorCode = OSErrorCode(ECONNRESET)
528+
rkey.errorCode = oserrno.ECONNRESET
529529
530530
if (event.events and EPOLLOUT) != 0:
531531
rkey.events.incl(Event.Write)
@@ -580,7 +580,8 @@ proc prepareKey[T](s: Selector[T], event: EpollEvent): Opt[ReadyKey] =
580580
let res = handleEintr(osdefs.read(fdi32, addr data, sizeof(uint64)))
581581
if res != sizeof(uint64):
582582
let errorCode = osLastError()
583-
if errorCode == EAGAIN:
583+
case errorCode
584+
of oserrno.EAGAIN:
584585
return Opt.none(ReadyKey)
585586
else:
586587
rkey.events.incl({Event.User, Event.Error})

chronos/ioselects/ioselectors_kqueue.nim

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ proc toString(key: int32|cint|SocketHandle|int): string =
5858
else:
5959
Base10.toString(uint32(fdi32))
6060
61+
proc toPointer(data: int32): pointer =
62+
when sizeof(int) == 8:
63+
cast[pointer](uint64(uint32(data)))
64+
else:
65+
cast[pointer](uint32(data))
66+
6167
template addKey[T](s: Selector[T], key: int32, skey: SelectorKey[T]) =
6268
if s.fds.hasKeyOrPut(key, skey):
6369
raiseAssert "Descriptor [" & key.toString() &
@@ -154,7 +160,7 @@ proc trigger2*(event: SelectEvent): SelectResult[void] =
154160
if res == -1:
155161
err(osLastError())
156162
elif res != sizeof(uint64):
157-
err(OSErrorCode(osdefs.EINVAL))
163+
err(oserrno.EINVAL)
158164
else:
159165
ok()
160166

@@ -310,7 +316,7 @@ proc registerSignal*[T](s: Selector[T], signal: int,
310316
# To be compatible with linux semantic we need to "eat" signals
311317
signal(cint(signal), SIG_IGN)
312318
changes.modifyKQueue(0, uint(signal), EVFILT_SIGNAL, EV_ADD, 0, 0,
313-
cast[pointer](uint32(fdi32)))
319+
fdi32.toPointer())
314320
if handleEintr(kevent(s.kqFd, addr(changes[0]), cint(1), nil, 0, nil)) == -1:
315321
let errorCode = osLastError()
316322
s.freeKey(fdi32)
@@ -341,7 +347,7 @@ proc registerProcess*[T](s: Selector[T], pid: int,
341347
s.addKey(fdi32, selectorKey)
342348
343349
changes.modifyKQueue(0, uint(uint32(pid)), EVFILT_PROC, flags, NOTE_EXIT,
344-
0, cast[pointer](uint32(fdi32)))
350+
0, fdi32.toPointer())
345351
if handleEintr(kevent(s.kqFd, addr(changes[0]), cint(1), nil, 0, nil)) == -1:
346352
s.freeKey(fdi32)
347353
return err(osLastError())
@@ -490,14 +496,14 @@ proc prepareKey[T](s: Selector[T], event: KEvent): Opt[ReadyKey] =
490496
of EVFILT_READ:
491497
if (event.flags and EV_EOF) != 0:
492498
rkey.events.incl(Event.Error)
493-
rkey.errorCode = OSErrorCode(ECONNRESET)
499+
rkey.errorCode = oserrno.ECONNRESET
494500

495501
if Event.User in pkey.events:
496502
var data: uint64 = 0
497503
if handleEintr(osdefs.read(cint(event.ident), addr data,
498504
sizeof(uint64))) != sizeof(uint64):
499505
let errorCode = osLastError()
500-
if errorCode == EAGAIN:
506+
if errorCode == oserrno.EAGAIN:
501507
# Someone already consumed event data
502508
return Opt.none(ReadyKey)
503509
else:
@@ -510,7 +516,7 @@ proc prepareKey[T](s: Selector[T], event: KEvent): Opt[ReadyKey] =
510516
of EVFILT_WRITE:
511517
if (event.flags and EV_EOF) != 0:
512518
rkey.events.incl(Event.Error)
513-
rkey.errorCode = OSErrorCode(ECONNRESET)
519+
rkey.errorCode = oserrno.ECONNRESET
514520

515521
rkey.events.incl(Event.Write)
516522

@@ -577,7 +583,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
577583
maxEventsCount, ptrTimeout)
578584
if res < 0:
579585
let errorCode = osLastError()
580-
if errorCode == EINTR:
586+
if errorCode == oserrno.EINTR:
581587
continue
582588
return err(errorCode)
583589
else:

chronos/osdefs.nim

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,60 @@
66
# Licensed under either of
77
# Apache License, version 2.0, (LICENSE-APACHEv2)
88
# MIT license (LICENSE-MIT)
9-
10-
from std/os import osLastError, osErrorMsg, OSErrorCode, raiseOSError,
11-
newOSError
12-
export osLastError, osErrorMsg, OSError, OSErrorCode, raiseOSError, newOSError
9+
import oserrno
10+
export oserrno
1311

1412
when defined(windows):
15-
from std/winlean import SocketHandle, SockLen, SockAddr, InAddr,
16-
In6_addr, Sockaddr_in, Sockaddr_in6, Sockaddr_storage,
17-
AddrInfo
18-
export SocketHandle, SockLen, SockAddr, InAddr,
19-
In6_addr, Sockaddr_in, Sockaddr_in6, Sockaddr_storage, AddrInfo
20-
2113
# Prerequisites for constants
2214
template WSAIORW*(x, y): untyped = (IOC_INOUT or x or y)
2315
template WSAIOW*(x, y): untyped =
2416
clong(-2147483648) or
2517
((clong(sizeof(int32)) and clong(IOCPARM_MASK)) shl 16) or (x shl 8) or y
2618

2719
type
20+
Sockaddr_storage* {.final, pure.} = object
21+
ss_family*: uint16
22+
ss_pad1: array[6, byte]
23+
ss_align: int64
24+
ss_pad2: array[112, byte]
25+
26+
InAddr* {.final, pure, union.} = object
27+
s_addr*: uint32
28+
29+
In6Addr* {.final, pure, union.} = object
30+
s_addr*: array[16, byte]
31+
32+
Sockaddr_in* {.final, pure.} = object
33+
sin_family*: uint16
34+
sin_port*: uint16
35+
sin_addr*: InAddr
36+
sin_zero*: array[0..7, char]
37+
38+
Sockaddr_in6* {.final, pure.} = object
39+
sin6_family*: uint16
40+
sin6_port*: uint16
41+
sin6_flowinfo*: uint32
42+
sin6_addr*: In6Addr
43+
sin6_scope_id*: uint32
44+
45+
SockLen* = cuint
46+
47+
SockAddr* {.final, pure.} = object
48+
sa_family*: uint16
49+
sa_data*: array[14, char]
50+
51+
AddrInfo* {.final, pure.} = object
52+
ai_flags*: cint ## Input flags.
53+
ai_family*: cint ## Address family of socket.
54+
ai_socktype*: cint ## Socket type.
55+
ai_protocol*: cint ## Protocol of socket.
56+
ai_addrlen*: csize_t ## Length of socket address.
57+
ai_canonname*: pointer ## Canonical name of service location.
58+
ai_addr*: ptr SockAddr ## Socket address of socket.
59+
ai_next*: ptr AddrInfo ## Pointer to next in list.
60+
61+
SocketHandle* = distinct int
62+
2863
HANDLE* = distinct uint
2964
GUID* {.final, pure.} = object
3065
D1*: uint32
@@ -104,36 +139,6 @@ when defined(windows):
104139
PIPE_UNLIMITED_INSTANCES* = 255'u32
105140
DEFAULT_PIPE_SIZE* = 65536'u32
106141

107-
ERROR_SUCCESS* = 0
108-
ERROR_FILE_NOT_FOUND* = 2
109-
ERROR_TOO_MANY_OPEN_FILES* = 4
110-
ERROR_ACCESS_DENIED* = 5
111-
ERROR_BROKEN_PIPE* = 109
112-
ERROR_BUFFER_OVERFLOW* = 111
113-
ERROR_PIPE_BUSY* = 231
114-
ERROR_NO_DATA* = 232
115-
ERROR_PIPE_NOT_CONNECTED* = 233
116-
ERROR_PIPE_CONNECTED* = 535
117-
ERROR_OPERATION_ABORTED* = 995
118-
ERROR_IO_PENDING* = 997
119-
ERROR_CONNECTION_REFUSED* = 1225
120-
ERROR_CONNECTION_ABORTED* = 1236
121-
122-
WSAEMFILE* = 10024
123-
WSAENETDOWN* = 10050
124-
WSAENETRESET* = 10052
125-
WSAECONNABORTED* = 10053
126-
WSAECONNRESET* = 10054
127-
WSAENOBUFS* = 10055
128-
WSAETIMEDOUT* = 10060
129-
WSAEADDRINUSE* = 10048
130-
WSAEDISCON* = 10101
131-
WSANOTINITIALISED* = 10093
132-
WSAENOTSOCK* = 10038
133-
WSAEINPROGRESS* = 10036
134-
WSAEINTR* = 10004
135-
WSAEWOULDBLOCK* = 10035
136-
ERROR_NETNAME_DELETED* = 64
137142
STATUS_PENDING* = 0x103
138143

139144
IOCPARM_MASK* = 0x7f'u32
@@ -1283,8 +1288,6 @@ when defined(posix):
12831288
INVALID_SOCKET* = SocketHandle(-1)
12841289
INVALID_HANDLE_VALUE* = cint(-1)
12851290

1286-
proc `==`*(x: OSErrorCode, y: int): bool =
1287-
int(x) == y
12881291
proc `==`*(x: SocketHandle, y: int): bool =
12891292
x == SocketHandle(y)
12901293

0 commit comments

Comments
 (0)