diff options
author | bptato <nincsnevem662@gmail.com> | 2024-12-05 21:06:59 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-12-05 21:07:18 +0100 |
commit | b92f653d6f4f9b3b862777e5c150c035f14cbd30 (patch) | |
tree | e3d1a8c5509a690c1b257cddd4734eedd7ceedea /src | |
parent | c056cbfb5e4708d605e4f9547412fdb049258d4a (diff) | |
download | chawan-b92f653d6f4f9b3b862777e5c150c035f14cbd30.tar.gz |
loader: fix heisenbug
Unconditionally registering output handles on resume could result in a failed assertion on double-register. The bug would appear like: resume (register) -> handleRead -> pushBuffer -> currentBuffer is nil -> register again handleWrite had a very high likelihood of occurring between resume and handleRead, and that hid the bug by immediately unregistering the handle after resume. In fact, I haven't been able to reproduce the bug at all today, and only found it after poring over the source... Fix this by not registering output handles that are empty (except if the istream is already finished, in which case it will just be unregistered).
Diffstat (limited to 'src')
-rw-r--r-- | src/server/loader.nim | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/server/loader.nim b/src/server/loader.nim index b0e96ee3..833ff139 100644 --- a/src/server/loader.nim +++ b/src/server/loader.nim @@ -121,6 +121,8 @@ proc newInputHandle(ostream: PosixStream; outputId, pid: int; ownerPid: pid, suspended: suspended )) + when defined(debug): + handle.outputs[^1].url = handle.url return handle func cap(buffer: LoaderBuffer): int {.inline.} = @@ -411,6 +413,8 @@ proc redirectToFile(ctx: LoaderContext; output: OutputHandle; istreamAtEnd: output.istreamAtEnd, outputId: ctx.getOutputId() )) + when defined(debug): + output.parent.outputs[^1].url = output.parent.url return true proc addCacheFile(ctx: LoaderContext; client: ClientData; output: OutputHandle): @@ -1281,7 +1285,8 @@ proc resume(ctx: LoaderContext; stream: SocketStream; client: ClientData; let output = ctx.findOutput(id, client) if output != nil: output.suspended = false - ctx.register(output) + if not output.isEmpty or output.istreamAtEnd: + ctx.register(output) stream.sclose() proc equalsConstantTime(a, b: ClientKey): bool = |