diff options
author | bptato <nincsnevem662@gmail.com> | 2024-02-29 23:23:40 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-02-29 23:31:38 +0100 |
commit | afafcaf1047f721c8d061d883329d0e556326511 (patch) | |
tree | 2abc62a06227c7aa9c573f9ce52424df638ccba8 /src/local/client.nim | |
parent | f4b53af1261e6f9be16a315247ace80fcb816505 (diff) | |
download | chawan-afafcaf1047f721c8d061d883329d0e556326511.tar.gz |
buffer, client: fix deadlock with send() calls
This is an ancient bug, but it got much easier to trigger with mouse scrolling support so it's time to fix it. (The bug itself was that since both the client and buffer ends of the controlling stream are blocking, they could get stuck when both were trying to send() data to the other end but the buffer was full. So now we set the client end to non-blocking.)
Diffstat (limited to 'src/local/client.nim')
-rw-r--r-- | src/local/client.nim | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/local/client.nim b/src/local/client.nim index 76a61bfa..3a80b4bf 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -21,6 +21,7 @@ import display/term import html/chadombuilder import html/dom import html/event +import io/bufstream import io/posixstream import io/promise import io/socketstream @@ -41,6 +42,7 @@ import loader/loader import loader/request import local/container import local/pager +import server/buffer import server/forkserver import types/blob import types/cookie @@ -450,12 +452,15 @@ proc acceptBuffers(client: Client) = client.pager.procmap.del(pid) stream.close() var accepted: seq[Pid] + let registerFun = proc(fd: int) = + client.selector.unregister(fd) + client.selector.registerHandle(fd, {Read, Write}, 0) for pid, container in client.pager.procmap: let stream = connectSocketStream(pid, buffered = false, blocking = true) if stream == nil: client.pager.alert("Error: failed to set up buffer") continue - container.setStream(stream) + container.setStream(stream, registerFun) let fd = int(stream.fd) client.fdmap[fd] = container client.selector.registerHandle(fd, {Read}, 0) @@ -513,6 +518,12 @@ proc handleRead(client: Client, fd: int) = let container = client.fdmap[fd] client.pager.handleEvent(container) +proc handleWrite(client: Client, fd: int) = + let container = client.fdmap[fd] + if container.iface.stream.flushWrite(): + client.selector.unregister(fd) + client.selector.registerHandle(fd, {Read}, 0) + proc flushConsole*(client: Client) {.jsfunc.} = if client.console == nil: # hack for when client crashes before console has been initialized @@ -561,6 +572,8 @@ proc inputLoop(client: Client) = for event in events: if Read in event.events: client.handleRead(event.fd) + if Write in event.events: + client.handleWrite(event.fd) if Error in event.events: client.handleError(event.fd) if Signal in event.events: @@ -597,6 +610,8 @@ proc headlessLoop(client: Client) = for event in events: if Read in event.events: client.handleRead(event.fd) + if Write in event.events: + client.handleWrite(event.fd) if Error in event.events: client.handleError(event.fd) if selectors.Event.Timer in event.events: |