diff options
Diffstat (limited to 'src/backend/port/qnx4/sem.c')
-rw-r--r-- | src/backend/port/qnx4/sem.c | 112 |
1 files changed, 63 insertions, 49 deletions
diff --git a/src/backend/port/qnx4/sem.c b/src/backend/port/qnx4/sem.c index 98fcc28993d..a25ba759ee3 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.6 2001/08/24 14:07:49 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.7 2001/09/07 00:27:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,14 +21,15 @@ #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> -#include "storage/ipc.h" -#include "storage/proc.h" #include <sys/sem.h> #include <sys/mman.h> #include <sys/stat.h> +#include "miscadmin.h" +#include "storage/ipc.h" +#include "storage/proc.h" + -#define SETMAX ((MAXBACKENDS + PROC_NSEMS_PER_SET + 1) / PROC_NSEMS_PER_SET) #define SEMMAX (PROC_NSEMS_PER_SET+1) #define OPMAX 8 @@ -42,19 +43,23 @@ struct pending_ops int idx; /* index of first free array member */ }; +struct sem_set_info +{ + 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 */ +}; + 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]; + int nsets; + /* there are actually nsets of these: */ + struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */ }; static struct sem_info *SemInfo = (struct sem_info *) - 1; @@ -78,7 +83,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg) sem_wait(&SemInfo->sem); - if (semid < 0 || semid >= SETMAX || + if (semid < 0 || semid >= SemInfo->nsets || semnum < 0 || semnum >= SemInfo->set[semid].nsems) { sem_post(&SemInfo->sem); @@ -144,9 +149,11 @@ semget(key_t key, int nsems, int semflg) { int fd, semid, - semnum /* , semnum1 */ ; + semnum, + nsets; int exist = 0; - struct stat statbuf; + Size sem_info_size; + struct stat statbuf; if (nsems < 0 || nsems > SEMMAX) { @@ -167,60 +174,64 @@ semget(key_t key, int nsems, int semflg) if (fd == -1) return fd; /* The size may only be set once. Ignore errors. */ - ltrunc(fd, sizeof(struct sem_info), SEEK_SET); - if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */ - { /* error is EBADF */ - close( fd ); - return -1; - } + nsets = PROC_SEM_MAP_ENTRIES(MaxBackends); + sem_info_size = sizeof(struct sem_info) + (nsets-1) * sizeof(struct sem_set_info); + ltrunc(fd, sem_info_size, SEEK_SET); + if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */ + { /* error is EBADF */ + close( fd ); + return -1; + } /* * size is rounded by proc to the next __PAGESIZE */ if ( statbuf.st_size != - ((( sizeof(struct sem_info) /__PAGESIZE)+1) * __PAGESIZE) ) + (((sem_info_size/__PAGESIZE)+1) * __PAGESIZE) ) { fprintf( stderr, "Found a pre-existing shared memory block for the semaphore memory\n" "of a different size (%ld instead %ld). Make sure that all executables\n" "are from the same release or remove the file \"/dev/shmem/%s\"\n" - "left by a previous version.\n", statbuf.st_size, - sizeof(struct sem_info), SHM_INFO_NAME); + "left by a previous version.\n", + (long) statbuf.st_size, + (long) sem_info_size, + SHM_INFO_NAME); errno = EACCES; return -1; } - SemInfo = mmap(NULL, sizeof(struct sem_info), + SemInfo = mmap(NULL, sem_info_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (SemInfo == MAP_FAILED) return -1; if (!exist) { + /* initialize shared memory */ + memset(SemInfo, 0, sem_info_size); + SemInfo->nsets = nsets; + for (semid = 0; semid < nsets; semid++) + SemInfo->set[semid].key = -1; /* 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); - on_proc_exit( semclean, NULL ); + on_proc_exit( semclean, 0 ); } } sem_wait(&SemInfo->sem); + nsets = SemInfo->nsets; if (key != IPC_PRIVATE) { /* search existing element */ semid = 0; - while (semid < SETMAX && SemInfo->set[semid].key != key) + while (semid < nsets && SemInfo->set[semid].key != key) semid++; - if (!(semflg & IPC_CREAT) && semid >= SETMAX) + if (!(semflg & IPC_CREAT) && semid >= nsets) { sem_post(&SemInfo->sem); errno = ENOENT; return -1; } - else if (semid < SETMAX) + else if (semid < nsets) { if (semflg & IPC_CREAT && semflg & IPC_EXCL) { @@ -244,9 +255,9 @@ semget(key_t key, int nsems, int semflg) /* search first free element */ semid = 0; - while (semid < SETMAX && SemInfo->set[semid].key != -1) + while (semid < nsets && SemInfo->set[semid].key != -1) semid++; - if (semid >= SETMAX) + if (semid >= nsets) { sem_post(&SemInfo->sem); errno = ENOSPC; @@ -256,15 +267,18 @@ semget(key_t key, int nsems, int semflg) 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; - } -*/ +/* Currently sem_init always returns -1. */ +#ifdef NOT_USED + if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) { + int semnum1; + + for( semnum1 = 0; semnum1 < semnum; semnum1++ ) { + sem_destroy( &SemInfo->set[semid].sem[semnum1] ); + } + sem_post( &SemInfo->sem ); + return -1; + } +#endif } SemInfo->set[semid].key = key; @@ -286,7 +300,7 @@ semop(int semid, struct sembuf * sops, size_t nsops) sem_wait(&SemInfo->sem); - if (semid < 0 || semid >= SETMAX) + if (semid < 0 || semid >= SemInfo->nsets) { sem_post(&SemInfo->sem); errno = EINVAL; |