diff options
author | bptato <nincsnevem662@gmail.com> | 2024-06-21 20:13:21 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-06-21 20:32:09 +0200 |
commit | 7ffce10055c6b553781e0b747506f6a3a50718a6 (patch) | |
tree | 56f2646592640e6feecd5590289e3c2d811550ad /src/local | |
parent | 51ae4cc4ec4402f78bbda6de5207c60b6a1aaf86 (diff) | |
download | chawan-7ffce10055c6b553781e0b747506f6a3a50718a6.tar.gz |
client, pager: fix cached item refcounting bugs
Diffstat (limited to 'src/local')
-rw-r--r-- | src/local/client.nim | 18 | ||||
-rw-r--r-- | src/local/container.nim | 4 | ||||
-rw-r--r-- | src/local/pager.nim | 22 |
3 files changed, 30 insertions, 14 deletions
diff --git a/src/local/client.nim b/src/local/client.nim index ee469652..c52ea71f 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -426,21 +426,25 @@ proc acceptBuffers(client: Client) = pager.alert("Error: failed to set up buffer") continue let key = pager.addLoaderClient(container.process, container.loaderConfig) + let loader = pager.loader stream.withPacketWriter w: w.swrite(key) - let loader = pager.loader if item.fdin != -1: let outputId = item.istreamOutputId if container.cacheId == -1: - (container.cacheId, container.cacheFile) = - loader.addCacheFile(outputId, loader.clientPid) + container.cacheId = loader.addCacheFile(outputId, loader.clientPid) + if container.request.url.scheme == "cache": + # loading from cache; now both the buffer and us hold a new reference + # to the cached item, but it's only shared with the buffer. add a + # pager ref too. + loader.shareCachedItem(container.cacheId, loader.clientPid) var outCacheId = container.cacheId let pid = container.process if item.fdout == item.fdin: loader.shareCachedItem(container.cacheId, pid) loader.resume(item.istreamOutputId) else: - outCacheId = loader.addCacheFile(item.ostreamOutputId, pid).outputId + outCacheId = loader.addCacheFile(item.ostreamOutputId, pid) loader.resume([item.istreamOutputId, item.ostreamOutputId]) w.swrite(outCacheId) if item.fdin != -1: @@ -450,7 +454,11 @@ proc acceptBuffers(client: Client) = discard close(item.fdout) container.setStream(stream, registerFun) else: - # buffer is cloned, no need to cache anything + # buffer is cloned, just share the parent's cached source + loader.shareCachedItem(container.cacheId, container.process) + # also add a reference here; it will be removed when the container is + # deleted + loader.shareCachedItem(container.cacheId, loader.clientPid) container.setCloneStream(stream, registerFun) let fd = int(stream.fd) client.fdmap[fd] = container diff --git a/src/local/container.nim b/src/local/container.nim index 8717610f..7aa5d324 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -154,7 +154,6 @@ type filter*: BufferFilter bgcolor*: CellColor tailOnLoad*: bool - cacheFile* {.jsget.}: string mainConfig*: Config flags*: set[ContainerFlag] images*: seq[PosBitmap] @@ -168,7 +167,7 @@ proc newContainer*(config: BufferConfig; loaderConfig: LoaderClientConfig; url: URL; request: Request; luctx: LUContext; attrs: WindowAttributes; title: string; redirectDepth: int; flags: set[ContainerFlag]; contentType: Option[string]; charsetStack: seq[Charset]; cacheId: int; - cacheFile: string; mainConfig: Config): Container = + mainConfig: Config): Container = return Container( url: url, request: request, @@ -184,7 +183,6 @@ proc newContainer*(config: BufferConfig; loaderConfig: LoaderClientConfig; ), loadinfo: "Connecting to " & request.url.host & "...", cacheId: cacheId, - cacheFile: cacheFile, process: -1, mainConfig: mainConfig, flags: flags, diff --git a/src/local/pager.nim b/src/local/pager.nim index 8760da86..a70b2b3d 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -483,7 +483,7 @@ proc draw*(pager: Pager) = let bmp = NetworkBitmap(image.bmp) let cached = container.findCachedImage(bmp.imageId) if cached == nil: - let (cacheId, _) = pager.loader.addCacheFile(bmp.outputId, + let cacheId = pager.loader.addCacheFile(bmp.outputId, pager.loader.clientPid, container.process) let request = newRequest(newURL("cache:" & $cacheId).get) # capture bmp for the closure @@ -566,9 +566,13 @@ proc newContainer(pager: Pager; bufferConfig: BufferConfig; loaderConfig: LoaderClientConfig; request: Request; title = ""; redirectDepth = 0; flags = {cfCanReinterpret, cfUserRequested}; contentType = none(string); charsetStack: seq[Charset] = @[]; - url = request.url; cacheId = -1; cacheFile = ""): Container = + url = request.url): Container = let stream = pager.loader.startRequest(request, loaderConfig) pager.loader.registerFun(stream.fd) + let cacheId = if request.url.scheme == "cache": + parseInt32(request.url.pathname).get(-1) + else: + -1 let container = newContainer( bufferConfig, loaderConfig, @@ -582,7 +586,6 @@ proc newContainer(pager: Pager; bufferConfig: BufferConfig; contentType, charsetStack, cacheId, - cacheFile, pager.config ) pager.connectingContainers.add(ConnectingContainerItem( @@ -602,9 +605,7 @@ proc newContainerFrom(pager: Pager; container: Container; contentType: string): newRequest(url), contentType = some(contentType), charsetStack = container.charsetStack, - url = container.url, - cacheId = container.cacheId, - cacheFile = container.cacheFile + url = container.url ) func findConnectingContainer*(pager: Pager; fd: int): int = @@ -835,6 +836,7 @@ proc deleteContainer(pager: Pager; container, setTarget: Container) = pager.setContainer(setTarget) pager.unreg.add(container) if container.process != -1: + pager.loader.removeCachedItem(container.cacheId) pager.forkserver.removeChild(container.process) pager.loader.removeClient(container.process) @@ -927,6 +929,14 @@ proc toggleSource(pager: Pager) {.jsfunc.} = pager.container.sourcepair = container pager.addContainer(container) +proc getCacheFile(pager: Pager; cacheId: int): string {.jsfunc.} = + return pager.loader.getCacheFile(cacheId) + +proc cacheFile(pager: Pager): string {.jsfget.} = + if pager.container != nil: + return pager.getCacheFile(pager.container.cacheId) + return "" + proc getEditorCommand(pager: Pager; file: string; line = 1): string {.jsfunc.} = var editor = pager.config.external.editor if (let uqEditor = ChaPath(editor).unquote(); uqEditor.isSome): |