Semsrv
Cross-process semaphores with timeouts on OS X
OS X provides three kinds of semaphores by default; POSIX semaphores, System V sempahores, and Mach semaphores. Of those, neither the POSIX form nor the System V form support any kind of timeout, and while Mach semaphores do support a timeout, it isn’t immediately obvious how to pass one to another process.
semsrv
is here to solve this problem. It’s a simple Mach server that
implements named semaphores; when you want a semaphore, you ask the server to
create it for you, giving it a name. If it already exists, the server will
return the existing semaphore object. If not, it will create a new Mach
semaphore and return that.
Once you have the semaphore_t
port value, you use it just as if you had
called semaphore_create()
yourself. When you’re done with it, you can use
mach_port_destroy()
to release the port in your own process. You won’t be
able to destroy the semaphore using semaphore_destroy()
, because your task
doesn’t own it.
A few notes:
-
If you’re going to use this code directly in your program, please don’t change the
.defs
file without altering the definition ofSEMSRV_SERVICE
to a name that starts with *your own* reverse domain prefix. Doing that would break anything that uses this code literally as-is. -
In a normal program, you probably want to try spawning the
semsrv
process in the background. If another program has already started the server with the same service name, your copy will fail, but that’s OK because you can just use the other copy. -
The
semsrv
program doesn’t daemonize itself. This might matter to you, or it might not. -
It’s possible that you might be interested in re-writing the server to use
launchd
so that it starts automatically and you don’t need to worry about point 2 (above). Note that doing that will mean your program needs to install a suitable launch daemon property list. -
This code is only really intended as a sample, and has had limited testing.
The code can be built by typing make
at a command prompt. It has a very
simple (and not perfect) Makefile
, but I can’t be bothered with anything
more sophisticated.
If you just want to kick the tyres, try:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Obviously to test more interesting behaviour, you’ll want more than one Terminal window…
You can grab the code from the mercurial repository.