mirror of https://github.com/postgres/postgres
parent
839de3c577
commit
41fe2a2a03
@ -0,0 +1,30 @@ |
|||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Makefile--
|
||||||
|
# Makefile for port/darwin
|
||||||
|
#
|
||||||
|
# IDENTIFICATION
|
||||||
|
# $Header: /cvsroot/pgsql/src/backend/port/darwin/Makefile,v 1.1 2000/12/11 00:49:54 tgl Exp $
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
subdir = src/backend/port/darwin
|
||||||
|
top_builddir = ../../../..
|
||||||
|
include $(top_builddir)/src/Makefile.global |
||||||
|
|
||||||
|
OBJS = sem.o
|
||||||
|
|
||||||
|
all: SUBSYS.o |
||||||
|
|
||||||
|
SUBSYS.o: $(OBJS) |
||||||
|
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
|
||||||
|
|
||||||
|
depend dep: |
||||||
|
$(CC) -MM $(CFLAGS) *.c >depend
|
||||||
|
|
||||||
|
clean: |
||||||
|
rm -f SUBSYS.o $(OBJS)
|
||||||
|
|
||||||
|
ifeq (depend,$(wildcard depend)) |
||||||
|
include depend |
||||||
|
endif |
@ -0,0 +1,374 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* 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.1 2000/12/11 00:49:54 tgl Exp $ |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <errno.h> |
||||||
|
#include <semaphore.h> |
||||||
|
#include <string.h> |
||||||
|
#include <sys/types.h> |
||||||
|
#include <unistd.h> |
||||||
|
#include <fcntl.h> |
||||||
|
#include <sys/mman.h> |
||||||
|
#include "postgres.h" |
||||||
|
#include "storage/ipc.h" |
||||||
|
#include "storage/proc.h" |
||||||
|
#include "port/darwin/sem.h" |
||||||
|
|
||||||
|
#define SEMMAX IPC_NMAXSEM |
||||||
|
#define SETMAX ((MAXBACKENDS + SEMMAX - 1) / SEMMAX) |
||||||
|
#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_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; |
||||||
|
|
||||||
|
|
||||||
|
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_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 /* , semnum1 */ ; |
||||||
|
int exist = 0; |
||||||
|
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; |
||||||
|
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. */ |
||||||
|
ftruncate(fd, sizeof(struct sem_info)); |
||||||
|
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 */ |
||||||
|
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_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) |
||||||
|
{ |
||||||
|
#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 < SETMAX && SemInfo->set[semid].key != -1) |
||||||
|
semid++; |
||||||
|
if (semid >= SETMAX) |
||||||
|
{ |
||||||
|
#ifdef DEBUG_IPC |
||||||
|
fprintf(stderr, "darwin semget failed because all keys were -1 up to SETMAX\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); |
||||||
|
|
||||||
|
/* Currently sem_init always returns -1.
|
||||||
|
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) { |
||||||
|
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) { |
||||||
|
sem_close( SemInfo->set[semid].sem[semnum1] ); |
||||||
|
} |
||||||
|
sem_post( SemInfo->sem ); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
*/ |
||||||
|
} |
||||||
|
|
||||||
|
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 >= 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; |
||||||
|
} |
@ -1,8 +1,8 @@ |
|||||||
/* $Header: /cvsroot/pgsql/src/backend/port/dynloader/darwin.h,v 1.2 2000/11/09 19:00:50 petere Exp $ */ |
/* $Header: /cvsroot/pgsql/src/backend/port/dynloader/darwin.h,v 1.3 2000/12/11 00:49:54 tgl Exp $ */ |
||||||
|
|
||||||
#include "fmgr.h" |
#include "fmgr.h" |
||||||
|
|
||||||
void *pg_dlopen(const char *filename); |
void* pg_dlopen(char *filename); |
||||||
PGFunction pg_dlsym(void *handle, const char *funcname); |
PGFunction pg_dlsym(void *handle, char *funcname); |
||||||
void pg_dlclose(void *handle); |
void pg_dlclose(void *handle); |
||||||
const char *pg_dlerror(void); |
char* pg_dlerror(void); |
||||||
|
@ -0,0 +1,75 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* sem.h |
||||||
|
* System V Semaphore Emulation |
||||||
|
* |
||||||
|
* Copyright (c) 1999, repas AEG Automation GmbH |
||||||
|
* |
||||||
|
* |
||||||
|
* IDENTIFICATION |
||||||
|
* $Header: /cvsroot/pgsql/src/include/port/darwin/Attic/sem.h,v 1.1 2000/12/11 00:49:53 tgl Exp $ |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _SYS_SEM_H |
||||||
|
#define _SYS_SEM_H |
||||||
|
|
||||||
|
/* #define DEBUG_IPC here if you want to see the shim in action */ |
||||||
|
|
||||||
|
#include <sys/ipc.h> |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
/*
|
||||||
|
* Semctl Command Definitions. |
||||||
|
*/ |
||||||
|
|
||||||
|
#define GETNCNT 3 /* get semncnt */ |
||||||
|
#define GETPID 4 /* get sempid */ |
||||||
|
#define GETVAL 5 /* get semval */ |
||||||
|
#define GETALL 6 /* get all semval's */ |
||||||
|
#define GETZCNT 7 /* get semzcnt */ |
||||||
|
#define SETVAL 8 /* set semval */ |
||||||
|
#define SETALL 9 /* set all semval's */ |
||||||
|
|
||||||
|
#ifndef ushort_t |
||||||
|
#define ushort_t unsigned int |
||||||
|
#endif |
||||||
|
|
||||||
|
/*
|
||||||
|
* There is one semaphore structure for each semaphore in the system. |
||||||
|
*/ |
||||||
|
|
||||||
|
struct sem |
||||||
|
{ |
||||||
|
ushort_t semval; /* semaphore text map address */ |
||||||
|
pid_t sempid; /* pid of last operation */ |
||||||
|
ushort_t semncnt; /* # awaiting semval > cval */ |
||||||
|
ushort_t semzcnt; /* # awaiting semval = 0 */ |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* User semaphore template for semop system calls. |
||||||
|
*/ |
||||||
|
|
||||||
|
struct sembuf |
||||||
|
{ |
||||||
|
ushort_t sem_num; /* semaphore # */ |
||||||
|
short sem_op; /* semaphore operation */ |
||||||
|
short sem_flg; /* operation flags */ |
||||||
|
}; |
||||||
|
|
||||||
|
extern int semctl(int semid, int semnum, int cmd, /* ... */ union semun arg); |
||||||
|
extern int semget(key_t key, int nsems, int semflg); |
||||||
|
extern int semop(int semid, struct sembuf * sops, size_t nsops); |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* _SYS_SEM_H */ |
Loading…
Reference in new issue