aboutsummaryrefslogtreecommitdiff
path: root/src/backend/port/qnx4/sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/port/qnx4/sem.c')
-rw-r--r--src/backend/port/qnx4/sem.c557
1 files changed, 298 insertions, 259 deletions
diff --git a/src/backend/port/qnx4/sem.c b/src/backend/port/qnx4/sem.c
index 426329469ff..bcd784e6c21 100644
--- a/src/backend/port/qnx4/sem.c
+++ b/src/backend/port/qnx4/sem.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.2 2000/03/14 18:12:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.3 2000/04/12 17:15:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,282 +29,321 @@
#define SEMMAX (PROC_NSEMS_PER_SET)
#define OPMAX 8
-#define MODE 0700
-#define SHM_INFO_NAME "SysV_Sem_Info"
+#define MODE 0700
+#define SHM_INFO_NAME "SysV_Sem_Info"
-struct pending_ops {
- int op[OPMAX]; /* array of pending operations */
- int idx; /* index of first free array member */
+struct pending_ops
+{
+ int op[OPMAX]; /* array of pending operations */
+ int idx; /* index of first free array member */
};
-struct sem_info {
- sem_t sem;
- struct {
- key_t key;
- int nsems;
- sem_t sem[SEMMAX]; /* array of POSIX semaphores */
- struct sem semV[SEMMAX]; /* array of System V semaphore structures */
- struct pending_ops pendingOps[SEMMAX]; /* array of pending operations */
- } set[SETMAX];
+struct sem_info
+{
+ sem_t sem;
+ struct
+ {
+ key_t key;
+ int nsems;
+ sem_t sem[SEMMAX];/* array of POSIX semaphores */
+ struct sem semV[SEMMAX]; /* array of System V semaphore
+ * structures */
+ struct pending_ops pendingOps[SEMMAX]; /* array of pending
+ * operations */
+ } set[SETMAX];
};
-static struct sem_info *SemInfo = ( struct sem_info * )-1;
+static struct sem_info *SemInfo = (struct sem_info *) - 1;
-int semctl( int semid, int semnum, int cmd, /*...*/union semun arg )
+int
+semctl(int semid, int semnum, int cmd, /* ... */ union semun arg)
{
- int r = 0;
-
- sem_wait( &SemInfo->sem );
-
- if( semid < 0 || semid >= SETMAX ||
- semnum < 0 || semnum >= SemInfo->set[semid].nsems ) {
- sem_post( &SemInfo->sem );
- errno = EINVAL;
- return -1;
- }
-
- switch( cmd ) {
- case GETNCNT:
- r = SemInfo->set[semid].semV[semnum].semncnt;
- break;
-
- case GETPID:
- r = SemInfo->set[semid].semV[semnum].sempid;
- break;
-
- case GETVAL:
- r = SemInfo->set[semid].semV[semnum].semval;
- break;
-
- case GETALL:
- for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
- arg.array[semnum] = SemInfo->set[semid].semV[semnum].semval;
- }
- break;
-
- case SETVAL:
- SemInfo->set[semid].semV[semnum].semval = arg.val;
- break;
-
- case SETALL:
- for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
- SemInfo->set[semid].semV[semnum].semval = arg.array[semnum];
- }
- break;
-
- case GETZCNT:
- r = SemInfo->set[semid].semV[semnum].semzcnt;
- break;
-
- case IPC_RMID:
- for( semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++ ) {
- if( sem_destroy( &SemInfo->set[semid].sem[semnum] ) == -1 ) {
- r = -1;
- }
- }
- SemInfo->set[semid].key = -1;
- SemInfo->set[semid].nsems = 0;
- break;
-
- default:
- sem_post( &SemInfo->sem );
- errno = EINVAL;
- return -1;
- }
-
- sem_post( &SemInfo->sem );
-
- return r;
+ int r = 0;
+
+ sem_wait(&SemInfo->sem);
+
+ if (semid < 0 || semid >= SETMAX ||
+ semnum < 0 || semnum >= SemInfo->set[semid].nsems)
+ {
+ sem_post(&SemInfo->sem);
+ errno = EINVAL;
+ return -1;
+ }
+
+ switch (cmd)
+ {
+ case GETNCNT:
+ r = SemInfo->set[semid].semV[semnum].semncnt;
+ break;
+
+ case GETPID:
+ r = SemInfo->set[semid].semV[semnum].sempid;
+ break;
+
+ case GETVAL:
+ r = SemInfo->set[semid].semV[semnum].semval;
+ break;
+
+ case GETALL:
+ for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++)
+ arg.array[semnum] = SemInfo->set[semid].semV[semnum].semval;
+ break;
+
+ case SETVAL:
+ SemInfo->set[semid].semV[semnum].semval = arg.val;
+ break;
+
+ case SETALL:
+ for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++)
+ SemInfo->set[semid].semV[semnum].semval = arg.array[semnum];
+ break;
+
+ case GETZCNT:
+ r = SemInfo->set[semid].semV[semnum].semzcnt;
+ break;
+
+ case IPC_RMID:
+ for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++)
+ {
+ if (sem_destroy(&SemInfo->set[semid].sem[semnum]) == -1)
+ r = -1;
+ }
+ SemInfo->set[semid].key = -1;
+ SemInfo->set[semid].nsems = 0;
+ break;
+
+ default:
+ sem_post(&SemInfo->sem);
+ errno = EINVAL;
+ return -1;
+ }
+
+ sem_post(&SemInfo->sem);
+
+ return r;
}
-int semget( key_t key, int nsems, int semflg )
+int
+semget(key_t key, int nsems, int semflg)
{
- int fd, semid, semnum/*, semnum1*/;
- int exist = 0;
-
- if( nsems < 0 || nsems > SEMMAX ) {
- errno = EINVAL;
- return -1;
- }
-
- /* open and map shared memory */
- if( SemInfo == ( struct sem_info * )-1 ) {
- /* test if the shared memory already exists */
- fd = shm_open( SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE );
- if( fd == -1 && errno == EEXIST ) {
- exist = 1;
- fd = shm_open( SHM_INFO_NAME, O_RDWR | O_CREAT, MODE );
- }
- if( fd == -1 ) {
- return fd;
- }
- /* The size may only be set once. Ignore errors. */
- ltrunc( fd, sizeof( struct sem_info ), SEEK_SET );
- SemInfo = mmap( NULL, sizeof( struct sem_info ),
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
- if( SemInfo == MAP_FAILED ) {
- return -1;
- }
- if( !exist ) {
- /* create semaphore for locking */
- sem_init( &SemInfo->sem, 1, 1 );
- sem_wait( &SemInfo->sem );
- /* initilize shared memory */
- memset( SemInfo->set, 0, sizeof( SemInfo->set ) );
- for( semid = 0; semid < SETMAX; semid++ ) {
- SemInfo->set[semid].key = -1;
- }
- sem_post( &SemInfo->sem );
- }
- }
-
- sem_wait( &SemInfo->sem );
-
- if( key != IPC_PRIVATE ) {
- /* search existing element */
- semid = 0;
- while( semid < SETMAX && SemInfo->set[semid].key != key ) semid++;
- if( !( semflg & IPC_CREAT ) && semid >= SETMAX ) {
- sem_post( &SemInfo->sem );
- errno = ENOENT;
- return -1;
- }
- else if( semid < SETMAX ) {
- if( semflg & IPC_CREAT && semflg & IPC_EXCL ) {
- sem_post( &SemInfo->sem );
- errno = EEXIST;
- return -1;
- }
- else {
- if( nsems != 0 && SemInfo->set[semid].nsems < nsems ) {
- sem_post( &SemInfo->sem );
- errno = EINVAL;
- return -1;
- }
- sem_post( &SemInfo->sem );
- return semid;
- }
- }
- }
-
- /* search first free element */
- semid = 0;
- while( semid < SETMAX && SemInfo->set[semid].key != -1 ) semid++;
- if( semid >= SETMAX ) {
- sem_post( &SemInfo->sem );
- errno = ENOSPC;
- return -1;
- }
-
- for( semnum = 0; semnum < nsems; semnum++ ) {
- sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 );
+ int fd,
+ semid,
+ semnum /* , semnum1 */ ;
+ int exist = 0;
+
+ if (nsems < 0 || nsems > SEMMAX)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* open and map shared memory */
+ if (SemInfo == (struct sem_info *) - 1)
+ {
+ /* test if the shared memory already exists */
+ fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE);
+ if (fd == -1 && errno == EEXIST)
+ {
+ exist = 1;
+ fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT, MODE);
+ }
+ if (fd == -1)
+ return fd;
+ /* The size may only be set once. Ignore errors. */
+ ltrunc(fd, sizeof(struct sem_info), SEEK_SET);
+ SemInfo = mmap(NULL, sizeof(struct sem_info),
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (SemInfo == MAP_FAILED)
+ return -1;
+ if (!exist)
+ {
+ /* create semaphore for locking */
+ sem_init(&SemInfo->sem, 1, 1);
+ sem_wait(&SemInfo->sem);
+ /* initilize shared memory */
+ memset(SemInfo->set, 0, sizeof(SemInfo->set));
+ for (semid = 0; semid < SETMAX; semid++)
+ SemInfo->set[semid].key = -1;
+ sem_post(&SemInfo->sem);
+ }
+ }
+
+ sem_wait(&SemInfo->sem);
+
+ if (key != IPC_PRIVATE)
+ {
+ /* search existing element */
+ semid = 0;
+ while (semid < SETMAX && SemInfo->set[semid].key != key)
+ semid++;
+ if (!(semflg & IPC_CREAT) && semid >= SETMAX)
+ {
+ sem_post(&SemInfo->sem);
+ errno = ENOENT;
+ return -1;
+ }
+ else if (semid < SETMAX)
+ {
+ if (semflg & IPC_CREAT && semflg & IPC_EXCL)
+ {
+ sem_post(&SemInfo->sem);
+ errno = EEXIST;
+ return -1;
+ }
+ else
+ {
+ if (nsems != 0 && SemInfo->set[semid].nsems < nsems)
+ {
+ sem_post(&SemInfo->sem);
+ errno = EINVAL;
+ return -1;
+ }
+ sem_post(&SemInfo->sem);
+ return semid;
+ }
+ }
+ }
+
+ /* search first free element */
+ semid = 0;
+ while (semid < SETMAX && SemInfo->set[semid].key != -1)
+ semid++;
+ if (semid >= SETMAX)
+ {
+ sem_post(&SemInfo->sem);
+ errno = ENOSPC;
+ return -1;
+ }
+
+ for (semnum = 0; semnum < nsems; semnum++)
+ {
+ sem_init(&SemInfo->set[semid].sem[semnum], 1, 0);
/* Currently sem_init always returns -1.
- if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
- for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
- sem_destroy( &SemInfo->set[semid].sem[semnum1] );
- }
- sem_post( &SemInfo->sem );
- return -1;
- }
+ if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
+ for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
+ sem_destroy( &SemInfo->set[semid].sem[semnum1] );
+ }
+ sem_post( &SemInfo->sem );
+ return -1;
+ }
*/
- }
+ }
- SemInfo->set[semid].key = key;
- SemInfo->set[semid].nsems = nsems;
+ SemInfo->set[semid].key = key;
+ SemInfo->set[semid].nsems = nsems;
- sem_post( &SemInfo->sem );
+ sem_post(&SemInfo->sem);
- return semid;
+ return semid;
}
-int semop( int semid, struct sembuf *sops, size_t nsops )
+int
+semop(int semid, struct sembuf * sops, size_t nsops)
{
- int i, r = 0, r1, errno1 = 0, op;
-
- sem_wait( &SemInfo->sem );
-
- if( semid < 0 || semid >= SETMAX ) {
- sem_post( &SemInfo->sem );
- errno = EINVAL;
- return -1;
- }
- for( i = 0; i < nsops; i++ ) {
- if( /*sops[i].sem_num < 0 ||*/ sops[i].sem_num >= SemInfo->set[semid].nsems ) {
- sem_post( &SemInfo->sem );
- errno = EFBIG;
- return -1;
- }
- }
-
- for( i = 0; i < nsops; i++ ) {
- if( sops[i].sem_op < 0 ) {
- if( SemInfo->set[semid].semV[sops[i].sem_num].semval < -sops[i].sem_op ) {
- if( sops[i].sem_flg & IPC_NOWAIT ) {
- sem_post( &SemInfo->sem );
- errno = EAGAIN;
- return -1;
- }
- SemInfo->set[semid].semV[sops[i].sem_num].semncnt++;
- if( SemInfo->set[semid].pendingOps[sops[i].sem_num].idx >= OPMAX ) {
- /* pending operations array overflow */
- sem_post( &SemInfo->sem );
- errno = ERANGE;
- return -1;
- }
- SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx++] = sops[i].sem_op;
- /* suspend */
- sem_post( &SemInfo->sem ); /* avoid deadlock */
- r1 = sem_wait( &SemInfo->set[semid].sem[sops[i].sem_num] );
- sem_wait( &SemInfo->sem );
- if( r1 ) {
- errno1 = errno;
- r = r1;
- /* remove pending operation */
- SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
- }
- else {
- SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
- }
- SemInfo->set[semid].semV[sops[i].sem_num].semncnt--;
- }
- else {
- SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
- }
- }
- else if( sops[i].sem_op > 0 ) {
- SemInfo->set[semid].semV[sops[i].sem_num].semval += sops[i].sem_op;
- op = sops[i].sem_op;
- while( op > 0 && SemInfo->set[semid].pendingOps[sops[i].sem_num].idx > 0 ) { /* operations pending */
- if( SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx-1] + op >= 0 ) {
- /* unsuspend processes */
- if( sem_post( &SemInfo->set[semid].sem[sops[i].sem_num] ) ) {
- errno1 = errno;
- r = -1;
- }
- /* adjust pending operations */
- op += SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx];
- SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
- }
- else {
- /* adjust pending operations */
- SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx-1] += op;
- op = 0;
- }
- }
- }
- else /* sops[i].sem_op == 0 */ {
- /* not supported */
- sem_post( &SemInfo->sem );
- errno = ENOSYS;
- return -1;
- }
- SemInfo->set[semid].semV[sops[i].sem_num].sempid = getpid( );
- }
-
- sem_post( &SemInfo->sem );
-
- errno = errno1;
- return r;
+ int i,
+ r = 0,
+ r1,
+ errno1 = 0,
+ op;
+
+ sem_wait(&SemInfo->sem);
+
+ if (semid < 0 || semid >= SETMAX)
+ {
+ sem_post(&SemInfo->sem);
+ errno = EINVAL;
+ return -1;
+ }
+ for (i = 0; i < nsops; i++)
+ {
+ if ( /* sops[i].sem_num < 0 || */ sops[i].sem_num >= SemInfo->set[semid].nsems)
+ {
+ sem_post(&SemInfo->sem);
+ errno = EFBIG;
+ return -1;
+ }
+ }
+
+ for (i = 0; i < nsops; i++)
+ {
+ if (sops[i].sem_op < 0)
+ {
+ if (SemInfo->set[semid].semV[sops[i].sem_num].semval < -sops[i].sem_op)
+ {
+ if (sops[i].sem_flg & IPC_NOWAIT)
+ {
+ sem_post(&SemInfo->sem);
+ errno = EAGAIN;
+ return -1;
+ }
+ SemInfo->set[semid].semV[sops[i].sem_num].semncnt++;
+ if (SemInfo->set[semid].pendingOps[sops[i].sem_num].idx >= OPMAX)
+ {
+ /* pending operations array overflow */
+ sem_post(&SemInfo->sem);
+ errno = ERANGE;
+ return -1;
+ }
+ SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx++] = sops[i].sem_op;
+ /* suspend */
+ sem_post(&SemInfo->sem); /* avoid deadlock */
+ r1 = sem_wait(&SemInfo->set[semid].sem[sops[i].sem_num]);
+ sem_wait(&SemInfo->sem);
+ if (r1)
+ {
+ errno1 = errno;
+ r = r1;
+ /* remove pending operation */
+ SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
+ }
+ else
+ SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
+ SemInfo->set[semid].semV[sops[i].sem_num].semncnt--;
+ }
+ else
+ SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
+ }
+ else if (sops[i].sem_op > 0)
+ {
+ SemInfo->set[semid].semV[sops[i].sem_num].semval += sops[i].sem_op;
+ op = sops[i].sem_op;
+ while (op > 0 && SemInfo->set[semid].pendingOps[sops[i].sem_num].idx > 0)
+ { /* operations pending */
+ if (SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx - 1] + op >= 0)
+ {
+ /* unsuspend processes */
+ if (sem_post(&SemInfo->set[semid].sem[sops[i].sem_num]))
+ {
+ errno1 = errno;
+ r = -1;
+ }
+ /* adjust pending operations */
+ op += SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx];
+ SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
+ }
+ else
+ {
+ /* adjust pending operations */
+ SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx - 1] += op;
+ op = 0;
+ }
+ }
+ }
+ else
+ /* sops[i].sem_op == 0 */
+ {
+ /* not supported */
+ sem_post(&SemInfo->sem);
+ errno = ENOSYS;
+ return -1;
+ }
+ SemInfo->set[semid].semV[sops[i].sem_num].sempid = getpid();
+ }
+
+ sem_post(&SemInfo->sem);
+
+ errno = errno1;
+ return r;
}