// Copyright (c) 1999-2000 David Muse // See the COPYING file for more information. #ifndef SEMAPHORESET_H #define SEMAPHORESET_H #include <pwd.h> #include <grp.h> #include <sys/types.h> // Semaphores allow processes to synchronize their activities. // // A semaphore is just a number with two primary operations that can be // performed on it: signal() and wait() // // The operations are analagous to: // // int semaphore; // // void signal() { // semaphore++; // increment the semaphore // } // // void wait() { // while (!semaphore>0); // wait until the semaphore>0 // semaphore--; // decrement the semaphore // } // // The actual signal() and wait() operations are atomic. There is no chance // of another process getting context-switched in and changing the semaphore // value between the two lines of code in the wait() process. // // Semaphores can be initialized to any number. // // The initial value of the semaphore corresponds to the number of processes // that will pass directly through their wait() calls without being blocked. // // Processes that get blocked calling wait() are placed in a queue. When // another process calls signal(), the process at the head of the queue is // unblocked. // // A semaphoreset is just a collection of related semaphores. // // A semaphoreset is owned by a user and group and has access permissions // just like a file. class semaphoreset { public: semaphoreset(); // Creates a semaphore set. virtual ~semaphoreset(); // Cleans up and removes the semaphore set // if it was created by create() or // createOrAttach() below. If the semaphore // was just attached to, it is not removed. int create(key_t key, mode_t permissions, int semcount, int *values); // Creates a semaphore set identified by "key" // containing "semcount" semaphores. // "key" should be generated using the ftok // function. // "permissions" sets the access permissions // for the set. // "values" should be an array of starting // values for each of the semaphores // in the set. int attach(key_t key, int semcount); // Attaches to an already existing semaphore set // identified by "key", containing "semcount" // semaphores. int createOrAttach(key_t key, mode_t permissions, int semcount, int *values); // Attempts to create the semaphore set // identified by "key". If this fails, it // attempts to attach to a semaphore set // identified by "key". void dontRemove(); // Instructs the destructor not to remove the semaphore // set if it was created during a call to create() or // createOrAttach() above. This is useful if an // application creates a semaphore set then forks and // wants to delete the semaphore set in the forked // process but does not want the semaphore removed from // the system. int forceRemove(); // Removes the semaphore set, whether it // was created or attached to. void showErrors(); // errors will be printed to stderr void dontShowErrors(); // errors will not be printed to stderr int getId(); // Returns the internal id for the semaphore set. int wait(int index); // wait on the "index"'th semaphore in the set int signal(int index); // signal on the "index"'th semaphore in the set int waitWithUndo(int index); // wait on the "index"'th semaphore in the set and // undo the wait when the program exits int signalWithUndo(int index); // signal on the "index"'th semaphore in the set and // undo the signal when the program exits int setValue(int index, int value); // set the "index"'th semaphore in the set to "value" int getValue(int index); // return the value of the "index"'th // semaphore in the set int setUserName(char *username); // makes this semaphore set owned by // the user "username" int setGroupName(char *groupname); // makes this semaphore set owned by // the group "groupname" int setUserId(ushort uid); // makes this semaphore set owned by // the user identified by "uid" int setGroupId(ushort gid); // makes this semaphore set owned by // the group identified by "gid" int setPermissions(mode_t permissions); // sets the access permissions for this // semaphore set to "permissions" char *getUserName(); // returns the name of the user that owns this // semaphore set char *getGroupName(); // returns the name of the group that owns this // semaphore set ushort getUserId(); // returns the user id of the user that owns this // semaphore set ushort getGroupId(); // returns the group id of the group that owns this // semaphore set mode_t getPermissions(); // returns the access permissions for this // semaphore set int getWaitingForZero(int index); // returns the number of processes that // are waiting for the semaphore to become 0 int getWaitingForIncrement(int index); // returns the number of processes that // are waiting for the semaphore to increment private: #include <rudiments/private/semaphoreset.h> }; #endif