📄 ipc.c
字号:
EPRINTF("\nIpcSemaphoreCreate, status %d, returns %d\n", *status, semId); fflush(stdout); fflush(stderr);#endif return semId;}/****************************************************************************//* IpcSemaphoreSet() - sets the initial value of the semaphore *//* *//* note: the xxx_return variables are only used for debugging. *//****************************************************************************/#ifdef NOT_USEDstatic int IpcSemaphoreSet_return;voidIpcSemaphoreSet(int semId, int semno, int value){ int errStatus; union semun semun; semun.val = value; errStatus = semctl(semId, semno, SETVAL, semun); IpcSemaphoreSet_return = errStatus; if (errStatus == -1) { EPRINTF("IpcSemaphoreSet: semctl failed (%s) id=%d", strerror(errno), semId); }}#endif/****************************************************************************//* IpcSemaphoreKill(key) - removes a semaphore *//* *//****************************************************************************/voidIpcSemaphoreKill(IpcSemaphoreKey key){ int semId; union semun semun; /* kill semaphore if existent */ semId = semget(key, 0, 0); if (semId != -1) semctl(semId, 0, IPC_RMID, semun);}/****************************************************************************//* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore *//* *//* note: the xxx_return variables are only used for debugging. *//****************************************************************************/static int IpcSemaphoreLock_return;voidIpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock){ extern int errno; int errStatus; struct sembuf sops; sops.sem_op = lock; sops.sem_flg = 0; sops.sem_num = sem; /* ---------------- * Note: if errStatus is -1 and errno == EINTR then it means we * returned from the operation prematurely because we were * sent a signal. So we try and lock the semaphore again. * I am not certain this is correct, but the semantics aren't * clear it fixes problems with parallel abort synchronization, * namely that after processing an abort signal, the semaphore * call returns with -1 (and errno == EINTR) before it should. * -cim 3/28/90 * ---------------- */ do { errStatus = semop(semId, &sops, 1); } while (errStatus == -1 && errno == EINTR); IpcSemaphoreLock_return = errStatus; if (errStatus == -1) { EPRINTF("IpcSemaphoreLock: semop failed (%s) id=%d", strerror(errno), semId); proc_exit(255); }}/****************************************************************************//* IpcSemaphoreUnlock(semId, sem, lock) - unlocks a semaphore *//* *//* note: the xxx_return variables are only used for debugging. *//****************************************************************************/static int IpcSemaphoreUnlock_return;voidIpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock){ extern int errno; int errStatus; struct sembuf sops; sops.sem_op = -lock; sops.sem_flg = 0; sops.sem_num = sem; /* ---------------- * Note: if errStatus is -1 and errno == EINTR then it means we * returned from the operation prematurely because we were * sent a signal. So we try and lock the semaphore again. * I am not certain this is correct, but the semantics aren't * clear it fixes problems with parallel abort synchronization, * namely that after processing an abort signal, the semaphore * call returns with -1 (and errno == EINTR) before it should. * -cim 3/28/90 * ---------------- */ do { errStatus = semop(semId, &sops, 1); } while (errStatus == -1 && errno == EINTR); IpcSemaphoreUnlock_return = errStatus; if (errStatus == -1) { EPRINTF("IpcSemaphoreUnlock: semop failed (%s) id=%d", strerror(errno), semId); proc_exit(255); }}intIpcSemaphoreGetCount(IpcSemaphoreId semId, int sem){ int semncnt; union semun dummy; /* for Solaris */ semncnt = semctl(semId, sem, GETNCNT, dummy); return semncnt;}intIpcSemaphoreGetValue(IpcSemaphoreId semId, int sem){ int semval; union semun dummy; /* for Solaris */ semval = semctl(semId, sem, GETVAL, dummy); return semval;}/****************************************************************************//* IpcMemoryCreate(memKey) *//* *//* - returns the memory identifier, if creation succeeds *//* returns IpcMemCreationFailed, if failure *//****************************************************************************/IpcMemoryIdIpcMemoryCreate(IpcMemoryKey memKey, uint32 size, int permission){ IpcMemoryId shmid; if (memKey == PrivateIPCKey) { /* private */ shmid = PrivateMemoryCreate(memKey, size); } else shmid = shmget(memKey, size, IPC_CREAT | permission); if (shmid < 0) { EPRINTF("IpcMemoryCreate: shmget failed (%s) " "key=%d, size=%d, permission=%o", strerror(errno), memKey, size, permission); return IpcMemCreationFailed; } /* if (memKey == PrivateIPCKey) */ on_shmem_exit(IPCPrivateMemoryKill, (caddr_t) shmid); return shmid;}/****************************************************************************//* IpcMemoryIdGet(memKey, size) returns the shared memory Id *//* or IpcMemIdGetFailed *//****************************************************************************/IpcMemoryIdIpcMemoryIdGet(IpcMemoryKey memKey, uint32 size){ IpcMemoryId shmid; shmid = shmget(memKey, size, 0); if (shmid < 0) { EPRINTF("IpcMemoryIdGet: shmget failed (%s) " "key=%d, size=%d, permission=%o", strerror(errno), memKey, size, 0); return IpcMemIdGetFailed; } return shmid;}/****************************************************************************//* IpcMemoryDetach(status, shmaddr) removes a shared memory segment *//* from a backend address space *//* (only called by backends running under the postmaster) *//****************************************************************************/static voidIpcMemoryDetach(int status, char *shmaddr){ if (shmdt(shmaddr) < 0) elog(NOTICE, "IpcMemoryDetach: shmdt(0x%x): %m", shmaddr);}/****************************************************************************//* IpcMemoryAttach(memId) returns the adress of shared memory *//* or IpcMemAttachFailed *//* *//* CALL IT: addr = (struct <MemoryStructure> *) IpcMemoryAttach(memId); *//* *//****************************************************************************/char *IpcMemoryAttach(IpcMemoryId memId){ char *memAddress; if (UsePrivateMemory) memAddress = (char *) PrivateMemoryAttach(memId); else memAddress = (char *) shmat(memId, 0, 0); /* if ( *memAddress == -1) { XXX ??? */ if (memAddress == (char *) -1) { EPRINTF("IpcMemoryAttach: shmat failed (%s) id=%d", strerror(errno), memId); return IpcMemAttachFailed; } if (!UsePrivateMemory) on_shmem_exit(IpcMemoryDetach, (caddr_t) memAddress); return (char *) memAddress;}/****************************************************************************//* IpcMemoryKill(memKey) removes a shared memory segment *//* (only called by the postmaster and standalone backends) *//****************************************************************************/voidIpcMemoryKill(IpcMemoryKey memKey){ IpcMemoryId shmid; if (!UsePrivateMemory && (shmid = shmget(memKey, 0, 0)) >= 0) { if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL) < 0) { elog(NOTICE, "IpcMemoryKill: shmctl(%d, %d, 0) failed: %m", shmid, IPC_RMID); } }}#ifdef HAS_TEST_AND_SET/* ------------------ * use hardware locks to replace semaphores for sequent machines * to avoid costs of swapping processes and to provide unlimited * supply of locks. * ------------------ *//* used in spin.c */SLock *SLockArray = NULL;static SLock **FreeSLockPP;static int *UnusedSLockIP;static slock_t *SLockMemoryLock;static IpcMemoryId SLockMemoryId = -1;struct ipcdummy{ /* to get alignment/size right */ SLock *free; int unused; slock_t memlock; SLock slocks[MAX_SPINS + 1];};#define SLOCKMEMORYSIZE sizeof(struct ipcdummy)voidCreateAndInitSLockMemory(IPCKey key){ int id; SLock *slckP; SLockMemoryId = IpcMemoryCreate(key, SLOCKMEMORYSIZE, 0700); AttachSLockMemory(key); *FreeSLockPP = NULL; *UnusedSLockIP = (int) FIRSTFREELOCKID; for (id = 0; id < (int) FIRSTFREELOCKID; id++) { slckP = &(SLockArray[id]); S_INIT_LOCK(&(slckP->locklock)); slckP->flag = NOLOCK; slckP->nshlocks = 0; S_INIT_LOCK(&(slckP->shlock)); S_INIT_LOCK(&(slckP->exlock)); S_INIT_LOCK(&(slckP->comlock)); slckP->next = NULL; } return;}voidAttachSLockMemory(IPCKey key){ struct ipcdummy *slockM; if (SLockMemoryId == -1) SLockMemoryId = IpcMemoryIdGet(key, SLOCKMEMORYSIZE); if (SLockMemoryId == -1) elog(FATAL, "SLockMemory not in shared memory"); slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId); if (slockM == IpcMemAttachFailed) elog(FATAL, "AttachSLockMemory: could not attach segment"); FreeSLockPP = (SLock **) &(slockM->free); UnusedSLockIP = (int *) &(slockM->unused); SLockMemoryLock = (slock_t *) &(slockM->memlock); S_INIT_LOCK(SLockMemoryLock); SLockArray = (SLock *) &(slockM->slocks[0]); return;}#ifdef NOT_USEDboolLockIsFree(int lockid){ return SLockArray[lockid].flag == NOLOCK;}#endif#endif /* HAS_TEST_AND_SET */#ifdef NOT_USEDstatic voidIpcConfigTip(void){ fprintf(stderr, "This type of error is usually caused by improper\n"); fprintf(stderr, "shared memory or System V IPC semaphore configuration.\n"); fprintf(stderr, "See the FAQ for more detailed information\n");}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -