Repository navigation
fix(libkernel): refuse to detach or rejoin a thread that is being joined - #6487
Conversation
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
No dependency: this PR builds on neither of them.
They edit the same lines in |
|
Rebase handoff, with one contract repair — rebased onto current The repair: your join completion set Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release,
To pick it up: Head is |
b4ae2ec to
2b4f79e
Compare
2b4f79e to
97c57c7
Compare
PPSA34015 (EA SPORTS FC 27) stopped with "Joining guest thread: Access is denied": scePthreadJoin waited on a thread that another call released under it, and then waited on its closed handle. As FreeBSD 11.4's thr_join.c and thr_detach.c do with the joiner field, scePthreadDetach now returns EINVAL while a thread waits to join the target, a second concurrent scePthreadJoin returns EOPNOTSUPP, a cancelled join backs out, and a completed join leaves the thread detached.
97c57c7 to
30cbb2f
Compare
What
EA SPORTS FC 27 (PPSA34015) stopped once on Windows with:
The join comes from the title's thread wrapper (eboot
0x1d4b365,scePthreadJoin(handle, NULL)after its status poll).scePthreadJoinwaits for_finishedand then for the native handle. If another call releases the thread in the meantime, the join waits on a closed handle in freed memory. That other call is ascePthreadDetach, or a secondscePthreadJoinwhoseReleaseThreadfrees the thread.WaitForSingleObjectthen fails withERROR_ACCESS_DENIED.FreeBSD 11.4 libthr keeps a
joinerfield for this case (thr_join.c, thr_detach.c). This PR follows it, under_join_mtx:scePthreadDetachreturnsEINVALwhile a thread waits to join the target.scePthreadJoinreturnsEOPNOTSUPP(ENOTSUP, 45), asjoin_commondoes.backout_join)._joinedunder the same lock, so a detach racing with its end returnsEINVALinstead of releasing the thread a second time.The libkernel debt entry for
scePthreadJoinrecords this.mainnow has the_joinedflag (second join after a completed one →ESRCH); this PR keeps it and adds the lock, so a detach cannot close the handle while a joiner waits.Tested
guest_pthread_join_detach:EINVAL.EOPNOTSUPP.EINVAL.guest_pthread_startstill passes on both.main66702f1:guest_pthread_join_detachpasses again on Windows 11. The Linux runs andguest_pthread_startabove are from before the rebase.v_readlane_b32 of lane 63 is outside the 32-lane host subgroup, see EA SPORTS FC 27 (PPSA34015) #6344), so I could not run it to the point of this race again. A run with this change and a log on the refused paths reached that earlier stop without the join error, which does not prove much either way.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)