Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

sem_utils.c

00001 /*-
00002  * Copyright (c) 2004-2005
00003  *      Sleepycat Software.  All rights reserved.
00004  *
00005  * http://www.apache.org/licenses/LICENSE-2.0.txt
00006  * 
00007  * authors: George Schlossnagle <[email protected]>
00008  */
00009 extern "C"
00010 {
00011 #include <sys/types.h>
00012 #include <sys/ipc.h>
00013 #include <sys/sem.h>
00014 #include <sys/stat.h>
00015 #include <unistd.h>
00016 
00017 #include "config.h"
00018 #include "sem_utils.h"
00019 
00020 
00021 #include <errno.h>
00022 }
00023 extern int errno;
00024 
00025 #if HAVE_SEMUN
00026 /* we have semun, no need to define */
00027 #else
00028 union semun {
00029     int val;                  /* value for SETVAL */
00030     struct semid_ds *buf;     /* buffer for IPC_STAT, IPC_SET */
00031     unsigned short *array;    /* array for GETALL, SETALL */
00032                               /* Linux specific part: */
00033     struct seminfo *__buf;    /* buffer for IPC_INFO */
00034 };
00035 #endif
00036 
00037 #ifndef SEM_R
00038 # define SEM_R 0444
00039 #endif
00040 #ifndef SEM_A
00041 # define SEM_A 0222
00042 #endif
00043 
00044 int md4_sem_create(int semnum, unsigned short *start)
00045 {
00046     int semid;
00047     int perms = 0777;
00048     union semun arg;
00049     key_t key = 12345;
00050     int count = 0;
00051     while((semid = semget(key, semnum, IPC_CREAT | IPC_EXCL | perms)) == -1) {
00052       if(count++ > 2) {
00053         return -1;
00054       }
00055       if (errno == EEXIST) {
00056         semid = semget(key, 1, perms);
00057         md4_sem_destroy(semid);
00058       }
00059     }  
00060     arg.array = start;
00061     if(semctl(semid, 0, SETALL, arg) < 0) {
00062       /* destroy (FIXME) and return */
00063       md4_sem_destroy(semid);
00064       return -1;
00065     }
00066     return semid;
00067 }
00068 
00069 void md4_sem_destroy(int semid)
00070 {
00071     union semun dummy;
00072     /* semid should always be 0, this clobbers the whole set */
00073     semctl(semid, 0, IPC_RMID, dummy);
00074 }
00075 
00076 void md4_sem_lock(int semid, int semnum)
00077 {
00078     struct sembuf sops;
00079     sops.sem_num = semnum;
00080     sops.sem_op = -1;
00081     sops.sem_flg = SEM_UNDO;
00082     semop(semid, &sops, 1);
00083 }
00084     
00085 void md4_sem_unlock(int semid, int semnum)
00086 {
00087     struct sembuf sops;
00088     sops.sem_num = semnum;
00089     sops.sem_op = 1;
00090     sops.sem_flg = SEM_UNDO;
00091     semop(semid, &sops, 1);
00092 }
00093 
00094 void md4_sem_wait_for_zero(int semid, int semnum)
00095 {
00096     struct sembuf sops;
00097     sops.sem_num = semnum;
00098     sops.sem_op = 0;
00099     sops.sem_flg = SEM_UNDO;
00100     semop(semid, &sops, 1);
00101 }
00102 
00103 void md4_sem_set(int semid, int semnum, int value)
00104 {
00105     union semun arg;
00106     arg.val = value;
00107     semctl(semid, semnum, SETALL, arg);
00108 }
00109 
00110 int md4_sem_get(int semid, int semnum)
00111 {
00112     union semun arg;
00113     return semctl(semid, 0, GETVAL, arg);
00114 }
00115 
00116 /* vim: set ts=4 sts=4 expandtab bs=2 ai : */

Generated on Sun Dec 25 12:14:41 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2