diff options
Diffstat (limited to 'src/backend/port/darwin/sem.c')
-rw-r--r-- | src/backend/port/darwin/sem.c | 389 |
1 files changed, 0 insertions, 389 deletions
diff --git a/src/backend/port/darwin/sem.c b/src/backend/port/darwin/sem.c deleted file mode 100644 index abb52c0b90c..00000000000 --- a/src/backend/port/darwin/sem.c +++ /dev/null @@ -1,389 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sem.c - * System V Semaphore Emulation - * - * Copyright (c) 1999, repas AEG Automation GmbH - * - * 2000-12-1 pmb@mac.com - * - changed from anonymous to named semaphores for darwin - * - this required changing sem_info from containig an array of sem_t to an array of sem_t* - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.5 2001/10/25 05:49:40 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include <errno.h> -#include <semaphore.h> -#include <string.h> -#include <sys/types.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> - -#include "miscadmin.h" -#include "storage/ipc.h" -#include "storage/proc.h" -#include "port/darwin/sem.h" - -#define SEMMAX IPC_NMAXSEM -#define OPMAX 8 - -#define MODE 0700 -#define SHM_INFO_NAME "SysV_Sem_Info" -#define SEM_NAME "/pgsql-darwin" - -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; - - -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_close(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; - char semname[64]; - - if (nsems < 0 || nsems > SEMMAX) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin semget aborting because nsems out of range. (%d)\n", nsems); -#endif - errno = EINVAL; - return -1; - } - - /* open and map shared memory */ - if (SemInfo == (struct sem_info *) - 1) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin initializing shared mem for semaphore shim.\n"); -#endif - /* 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; */ - shm_unlink(SHM_INFO_NAME); - fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE); - } - if (fd == -1) - return fd; - shm_unlink(SHM_INFO_NAME); - /* 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); - ftruncate(fd, sem_info_size); - 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 */ - sprintf(semname, "%s-map", SEM_NAME); -#ifdef DEBUG_IPC - fprintf(stderr, "darwin creating sem %s to cover shared mem.\n", semname); -#endif - SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1); - sem_unlink(semname); - } - } - - 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) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin semget failed because if (nsems != 0 && SemInfo->set[semid].nsems < nsems) %d %d\n", - nsems, SemInfo->set[semid].nsems); -#endif - 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) - { -#ifdef DEBUG_IPC - fprintf(stderr, "darwin semget failed because all keys were -1\n"); -#endif - sem_post(SemInfo->sem); - errno = ENOSPC; - return -1; - } - - for (semnum = 0; semnum < nsems; semnum++) - { - sprintf(semname, "%s-%d-%d", SEM_NAME, semid, semnum); -#ifdef DEBUG_IPC - fprintf(stderr, "darwin creating sem %s to cover set %d num %dm.\n", semname, semid, semnum); -#endif - SemInfo->set[semid].sem[semnum] = sem_open(semname, O_CREAT, semflg & 0777, 0); - sem_unlink(semname); - - /* 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_close(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; -} |