about summary refs log tree commit diff stats
path: root/src/loader/loader.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader/loader.nim')
-rw-r--r--src/loader/loader.nim63
1 files changed, 19 insertions, 44 deletions
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index 85490b84..e8d29ee2 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -26,13 +26,13 @@ import std/net
 import std/options
 import std/os
 import std/posix
-import std/selectors
 import std/strutils
 import std/tables
 
 import io/bufreader
 import io/bufwriter
 import io/dynstream
+import io/poll
 import io/serversocket
 import io/stdio
 import io/tempfile
@@ -42,7 +42,6 @@ import loader/headers
 import loader/loaderhandle
 import loader/loaderiface
 import loader/request
-import loader/response
 import monoucha/javascript
 import types/cookie
 import types/formdata
@@ -52,9 +51,6 @@ import types/urimethodmap
 import types/url
 import utils/twtstr
 
-export request
-export response
-
 type
   CachedItem = ref object
     id: int
@@ -77,7 +73,7 @@ type
     alive: bool
     config: LoaderConfig
     handleMap: seq[LoaderHandle]
-    selector: Selector[int]
+    pollData: PollData
     # List of existing clients (buffer or pager) that may make requests.
     clientData: Table[int, ClientData] # pid -> data
     # ID of next output. TODO: find a better allocation scheme
@@ -145,40 +141,22 @@ type PushBufferResult = enum
 
 proc register(ctx: LoaderContext; handle: InputHandle) =
   assert not handle.registered
-  ctx.selector.registerHandle(int(handle.stream.fd), {Read}, 0)
+  ctx.pollData.register(handle.stream.fd, cshort(POLLIN))
   handle.registered = true
 
 proc unregister(ctx: LoaderContext; handle: InputHandle) =
   assert handle.registered
-  ctx.selector.unregister(int(handle.stream.fd))
+  ctx.pollData.unregister(int(handle.stream.fd))
   handle.registered = false
 
 proc register(ctx: LoaderContext; output: OutputHandle) =
   assert not output.registered
-  ctx.selector.registerHandle(int(output.stream.fd), {Write}, 0)
+  ctx.pollData.register(int(output.stream.fd), cshort(POLLOUT))
   output.registered = true
 
-const bsdPlatform = defined(macosx) or defined(freebsd) or defined(netbsd) or
-  defined(openbsd) or defined(dragonfly)
 proc unregister(ctx: LoaderContext; output: OutputHandle) =
   assert output.registered
-  # so kqueue-based selectors raise when we try to unregister a pipe whose
-  # reader is at EOF. "solution": clean up this mess ourselves.
-  let fd = int(output.stream.fd)
-  when bsdPlatform:
-    let oc = ctx.selector.count
-    try:
-      ctx.selector.unregister(fd)
-    except IOSelectorsException:
-      # ????
-      for name, f in ctx.selector[].fieldPairs:
-        when name == "fds":
-          cast[ptr int](addr f[fd])[] = -1
-        elif name == "changes":
-          f.setLen(0)
-      ctx.selector.count = oc - 1
-  else:
-    ctx.selector.unregister(fd)
+  ctx.pollData.unregister(int(output.stream.fd))
   output.registered = false
 
 # Either write data to the target output, or append it to the list of buffers to
@@ -1178,17 +1156,13 @@ proc exitLoader(ctx: LoaderContext) =
 
 var gctx: LoaderContext
 proc initLoaderContext(fd: cint; config: LoaderConfig): LoaderContext =
-  var ctx = LoaderContext(
-    alive: true,
-    config: config,
-    selector: newSelector[int]()
-  )
+  var ctx = LoaderContext(alive: true, config: config)
   gctx = ctx
   let myPid = getCurrentProcessId()
   # we don't capsicumize loader, so -1 is appropriate here
   ctx.ssock = initServerSocket(config.sockdir, -1, myPid, blocking = true)
   let sfd = int(ctx.ssock.sock.getFd())
-  ctx.selector.registerHandle(sfd, {Read}, 0)
+  ctx.pollData.register(sfd, POLLIN)
   if sfd >= ctx.handleMap.len:
     ctx.handleMap.setLen(sfd + 1)
   ctx.handleMap[sfd] = LoaderHandle() # pseudo handle
@@ -1302,25 +1276,26 @@ proc finishCycle(ctx: LoaderContext; unregRead: var seq[InputHandle];
 proc runFileLoader*(fd: cint; config: LoaderConfig) =
   var ctx = initLoaderContext(fd, config)
   let fd = int(ctx.ssock.sock.getFd())
-  var keys: array[64, ReadyKey]
   while ctx.alive:
-    let count = ctx.selector.selectInto(-1, keys)
+    ctx.pollData.poll(-1)
     var unregRead: seq[InputHandle] = @[]
     var unregWrite: seq[OutputHandle] = @[]
-    for event in keys.toOpenArray(0, count - 1):
-      let handle = ctx.handleMap[event.fd]
-      if Read in event.events:
-        if event.fd == fd: # incoming connection
+    for event in ctx.pollData.events:
+      let efd = int(event.fd)
+      if (event.revents and POLLIN) != 0:
+        if efd == fd: # incoming connection
           ctx.acceptConnection()
         else:
-          let handle = InputHandle(ctx.handleMap[event.fd])
+          let handle = InputHandle(ctx.handleMap[efd])
           case ctx.handleRead(handle, unregWrite)
           of hrrDone: discard
           of hrrUnregister, hrrBrokenPipe: unregRead.add(handle)
-      if Write in event.events:
+      if (event.revents and POLLOUT) != 0:
+        let handle = ctx.handleMap[efd]
         ctx.handleWrite(OutputHandle(handle), unregWrite)
-      if Error in event.events:
-        assert event.fd != fd
+      if (event.revents and POLLERR) != 0 or (event.revents and POLLHUP) != 0:
+        assert efd != fd
+        let handle = ctx.handleMap[efd]
         if handle of InputHandle: # istream died
           unregRead.add(InputHandle(handle))
         else: # ostream died