home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_04 / 8n04086c < prev    next >
Text File  |  1990-03-20  |  3KB  |  103 lines

  1. *****Listing 4*****
  2.  
  3. #include <errno.h>
  4. #include <limits.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #define PATHDLM    ('/')    /* path name delimiter */
  8. #include "rwsem.h"
  9.  
  10. /* function declarations */
  11. int getcnt(char *file, int *cntp);
  12. int putcnt(char *file, int cnt);
  13.  
  14. /* read/write semaphore set table definition */
  15. static rwsset_t rwst[RWSOPEN_MAX];
  16.  
  17. /* rwslock:  read/write semaphore lock */
  18. int rwslock(rwsset_t *rwsp, int rwsno, int ltype)
  19. {
  20.     int wsem = 0;            /* write semaphore */
  21.     int rsem = 0;            /* read semaphore */
  22.     int rc = 0;            /* readcount */
  23.     char rcpath[PATH_MAX + 1];    /* readcount file path name */
  24.  
  25.     /* identify write and read semaphores and read-count file */
  26.     wsem = rwsno * 2;
  27.     rsem = wsem + 1;
  28.     sprintf(rcpath, "%s%cr%d", rwsp->rwsdir, (int)PATHDLM, rwsno);
  29.  
  30.     switch (ltype) {
  31.     case RWS_UNLCK:    /* unlock */
  32.         switch (rwsp->lockheld[rwsno]) {
  33.         case RWS_UNLCK:    /* unlock */
  34.             break;    /* case RWS_UNLCK: */
  35.         case RWS_RDLCK:    /* read lock */
  36.             if (semlower(rwsp->ssp, rsem) == -1) {    /* allocate readcount */
  37.                 return -1;
  38.             }
  39.             getcnt(rcpath, &rc);            /* get readcount */
  40.             rc--;                    /* decrement readcount */
  41.             if (rc == 0) {                /* if no other readers, */
  42.                 if (semraise(rwsp->ssp, wsem) == -1) {    /* free resource */
  43.                     semraise(rwsp->ssp, rsem);
  44.                     return -1;
  45.                 }
  46.             }
  47.             putcnt(rcpath, rc);            /* store new readcount */
  48.             if (semraise(rwsp->ssp, rsem) == -1) {    /* free readcount */
  49.                 return -1;
  50.             }
  51.             break;    /* case RWS_RDLCK: */
  52.         case RWS_WRLCK:    /* write lock */
  53.             if (semraise(rwsp->ssp, wsem) == -1) {
  54.                 return -1;
  55.             }
  56.             break;    /* case RWS_WRLCK: */
  57.         default:
  58.             errno = RWSPANIC;
  59.             return -1;
  60.             break;    /* default: */
  61.         };
  62.         break;    /* case RWS_UNLCK: */
  63.     case RWS_RDLCK:    /* read lock */
  64.         if (rwsp->lockheld[rwsno] == RWS_RDLCK) {
  65.             errno = 0;
  66.             return 0;
  67.         }
  68.         if (semlower(rwsp->ssp, rsem) == -1) {    /* allocate readcount */
  69.             return -1;
  70.         }
  71.         getcnt(rcpath, &rc);            /* get readcount */
  72.         rc++;                    /* increment readcount */
  73.         if (rc == 1) {                /* if no other readers, */
  74.             if (semlower(rwsp->ssp, wsem) == -1) {    /* allocate resource */
  75.                 semraise(rwsp->ssp, rsem);
  76.                 return -1;
  77.             }
  78.         }
  79.         putcnt(rcpath, rc);            /* store new readcount */
  80.         if (semraise(rwsp->ssp, rsem) == -1) {    /* free readcount */
  81.             if (rc == 1) semraise(rwsp->ssp, wsem);
  82.             return -1;
  83.         }
  84.         break;    /* case RWS_RDLCK: */
  85.     case RWS_WRLCK:    /* write lock */
  86.         if (semlower(rwsp->ssp, wsem) == -1) {    /* allocate resource */
  87.             return -1;
  88.         }
  89.         break;    /* case RWS_WRLCK: */
  90.     default:
  91.         errno = EINVAL;
  92.         return -1;
  93.         break;    /* default: */
  94.     };
  95.  
  96.     /* save type of lock held */
  97.     rwsp->lockheld[rwsno] = ltype;
  98.  
  99.     errno = 0;
  100.     return 0;
  101. }
  102.  
  103.