Semaphores may be used for synchronizing complex objects or for enforcing mutual exclusion. You may use any object you own or any LINK_OK object as a semaphore, and any type of object (thing, room, player, or exit) may be used.
The semaphore state of an object is shown by the Semaphore attribute (which is read-only); a positive number indicates the number of commands awaiting notifies, and a negative number indicates the number of waits on that semaphore that will not block.
Use the '@wait <object>' form of the @wait command to request a command be delayed until <object> is notified with the @notify command. The @drain and @notify/all commands clear the semaphore on <object>, either discarding or executing all pending commands. Remember that the object performing the @wait executes the command, not the object used as a semaphore.
You may also combine the semaphore and timer options of @wait with '@wait <object>/<timeout> = <command>' If the time period expires before the semaphore is notified, then the command is executed and the semaphore count is decremented, just as if the command had been run because the semaphore had been notified.
Examples: <simple> @wait semaphore="Foo @notify semaphore <mutex lock> @va mutex lock=@wait me=@trig me/vb @vb mutex lock="Got it!;@notify me @startup mutex lock=@notify me <timed wait> @wait timer/60 = "Sixty Second Timer.
In the above examples you will say "Foo" after semaphore is notified, you will say "Got it" when you have the mutual exclusion lock mutex lock (You could have also modified object registers that need to be protected from concurrent update), and you will say "Sixty Second Timer." either when timer is notified or after sixty seconds pass.
PennMUSH, TinyMUSH, TinyMUX, and RhostMUSH also support multiple semaphores per object by allowing an attribute other than SEMAPHORE to be specified for the count (e.g. @wait me/othersem=command, @notify me/othersem, and @drain timer/newsem).
PennMUSH support the @wait timer/newsem/60="Timer form where both the alternate attribute and a timer is given.
On PennMUSH, if the attribute is already set, it has to have the same owner (God) and flags as the SEMAPHORE attribute would (typically no_inherit, no_clone, and locked), have a non-numeric name, and have a numeric or empty value. If it's not set, it can't be a built-in attribute other than SEMAPHORE.
RhostMUSH uses unique process ID's (or PID's) to optionally distinguish between semaphores or waits.