home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / baclsema.zip / AIXSEM.C next >
C/C++ Source or Header  |  1994-06-23  |  8KB  |  341 lines

  1. // ****************************************************************************
  2. //
  3. // Module:  aixsem.C
  4. // Author:  Dick Lam
  5. //
  6. // Purpose: C++ class source file for osSemaphore
  7. //
  8. // Notes:  This is a base class.  It contains general implementation methods
  9. //         for semaphores used in signalling between processes and threads.
  10. //
  11. // ****************************************************************************
  12.  
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <string.h>
  16. #include <sys/types.h>
  17. #include <sys/sem.h>
  18. #include <sys/ipc.h>
  19. #include <sys/mode.h>
  20. #include "ossem.h"
  21.  
  22. // ****************************************************************************
  23.  
  24. // init operating system-specific variables
  25.  
  26. const char *semPath = "/tmp/";
  27.  
  28. // ****************************************************************************
  29.  
  30. // osSemaphore - constructor
  31.  
  32. osSemaphore::osSemaphore(ipcSemaphore *interface, const char *name,
  33.                          ipcSemaphoreType type, ipcSemaphoreOp operation)
  34.  
  35. {
  36.    // init instance variables
  37.    myInterface = interface;
  38.    myName = 0;
  39.    myID = 0L;
  40.    myType = type;
  41.    if (operation == semcreate)
  42.       isOwner = 1;
  43.    else
  44.       isOwner = 0;
  45.  
  46.    // check that input name is valid
  47.    if (!name || (strlen(name) == 0)) {
  48.       myInterface->myState = ipcSemaphore::badname;
  49.       return;
  50.    }
  51.  
  52.    // allocate space for the name
  53.    myName = new char[strlen(semPath) + strlen(name) + 1];
  54.    if (!myName) {
  55.       myInterface->myState = ipcSemaphore::bad;
  56.       return;
  57.    }
  58.  
  59.    // and form the complete semaphore pathname
  60.    strcpy(myName, semPath);
  61.    strcat(myName, name);
  62.  
  63.    // create a file for later call to ftok
  64.    if (isOwner) {
  65.       if (::creat(myName, O_RDWR | O_CREAT | O_EXCL) == -1) {
  66.          myInterface->myState = ipcSemaphore::badname;
  67.          return;
  68.       }
  69.    }
  70.  
  71.    // set the object state and return
  72.    myInterface->myState = ipcSemaphore::good;
  73. }
  74.  
  75. // ----------------------------------------------------------------------------
  76.  
  77. // ~osSemaphore - destructor
  78.  
  79. osSemaphore::~osSemaphore()
  80.  
  81. {
  82.    // if the process is the semaphore owner, delete the file and remove
  83.    // the semaphore from the system
  84.    if (isOwner && (myInterface->myState == ipcSemaphore::good)) {
  85.       ::semctl( (int)myID, 0, IPC_RMID, 0);
  86.       ::unlink(myName);
  87.    }
  88.  
  89.    // delete the name
  90.    delete myName;
  91. }
  92.  
  93. // ----------------------------------------------------------------------------
  94.  
  95. // Name - returns the name of the semaphore
  96.  
  97. char *osSemaphore::Name() const
  98.  
  99. {
  100.    return myName;
  101. }
  102.  
  103. // ----------------------------------------------------------------------------
  104.  
  105. // ID - returns the semaphore id
  106.  
  107. unsigned long osSemaphore::ID() const
  108.  
  109. {
  110.    return myID;
  111. }
  112.  
  113. // ----------------------------------------------------------------------------
  114.  
  115. // Type - returns the type of semaphore
  116.  
  117. ipcSemaphoreType osSemaphore::Type() const
  118.  
  119. {
  120.    return myType;
  121. }
  122.  
  123. // ----------------------------------------------------------------------------
  124.  
  125. // Owner - returns 1 if this is the owner (creator), and 0 otherwise
  126.  
  127. int osSemaphore::Owner() const
  128.  
  129. {
  130.    return isOwner;
  131. }
  132.  
  133. // ----------------------------------------------------------------------------
  134.  
  135. // CreateMutex - creates a mutex semaphore
  136.  
  137. void osSemaphore::CreateMutex()
  138.  
  139. {
  140.    // get key
  141.    key_t semkey = ::ftok(myName, 'V');
  142.    if (semkey == (key_t)-1) {
  143.       myInterface->myState = ipcSemaphore::bad;
  144.       return;
  145.    }
  146.  
  147.    // and create the semaphore
  148.    int newsem = ::semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR |
  149.                                     S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  150.    if (newsem == -1) {
  151.       myInterface->myState = ipcSemaphore::bad;
  152.       return;
  153.    }
  154.  
  155.    myID = (unsigned long)newsem;
  156. }
  157.  
  158. // ----------------------------------------------------------------------------
  159.  
  160. // OpenMutex - opens a mutex semaphore
  161.  
  162. void osSemaphore::OpenMutex()
  163.  
  164. {
  165.    // get key
  166.    key_t semkey = ::ftok(myName, 'V');
  167.    if (semkey == (key_t)-1) {
  168.       myInterface->myState = ipcSemaphore::bad;
  169.       return;
  170.    }
  171.  
  172.    // access an already existing semaphore
  173.    int newsem = ::semget(semkey, 0, S_IRUSR | S_IWUSR | S_IRGRP |
  174.                                     S_IWGRP | S_IROTH | S_IWOTH);
  175.    if (newsem == -1) {
  176.       myInterface->myState = ipcSemaphore::notfound;
  177.       return;
  178.    }
  179.  
  180.    myID = (unsigned long)newsem;
  181. }
  182.  
  183. // ----------------------------------------------------------------------------
  184.  
  185. // RequestMutex - requests a mutex semaphore
  186.  
  187. void osSemaphore::RequestMutex()
  188.  
  189. {
  190.    static struct sembuf request_op[2] = {{0, 0, 0},
  191.                                          {0, 1, SEM_UNDO}};
  192.  
  193.    ::semop( (int)myID, request_op, 2 );
  194. }
  195.  
  196. // ----------------------------------------------------------------------------
  197.  
  198. // ReleaseMutex - releases a mutex semaphore
  199.  
  200. void osSemaphore::ReleaseMutex()
  201.  
  202. {
  203.    static struct sembuf release_op = {0, -1, IPC_NOWAIT | SEM_UNDO};
  204.  
  205.    ::semop( (int)myID, &release_op, 1 );
  206. }
  207.  
  208. // ----------------------------------------------------------------------------
  209.  
  210. // QueryMutex - queries a mutex semaphore
  211.  
  212. unsigned long osSemaphore::QueryMutex()
  213.  
  214. {
  215.    unsigned short values[1];
  216.  
  217.    ::semctl( (int)myID, 0, GETALL, values );
  218.    return (unsigned long)values[0];
  219. }
  220.  
  221. // ----------------------------------------------------------------------------
  222.  
  223. // CloseMutex - closes a mutex semaphore
  224.  
  225. void osSemaphore::CloseMutex()
  226.  
  227. {
  228. }
  229.  
  230. // ----------------------------------------------------------------------------
  231.  
  232. // CreateEvent - creates an event semaphore
  233.  
  234. void osSemaphore::CreateEvent()
  235.  
  236. {
  237.    // get key
  238.    key_t semkey = ::ftok(myName, 'V');
  239.    if (semkey == (key_t)-1) {
  240.       myInterface->myState = ipcSemaphore::bad;
  241.       return;
  242.    }
  243.  
  244.    // and create the semaphore
  245.    int newsem = ::semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR |
  246.                                     S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  247.    if (newsem == -1) {
  248.       myInterface->myState = ipcSemaphore::bad;
  249.       return;
  250.    }
  251.  
  252.    myID = (unsigned long)newsem;
  253. }
  254.  
  255. // ----------------------------------------------------------------------------
  256.  
  257. // OpenEvent - opens an event semaphore
  258.  
  259. void osSemaphore::OpenEvent()
  260.  
  261. {
  262.    // get key
  263.    key_t semkey = ::ftok(myName, 'V');
  264.    if (semkey == (key_t)-1) {
  265.       myInterface->myState = ipcSemaphore::bad;
  266.       return;
  267.    }
  268.  
  269.    // access an already existing semaphore
  270.    int newsem = ::semget(semkey, 0, S_IRUSR | S_IWUSR | S_IRGRP |
  271.                                     S_IWGRP | S_IROTH | S_IWOTH);
  272.    if (newsem == -1) {
  273.       myInterface->myState = ipcSemaphore::notfound;
  274.       return;
  275.    }
  276.  
  277.    myID = (unsigned long)newsem;
  278. }
  279.  
  280. // ----------------------------------------------------------------------------
  281.  
  282. // PostEvent - posts an event semaphore
  283.  
  284. void osSemaphore::PostEvent()
  285.  
  286. {
  287.    static struct sembuf post_op = {0, -1, IPC_NOWAIT | SEM_UNDO};
  288.  
  289.    ::semop( (int)myID, &post_op, 1 );
  290. }
  291.  
  292. // ----------------------------------------------------------------------------
  293.  
  294. // ResetEvent - resets an event semaphore
  295.  
  296. void osSemaphore::ResetEvent()
  297.  
  298. {
  299.    static struct sembuf reset_op = {0, 1, SEM_UNDO};
  300.  
  301.    ::semop( (int)myID, &reset_op, 1 );
  302. }
  303.  
  304. // ----------------------------------------------------------------------------
  305.  
  306. // WaitEvent - waits on an event semaphore
  307.  
  308. void osSemaphore::WaitEvent()
  309.  
  310. {
  311.    static struct sembuf wait_op = {0, 0, 0};
  312.  
  313.    ::semop( (int)myID, &wait_op, 1 );
  314. }
  315.  
  316. // ----------------------------------------------------------------------------
  317.  
  318. // QueryEvent - queries an event semaphore
  319.  
  320. unsigned long osSemaphore::QueryEvent()
  321.  
  322. {
  323.    unsigned short values[1];
  324.  
  325.    ::semctl( (int)myID, 0, GETALL, values );
  326.    return (unsigned long)values[0];
  327. }
  328.  
  329. // ----------------------------------------------------------------------------
  330.  
  331. // CloseEvent - closes an event semaphore
  332.  
  333. void osSemaphore::CloseEvent()
  334.  
  335. {
  336. }
  337.  
  338. // ****************************************************************************
  339.  
  340. // end of aixsem.C
  341.