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.c396
1 files changed, 0 insertions, 396 deletions
diff --git a/src/backend/port/qnx4/sem.c b/src/backend/port/qnx4/sem.c
deleted file mode 100644
index 4a8d6a348fa..00000000000
--- a/src/backend/port/qnx4/sem.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * sem.c
- * System V Semaphore Emulation
- *
- * Copyright (c) 1999, repas AEG Automation GmbH
- *
- *
- * IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/port/qnx4/sem.c,v 1.13 2005/10/15 02:49:23 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include <errno.h>
-#include <semaphore.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.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 SEMMAX (PROC_NSEMS_PER_SET+1)
-#define OPMAX 8
-
-#define MODE 0700
-#define SHM_INFO_NAME "PgSysV_Sem_Info"
-
-
-struct pending_ops
-{
- int op[OPMAX]; /* array of pending operations */
- 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;
- 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;
-
-/* ----------------------------------------------------------------
- * semclean - remove the shared memory file on exit
- * only called by the process which created the shm file
- * ----------------------------------------------------------------
- */
-
-static void
-semclean(void)
-{
- remove("/dev/shmem/" SHM_INFO_NAME);
-}
-
-int
-semctl(int semid, int semnum, int cmd, /* ... */ union semun arg)
-{
- int r = 0;
-
- sem_wait(&SemInfo->sem);
-
- if (semid < 0 || semid >= SemInfo->nsets ||
- 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 fd,
- semid,
- semnum,
- nsets;
- int exist = 0;
- Size sem_info_size;
- struct stat statbuf;
-
- 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. */
- 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 !=
- (((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",
- (long) statbuf.st_size,
- (long) sem_info_size,
- SHM_INFO_NAME);
- errno = EACCES;
- return -1;
- }
- 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);
- on_proc_exit(semclean, 0);
- }
- }
-
- sem_wait(&SemInfo->sem);
- nsets = SemInfo->nsets;
-
- if (key != IPC_PRIVATE)
- {
- /* search existing element */
- semid = 0;
- while (semid < nsets && SemInfo->set[semid].key != key)
- semid++;
- if (!(semflg & IPC_CREAT) && semid >= nsets)
- {
- sem_post(&SemInfo->sem);
- errno = ENOENT;
- return -1;
- }
- else if (semid < nsets)
- {
- 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 < nsets && SemInfo->set[semid].key != -1)
- semid++;
- if (semid >= nsets)
- {
- 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. */
-#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;
- SemInfo->set[semid].nsems = nsems;
-
- sem_post(&SemInfo->sem);
-
- return semid;
-}
-
-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 >= SemInfo->nsets)
- {
- 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;
-}