3 * $Header: /cvsroot/pgpool/pgpool-II/pool_sema.c,v 1.5.2.2 2009/08/22 04:19:49 t-ishii Exp $
5 * pgpool: a language independent connection pool server for PostgreSQL
6 * written by Tatsuo Ishii
8 * Portions Copyright (c) 2003-2009, PgPool Global Development Group
9 * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group
11 * Permission to use, copy, modify, and distribute this software and
12 * its documentation for any purpose and without fee is hereby
13 * granted, provided that the above copyright notice appear in all
14 * copies and that both that copyright notice and this permission
15 * notice appear in supporting documentation, and that the name of the
16 * author not be used in advertising or publicity pertaining to
17 * distribution of the software without specific, written prior
18 * permission. The author makes no representations about the
19 * suitability of this software for any purpose. It is provided "as
20 * is" without express or implied warranty.
32 #ifndef HAVE_UNION_SEMUN
37 unsigned short *array;
46 * Removes a semaphore set.
49 IpcSemaphoreKill(int status, Datum semId)
52 struct semid_ds seminfo;
55 * Is a previously-existing sema segment still existing and in use?
58 if (semctl(semId, 0, IPC_STAT, semun) < 0
59 && (errno == EINVAL || errno == EACCES
66 semun.val = 0; /* unused, but keep compiler quiet */
68 if (semctl(semId, 0, IPC_RMID) < 0)
69 pool_log("semctl(%lu, 0, IPC_RMID, ...) failed: %s", semId, strerror(errno));
73 * Create a semaphore set and initialize.
76 pool_semaphore_create(int numSems)
80 /* Try to create new semaphore set */
81 semId = semget(IPC_PRIVATE, numSems, IPC_CREAT | IPC_EXCL | IPCProtection);
85 pool_error("could not create %d semaphores: %s", numSems, strerror(errno));
89 on_shmem_exit(IpcSemaphoreKill, semId);
91 /* Initialize it to count 1 */
92 for (i = 0; i < numSems; i++)
97 if (semctl(semId, i, SETVAL, semun) < 0)
99 pool_error("semctl(%d, %d, SETVAL, %d) failed: %s",
100 semId, i, 1, strerror(errno));
109 * Lock a semaphore (decrement count), blocking if count would be < 0
112 pool_semaphore_lock(int semNum)
117 sops.sem_op = -1; /* decrement */
119 sops.sem_num = semNum;
122 * Note: if errStatus is -1 and errno == EINTR then it means we returned
123 * from the operation prematurely because we were sent a signal. So we
124 * try and lock the semaphore again.
128 errStatus = semop(semId, &sops, 1);
129 } while (errStatus < 0 && errno == EINTR);
132 pool_error("semop(id=%d) failed: %s", semId, strerror(errno));
136 * Unlock a semaphore (increment count)
139 pool_semaphore_unlock(int semNum)
144 sops.sem_op = 1; /* increment */
146 sops.sem_num = semNum;
149 * Note: if errStatus is -1 and errno == EINTR then it means we returned
150 * from the operation prematurely because we were sent a signal. So we
151 * try and unlock the semaphore again. Not clear this can really happen,
152 * but might as well cope.
156 errStatus = semop(semId, &sops, 1);
157 } while (errStatus < 0 && errno == EINTR);
160 pool_error("semop(id=%d) failed: %s", semId, strerror(errno));