[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

The semaphore system has the ability to ask for ownership of a complete
list of semaphores.  This can help prevent deadlocks when there are two or
more tasks trying to get the same set of semaphores.  If task A gets
semaphore 1 and tries to obtain semaphore 2 after task B has obtained
semaphore 2 but before task B tries to obtain semaphore 1 then both tasks
will hang.  Exec provides ObtainSemaphoreList() and ReleaseSemaphoreList()
to prevent this problem.

A semaphore list is a list header to a list that contains SignalSemaphore
structures.  The semaphore list must not contain any public semaphores.
This is because the semaphore list functions use the standard node
structures in the semaphore.

To arbitrate access to a semaphore list use another semaphore.  Create a
public semaphore and use it to arbitrate access to the list header of the
semaphore list.  This also gives you a locking semaphore, protecting the
ObtainSemaphoreList() call.  Once you have gained access to the list with
ObtainSemaphore(), you may obtain all the semaphores on the list via
ObtainSemaphoreList() (or get individual semaphores with
ObtainSemaphore()).  When you are finished with the protected objects,
release the semaphores on the list with ReleaseSemaphoreList(), and then
release the list semaphore via ReleaseSemaphore().

For example:

    ObtainSemaphore((struct SignalSemaphore *)SemaphoreList);
    ObtainSemaphoreList(SemaphoreList->sl_List);

    /* At this point the objects are protected, and can be manipulated */

    ReleaseSemaphoreList(SemaphoreList->sl_List);
    ReleaseSemaphore((struct SignalSemaphore *)SemaphoreList);

See the SharedList structure above for an example of a semaphore structure
with a list header.