diff options
author | bptato <nincsnevem662@gmail.com> | 2023-06-29 18:09:34 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-06-29 18:30:57 +0200 |
commit | cd6b8bf5cf93ada0ee60202c249ae80693e5ca89 (patch) | |
tree | 2c1865bda4a795c10cad36baba06b14845557d79 /src/display/client.nim | |
parent | 09be1d576ce815d80df1b625366de5965971430c (diff) | |
download | chawan-cd6b8bf5cf93ada0ee60202c249ae80693e5ca89.tar.gz |
Do not block indefinitely if buffer crashes before accept
Kind of a hack, but better than nothing.
Diffstat (limited to 'src/display/client.nim')
-rw-r--r-- | src/display/client.nim | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/src/display/client.nim b/src/display/client.nim index 767a5e67..721af4a0 100644 --- a/src/display/client.nim +++ b/src/display/client.nim @@ -25,6 +25,7 @@ import html/dom import html/htmlparser import io/lineedit import io/loader +import io/posixstream import io/promise import io/request import io/window @@ -49,23 +50,24 @@ type ClientObj* = object alive: bool attrs: WindowAttributes + config {.jsget.}: Config + console {.jsget.}: Console dispatcher: Dispatcher - feednext: bool - s: string errormessage: string - userstyle: CSSStylesheet + fd: int + fdmap: Table[int, Container] + feednext: bool + jsctx: JSContext + jsrt: JSRuntime + line {.jsget.}: LineEdit loader: FileLoader - console {.jsget.}: Console pager {.jsget.}: Pager - line {.jsget.}: LineEdit - config {.jsget.}: Config + s: string + selector: Selector[Container] + ssock: ServerSocket store {.jsget, jsset.}: Document - jsrt: JSRuntime - jsctx: JSContext - fdmap: Table[int, Container] timeouts: TimeoutState[Container] - ssock: ServerSocket - selector: Selector[Container] + userstyle: CSSStylesheet Console = ref object err: Stream @@ -155,6 +157,7 @@ proc quit(client: Client, code = 0) {.jsfunc.} = JS_FreeValue(ctx, global) if client.jsctx != nil: free(client.jsctx) + #TODO #if client.jsrt != nil: # free(client.jsrt) quit(code) @@ -264,21 +267,25 @@ proc acceptBuffers(client: Client) = client.pager.procmap.del(pid) stream.close() while client.pager.procmap.len > 0: - let stream = client.ssock.acceptSocketStream() - var pid: Pid - stream.sread(pid) - if pid in client.pager.procmap: - let container = client.pager.procmap[pid] - client.pager.procmap.del(pid) - container.setStream(stream) - let fd = stream.source.getFd() - client.fdmap[int(fd)] = container - client.selector.registerHandle(fd, {Read}, nil) - client.pager.handleEvents(container) - else: - #TODO uh what? - client.console.log("???") - stream.close() + try: + let stream = client.ssock.acceptSocketStream() + var pid: Pid + #TODO if this returns EAGAIN then we're stuck + stream.sread(pid) + if pid in client.pager.procmap: + let container = client.pager.procmap[pid] + client.pager.procmap.del(pid) + container.setStream(stream) + let fd = stream.source.getFd() + client.fdmap[int(fd)] = container + client.selector.registerHandle(fd, {Read}, nil) + client.pager.handleEvents(container) + else: + #TODO uh what? + client.console.log("???") + stream.close() + except OSError: # EAGAIN, probably. TODO + break proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize_t): cint {. importc: "setvbuf", header: "<stdio.h>", tags: [].} @@ -312,6 +319,8 @@ proc handleRead(client: Client, fd: int) = client.loader.onRead(fd) elif fd in client.loader.unregistered: discard # ignore + elif fd == client.fd: + client.acceptBuffers() else: let container = client.fdmap[fd] client.pager.handleEvent(container) @@ -375,7 +384,6 @@ proc inputLoop(client: Client) = client.command(client.pager.scommand) client.pager.scommand = "" client.handlePagerEvents() - client.acceptBuffers() if client.pager.container == nil: # No buffer to display. quit(1) @@ -386,7 +394,8 @@ func hasSelectFds(client: Client): bool = return not client.timeouts.empty or client.pager.numload > 0 or client.loader.connecting.len > 0 or - client.loader.ongoing.len > 0 + client.loader.ongoing.len > 0 or + client.pager.procmap.len > 0 proc headlessLoop(client: Client) = while client.hasSelectFds(): @@ -487,13 +496,17 @@ proc launchClient*(client: Client, pages: seq[string], ctype: Option[string], dump = not open(tty, "/dev/tty", fmRead) else: dump = true - client.ssock = initServerSocket(false) - client.selector = newSelector[Container]() + client.ssock = initServerSocket(false, false) + client.fd = cast[int](client.ssock.sock.getFd()) + let selector = newSelector[Container]() + selector.registerHandle(client.fd, {Read}, nil) + let efd = int(client.dispatcher.forkserver.estream.fd) + selector.registerHandle(efd, {Read}, nil) client.loader.registerFun = proc(fd: int) = - client.selector.registerHandle(fd, {Read}, nil) + selector.registerHandle(fd, {Read}, nil) client.loader.unregisterFun = proc(fd: int) = - client.selector.unregister(fd) - client.selector.registerHandle(int(client.dispatcher.forkserver.estream.fd), {Read}, nil) + selector.unregister(fd) + client.selector = selector client.pager.launchPager(tty) client.console = newConsole(client.pager, tty) #TODO passing console.err here makes it impossible to change it later. maybe @@ -517,7 +530,6 @@ proc launchClient*(client: Client, pages: seq[string], ctype: Option[string], for page in pages: client.pager.loadURL(page, ctype = ctype, cs = cs) - client.acceptBuffers() client.pager.refreshStatusMsg() if not dump: client.inputLoop() |