H-uru / Plasma

Cyan Worlds's Plasma game engine
http://h-uru.github.io/Plasma/
GNU General Public License v3.0
203 stars 80 forks source link

Fixing global semaphore deadlock for *NIX platforms #1603

Closed colincornaby closed 3 weeks ago

colincornaby commented 1 month ago

If the program crashed or behaved unexpectedly while a global semaphore was locked, that semaphore would stay locked until the machine was restarted. Unlinking the semaphore upon creation will cause the semaphore to be disposed of once the last process using that semaphore is no longer running.

colincornaby commented 1 month ago

FYI - the 'sem_init' in the alternate path isn't just deprecated on macOS, but it's outright non functional.

dpogue commented 1 month ago

I guess this issue probably exists on Linux too, but is it worth looking into Mach semaphores for Darwin-based systems? Supposedly this is the primitive on which Darwin implemented named POSIX semaphores: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/synchronization/synchronization.html

colincornaby commented 1 month ago

I had started to look at Mach semaphores, but didn't see anything directly analogous to a named semaphore in my cursory glance. There was some reference about passing semaphores across process boundaries, but I didn't see anything that directly mapped to named. Let me know if you find anything.

Another suggestion I found - that would work well here but completely upend the interface - is to establish a file based lock on the log file. File system locks - supposedly - are released when the process dies. Technically - you may even be able to rebuild named locks over file system locks. I have not looked too deeply at this path though.

colincornaby commented 1 month ago

Looking into file locks as a possible replacement - especially in since the guard here is specifically intended to gate file access.

On Windows this function would be LockFileEx: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex

If a process terminates with a portion of a file locked or closes a file that has outstanding locks, the locks are unlocked by the operating system. However, the time it takes for the operating system to unlock these locks depends upon available system resources. Therefore, it is recommended that your process explicitly unlock all files it has locked when it terminates. If this is not done, access to these files may be denied if the operating system has not yet unlocked them.

In POSIX the function would be flock. In Linux it at least seems that file looks are kernel managed will be released on unexpected exit. https://stackoverflow.com/questions/12651068/release-of-flock-in-case-of-errors

I would have to check the behavior on macOS.

colincornaby commented 3 weeks ago

I think the other PR is likely the direction to go - so I'll close this one.