mirror of
https://github.com/logos-messaging/nim-sds.git
synced 2026-02-17 12:33:06 +00:00
52 lines
1.8 KiB
Nim
52 lines
1.8 KiB
Nim
|
|
import chronos, chronos/selectors2
|
|
|
|
## Notice that this module extends current nim-chronos functionality to provide
|
|
## proper shutdown of the thread's dispatcher.
|
|
##
|
|
## This is necessary because nim-chronos does not provide a way to close
|
|
## the selector associated with a thread's dispatcher, which may lead to
|
|
## resource leaks.
|
|
##
|
|
## Therefore, this ideally should be contributed back to nim-chronos.
|
|
|
|
when defined(windows):
|
|
proc safeCloseHandle(h: HANDLE): Result[void, string] =
|
|
let res = closeHandle(h)
|
|
if res == 0: # WINBOOL FALSE
|
|
return err("Failed to close handle error code: " & osErrorMsg(osLastError()))
|
|
return ok()
|
|
|
|
proc closeDispatcher*(loop: PDispatcher): Result[void, string] =
|
|
? safeCloseHandle(loop.ioPort)
|
|
for i in loop.handles.items:
|
|
closeHandle(i)
|
|
loop.handles.clear()
|
|
return ok()
|
|
|
|
elif defined(macosx) or defined(freebsd) or defined(netbsd) or
|
|
defined(openbsd) or defined(dragonfly) or defined(macos) or
|
|
defined(linux) or defined(android) or defined(solaris):
|
|
|
|
proc closeDispatcher*(loop: PDispatcher): Result[void, string] =
|
|
## Close selector associated with current thread's dispatcher.
|
|
try:
|
|
loop.getIoHandler().close()
|
|
except IOSelectorsException as e:
|
|
return err("Exception in closeDispatcher: " & e.msg)
|
|
return ok()
|
|
|
|
proc shutdown*(): Result[void, string] {.raises: [].} =
|
|
## Performs final cleanup of all dispatcher resources.
|
|
## Notice that this should be called only when sure that no new async tasks will be scheduled.
|
|
##
|
|
## This routine shall be called only after `pollFor` has completed. Upon
|
|
## invocation, all streams are assumed to have been closed.
|
|
##
|
|
## Then, it assumes the thread's dispatcher has explicitly been stopped, destroyed and will never
|
|
## be used again.
|
|
|
|
let disp = getThreadDispatcher()
|
|
? closeDispatcher(disp)
|
|
return ok()
|