Make the texture send queue own its packet copies - #73
Conversation
Change TexturePendingServerAdd() to clone each CmdTexture before adding it to the send queue. This keeps objects in mTrackedTextures separate from packets being used by the communication thread. Update TextureTrackingRem() to queue a Destroy copy and immediately remove and free the tracked Create object. Free temporary managed-texture Update objects after their queue copies are created. Make Communications_Outgoing_Textures() release every queued texture packet after it is sent. Add Communications_ReleaseTexturePackets() to free pending and in-flight texture packets when Communications_Loop() disconnects or ClientInfo is destroyed. Stop accepting texture packets after mbDisconnectPending is set, clear packets from the old connection, and remove older pending packets when a Create or Destroy supersedes them. Walk mTrackedTextures backward when TextureTrackingRem() can erase entries. Update ClientInfo::TextureTrackingClear() to preserve texture IDs supplied by legacy ImGui renderers and generate an ID only when the texture does not already have one. These changes prevent texture packets from being changed or freed while they are being sent. They also prevent stale Updates from reaching a new server before their Creates and avoid leaking packets after an interrupted connection.
|
Could you explain the problem encountered leading to this change? |
|
This came about from an infinite loop we hit in TexturePendingServerAdd(). The same CmdTexture was being queued twice. This led to its mpNext pointint back to itself and then on next list traversal the game was stuck in an infinite loop. While attempting to fix that we found texture commands leaking, which then led to making ownership explicit. Now the tracking list keeps the texture data, and the send queue gets its own packet copies. These are freed after sending or during disconnect cleanup. So the change started with the infinite loop and eventually grew to fix the allocation and cleanup problems we found along the way. |
|
Thank you for the information.
Do you have a scenario I could test this with? (I mean a pattern of
adding/removing texture that caused it, not access to the codebase).
Ideally, I'd like to avoid duplicating texture commands to keep cpu load on
the client low, so I'd like to explore options to prevent the problem in
other ways.
…On Sat, Sep 5, 2026 at 12:00 PM Martin Ecker ***@***.***> wrote:
*martinecker* left a comment (sammyfreg/netImgui#73)
<#73 (comment)>
This came about from an infinite loop we hit in TexturePendingServerAdd().
The same CmdTexture was being queued twice. This led to its mpNext pointint
back to itself and then on next list traversal the game was stuck in an
infinite loop.
While attempting to fix that we found texture commands leaking, which then
led to making ownership explicit. Now the tracking list keeps the texture
data, and the send queue gets its own packet copies. These are freed after
sending or during disconnect cleanup.
So the change started with the infinite loop and eventually grew to fix
the allocation and cleanup problems we found along the way.
—
Reply to this email directly, view it on GitHub
<#73?email_source=notifications&email_token=AESBPYYRSG4E22VHCM7OB6D5NQ2BDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNJVGMYDCNBQGQ32M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5553014047>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AESBPY76BKIW6AVYM6YN27D5NQ2BDAVCNFSNUABFKJSXA33TNF2G64TZHMZDMMJXGI2TEOBRHNEXG43VMU5TKMZVGEZDEOBZHE3KC5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AESBPYZM5BQBLAAWKCI6UAL5NQ2BDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNJVGMYDCNBQGQ32M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AESBPYYMQ4R447WPNDZFRQ35NQ2BDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNJVGMYDCNBQGQ32M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you commented.Message ID:
***@***.***>
|
|
Okay, let me try to reconstruct what we saw. It's been a little since we've made these changes, so please excuse if my memory is foggy... NetImgui keeps a texture’s Create command in mTrackedTextures and also uses that same object as a node in the send queue.
Another scenario that we hit if I recall was during connection setup where ContextOverride() resends every tracked Create packet, which could also requeue a packet that was already pending. |
|
The dev branch has some recent code refactoring to better handle textures. This change might not be needed anymore and is probably not compatible with the latest dev branch, |
Change TexturePendingServerAdd() to clone each CmdTexture before adding it to the send queue. This keeps objects in mTrackedTextures separate from packets being used by the communication thread.
Update TextureTrackingRem() to queue a Destroy copy and immediately remove and free the tracked Create object. Free temporary managed-texture Update objects after their queue copies are created. Make Communications_Outgoing_Textures() release every queued texture packet after it is sent.
Add Communications_ReleaseTexturePackets() to free pending and in-flight texture packets when Communications_Loop() disconnects or ClientInfo is destroyed. Stop accepting texture packets after mbDisconnectPending is set, clear packets from the old connection, and remove older pending packets when a Create or Destroy supersedes them.
Walk mTrackedTextures backward when TextureTrackingRem() can erase entries. Update ClientInfo::TextureTrackingClear() to preserve texture IDs supplied by legacy ImGui renderers and generate an ID only when the texture does not already have one.
These changes prevent texture packets from being changed or freed while they are being sent. They also prevent stale Updates from reaching a new server before their Creates and avoid leaking packets after an interrupted connection.