Crashes on Switch platform with broken pthread_detach() #149
Labels
No labels
bug
dependencies
duplicate
enhancement
hacktoberfest-accepted
invalid
question
submodules
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-moonlight-stream/moonlight-common-c#149
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I found that interrupting a connection to the server on the unofficial Switch client results in a crash when returning to launcher or reopening Moonlight. I traced this to a failed call to pthread_detach() leaving the thread handle open, which causes a crash after switching apps.
libnx does not contain an implementation of newlib::pthread_detach; the source says:
The ReSwitched server says it's not possible to implement thread detaching on the Switch's constrained (IMO anemic) runtime environment, especially when you need to support multiple applications chainloading in the same address space and OS process.
The solution (workaround) I came up with for my fork of the client was to call the termination callback synchronously, but it only sets a flag which gets read by the main thread loop. Obviously this is incompatible with the library's current programming model. Do you have any ideas on how to improve functionality?
theoretically you could add a global mutexed vector of threads to be joined upon session destructor or next startup
but i still think requiring shutdown in the main thread is a neater solution
Hmm it might be better to add a main-thread shutdown for the 3DS too.
Does this library have a way to pass events to the main thread event loop, or it depends on the user to handle that itself? I don't have the code in front of me right now.
For platforms that don't support detaching threads, we can just document that calling
LiStopConnection()in the termination callback is not allowed and then implement detach as a join.You should discuss this with @UselessMnemonic. I am hesistant to make a breaking behavior change like this for 3DS without seeing evidence of an actual bug or ensuring that no affected clients invoke
LiStopConnection()in their termination callback.Not natively, but the callback infrastructure lets you do whatever you want. Moonlight-Qt pushes SDL events to the main thread during several connection listener callbacks.
Hmm the downstream project hasn't chimed in with coordinating changes to these libraries. In the case of moonlight-common-c, I think invoking the user callback directly in
ClInternalConnectionTerminatedwould be more efficient than spawning a thread and joining it immediately, and functionally identical.I'm unsure (from a maintainer's view) if it's better to note down that termination is synchronous on Switch, in the function body of
ClInternalConnectionTerminatedor withinPltDetachThread. I think the former better marks "the control flow is different" at the place it happens (to avoid a new library consumer thinking PltDetachThread detaches and being confused why the code deadlocks). Though it seems the existing code tries to keep platform-specific branching inPltDetachThread... but the changes suggested here are not merely platform-specific implementation, but contractural changes!If we do place the change in Connection.c#ClInternalConnectionTerminated, we could choose to either #ifdef
PltJoinThreadrather than detaching, or cut out the thread entirely (more efficient but also more code divergence between Switch and other consoles).As for the 3DS thread detach, given I haven't heard from UselessMnemonic, I'm not sure if he doesn't want to talk (or forgot to reply here), or I'd have to message off this issue tracker.