diff options
author | bptato <nincsnevem662@gmail.com> | 2024-02-13 21:17:29 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-02-13 21:20:00 +0100 |
commit | 4e690f150c8e3e2a54661f7a5cbdf7df40718c73 (patch) | |
tree | 2eb420a9374fed69cbbd2ce1a62cf385738a81a8 | |
parent | 0bc67b7bc1476a27961476f0d42f7af8c21e2933 (diff) | |
download | chawan-4e690f150c8e3e2a54661f7a5cbdf7df40718c73.tar.gz |
loader: fix delOutput bug, remove ErrorWouldBlock
-rw-r--r-- | src/io/posixstream.nim | 5 | ||||
-rw-r--r-- | src/loader/loader.nim | 30 | ||||
-rw-r--r-- | src/server/buffer.nim | 8 |
3 files changed, 15 insertions, 28 deletions
diff --git a/src/io/posixstream.nim b/src/io/posixstream.nim index 1b615dce..3aa14191 100644 --- a/src/io/posixstream.nim +++ b/src/io/posixstream.nim @@ -8,7 +8,6 @@ type isend*: bool ErrorAgain* = object of IOError - ErrorWouldBlock* = object of IOError ErrorBadFD* = object of IOError ErrorFault* = object of IOError ErrorInterrupted* = object of IOError @@ -19,10 +18,8 @@ type proc raisePosixIOError*() = # In the nim stdlib, these are only constants on linux amd64, so we # can't use a switch. - if errno == EAGAIN: + if errno == EAGAIN or errno == EWOULDBLOCK: raise newException(ErrorAgain, "eagain") - elif errno == EWOULDBLOCK: - raise newException(ErrorWouldBlock, "would block") elif errno == EBADF: raise newException(ErrorBadFD, "bad fd") elif errno == EFAULT: diff --git a/src/loader/loader.nim b/src/loader/loader.nim index 31f5be10..11ddefcc 100644 --- a/src/loader/loader.nim +++ b/src/loader/loader.nim @@ -147,11 +147,6 @@ func findCachedHandle(ctx: LoaderContext, cacheUrl: string): LoaderHandle = return it return nil -proc delOutput(ctx: LoaderContext, id: StreamId) = - let output = ctx.findOutput(id) - if output != nil: - ctx.outputMap.del(output.ostream.fd) - type PushBufferResult = enum pbrDone, pbrUnregister @@ -163,7 +158,7 @@ proc pushBuffer(ctx: LoaderContext, output: OutputHandle, buffer: LoaderBuffer): var n = 0 try: n = output.ostream.sendData(buffer) - except ErrorAgain, ErrorWouldBlock: + except ErrorAgain: discard except ErrorBrokenPipe: return pbrUnregister @@ -179,9 +174,8 @@ proc pushBuffer(ctx: LoaderContext, output: OutputHandle, buffer: LoaderBuffer): proc addFd(ctx: LoaderContext, handle: LoaderHandle, originalUrl: URL) = let output = handle.output output.ostream.setBlocking(false) + handle.istream.setBlocking(false) ctx.selector.registerHandle(handle.istream.fd, {Read}, 0) - let ofl = fcntl(handle.istream.fd, F_GETFL, 0) - discard fcntl(handle.istream.fd, F_SETFL, ofl or O_NONBLOCK) ctx.handleMap[handle.istream.fd] = handle if output.sostream != nil: # replace the fd with the new one in outputMap if stream was @@ -189,9 +183,7 @@ proc addFd(ctx: LoaderContext, handle: LoaderHandle, originalUrl: URL) = # (kind of a hack, but should always work) ctx.outputMap[output.ostream.fd] = output ctx.outputMap.del(output.sostream.fd) - if output.clientId != NullStreamId: - ctx.delOutput(output.clientId) - output.clientId = NullStreamId + output.clientId = NullStreamId if originalUrl != nil: let tmpf = getTempFile(ctx.config.tmpdir) let ps = newPosixStream(tmpf, O_CREAT or O_WRONLY, 0o600) @@ -331,8 +323,8 @@ proc onLoad(ctx: LoaderContext, stream: SocketStream) = request.headers["Referer"] = r if request.proxy == nil or not ctx.config.acceptProxy: request.proxy = ctx.config.proxy - let fd = int(stream.source.getFd()) - ctx.outputMap[fd] = handle.output + let output = handle.output + ctx.outputMap[output.ostream.fd] = output ctx.loadResource(request, handle) proc acceptConnection(ctx: LoaderContext) = @@ -360,7 +352,7 @@ proc acceptConnection(ctx: LoaderContext) = stream.sread(fds) for fd in fds: let output = ctx.findOutput((pid, fd)) - if output != nil: + if output != nil and output.registered: # remove from the selector, so any new reads will be just placed # in the handle's buffer ctx.selector.unregister(output.ostream.fd) @@ -371,7 +363,7 @@ proc acceptConnection(ctx: LoaderContext) = stream.sread(fds) for fd in fds: let output = ctx.findOutput((pid, fd)) - if output != nil: + if output != nil and output.registered: # place the stream back into the selector, so we can write to it # again ctx.selector.registerHandle(output.ostream.fd, {Write}, 0) @@ -447,7 +439,7 @@ proc handleRead(ctx: LoaderContext, handle: LoaderHandle, unregWrite.add(output) if n < buffer.cap: break - except ErrorAgain, ErrorWouldBlock: # retry later + except ErrorAgain: # retry later break except ErrorBrokenPipe: # sender died; stop streaming unregRead.add(handle) @@ -465,7 +457,7 @@ proc handleWrite(ctx: LoaderContext, output: OutputHandle, if output.currentBufferIdx < buffer.len: break output.bufferCleared() # swap out buffer - except ErrorAgain, ErrorWouldBlock: # never mind + except ErrorAgain: # never mind break except ErrorBrokenPipe: # receiver died; stop streaming unregWrite.add(output) @@ -500,8 +492,6 @@ proc finishCycle(ctx: LoaderContext, unregRead: var seq[LoaderHandle], if output.registered: ctx.selector.unregister(output.ostream.fd) ctx.outputMap.del(output.ostream.fd) - if output.clientId != NullStreamId: - ctx.delOutput(output.clientId) output.ostream.close() output.ostream = nil let handle = output.parent @@ -738,7 +728,7 @@ proc onRead*(loader: FileLoader, fd: int) = buffer[].buf.setLen(olen + n) if n == 0: break - except ErrorAgain, ErrorWouldBlock: + except ErrorAgain: buffer[].buf.setLen(olen) break if response.body.atEnd(): diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 0a144fd4..4d0b829b 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -784,8 +784,7 @@ proc connect*(buffer: Buffer): ConnectResult {.proxy.} = if buffer.source.contentType.isNone: buffer.source.contentType = some(response.contentType) buffer.istream = response.body - let fd = response.body.source.getFd() - buffer.fd = int(fd) + buffer.fd = response.body.fd needsAuth = response.status == 401 # Unauthorized redirect = response.redirect if "Set-Cookie" in response.headers.table: @@ -849,7 +848,8 @@ proc readFromFd*(buffer: Buffer, url: URL, ishtml: bool) {.proxy.} = buffer.setHTML(ishtml) let response = buffer.loader.doRequest(request) buffer.istream = response.body - buffer.fd = int(response.body.source.getFd()) + buffer.istream.setBlocking(false) + buffer.fd = response.body.fd buffer.selector.registerHandle(buffer.fd, {Read}, 0) proc setContentType*(buffer: Buffer, contentType: string) {.proxy.} = @@ -1119,7 +1119,7 @@ proc onload(buffer: Buffer) = ) return # skip incr render buffer.resolveTask(LOAD, res) - except ErrorAgain, ErrorWouldBlock: + except ErrorAgain: break if buffer.document != nil: # incremental rendering: only if we cannot read the entire stream in one |