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 >
Wrap
Text File
|
1990-03-20
|
3KB
|
103 lines
*****Listing 4*****
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#define PATHDLM ('/') /* path name delimiter */
#include "rwsem.h"
/* function declarations */
int getcnt(char *file, int *cntp);
int putcnt(char *file, int cnt);
/* read/write semaphore set table definition */
static rwsset_t rwst[RWSOPEN_MAX];
/* rwslock: read/write semaphore lock */
int rwslock(rwsset_t *rwsp, int rwsno, int ltype)
{
int wsem = 0; /* write semaphore */
int rsem = 0; /* read semaphore */
int rc = 0; /* readcount */
char rcpath[PATH_MAX + 1]; /* readcount file path name */
/* identify write and read semaphores and read-count file */
wsem = rwsno * 2;
rsem = wsem + 1;
sprintf(rcpath, "%s%cr%d", rwsp->rwsdir, (int)PATHDLM, rwsno);
switch (ltype) {
case RWS_UNLCK: /* unlock */
switch (rwsp->lockheld[rwsno]) {
case RWS_UNLCK: /* unlock */
break; /* case RWS_UNLCK: */
case RWS_RDLCK: /* read lock */
if (semlower(rwsp->ssp, rsem) == -1) { /* allocate readcount */
return -1;
}
getcnt(rcpath, &rc); /* get readcount */
rc--; /* decrement readcount */
if (rc == 0) { /* if no other readers, */
if (semraise(rwsp->ssp, wsem) == -1) { /* free resource */
semraise(rwsp->ssp, rsem);
return -1;
}
}
putcnt(rcpath, rc); /* store new readcount */
if (semraise(rwsp->ssp, rsem) == -1) { /* free readcount */
return -1;
}
break; /* case RWS_RDLCK: */
case RWS_WRLCK: /* write lock */
if (semraise(rwsp->ssp, wsem) == -1) {
return -1;
}
break; /* case RWS_WRLCK: */
default:
errno = RWSPANIC;
return -1;
break; /* default: */
};
break; /* case RWS_UNLCK: */
case RWS_RDLCK: /* read lock */
if (rwsp->lockheld[rwsno] == RWS_RDLCK) {
errno = 0;
return 0;
}
if (semlower(rwsp->ssp, rsem) == -1) { /* allocate readcount */
return -1;
}
getcnt(rcpath, &rc); /* get readcount */
rc++; /* increment readcount */
if (rc == 1) { /* if no other readers, */
if (semlower(rwsp->ssp, wsem) == -1) { /* allocate resource */
semraise(rwsp->ssp, rsem);
return -1;
}
}
putcnt(rcpath, rc); /* store new readcount */
if (semraise(rwsp->ssp, rsem) == -1) { /* free readcount */
if (rc == 1) semraise(rwsp->ssp, wsem);
return -1;
}
break; /* case RWS_RDLCK: */
case RWS_WRLCK: /* write lock */
if (semlower(rwsp->ssp, wsem) == -1) { /* allocate resource */
return -1;
}
break; /* case RWS_WRLCK: */
default:
errno = EINVAL;
return -1;
break; /* default: */
};
/* save type of lock held */
rwsp->lockheld[rwsno] = ltype;
errno = 0;
return 0;
}