3 * Copyright (C) 2002 Simone Piccardi
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /*****************************************************************************
21 * File Mutex.c: define a set of functions for mutex manipulation
23 * Author: S. Piccardi Dec. 2002
25 * $Id: Mutex.c,v 1.7 2003/05/02 09:55:14 piccardi Exp $
27 *****************************************************************************/
28 #include <sys/sem.h> /* IPC semaphore declarations */
29 #include <sys/types.h>
32 #include <signal.h> /* signal handling declarations */
36 * Function MutexCreate: create a mutex/semaphore
38 * First call create a semaphore, using the given key.
39 * We want only one semaphore so we set second argument to 1; third
40 * parameter is the flag argument, and is set to create a semaphore
41 * with R/W privilege for the user.
42 * Second call initialize the semaphore to 1 (unlocked)
44 * Input: an IPC key value (to create an unique semaphore)
45 * Return: the semaphore id# or -1 on error
47 int MutexCreate(key_t ipc_key)
49 const union semun semunion={1}; /* semaphore union structure */
51 sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */
52 if (sem_id == -1) { /* if error return code */
55 ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */
62 * Function MutexFind: get the semaphore/mutex Id given the IPC key value
64 * Input: an IPC key value
66 int MutexFind(key_t ipc_key)
68 return semget(ipc_key, 1, 0);
71 * Function MutexRead: read the current value of the mutex/semaphore
73 * Input: a semaphore id #
74 * Return: the semaphore value
76 int MutexRead(int sem_id)
78 return semctl(sem_id, 0, GETVAL);
81 * Define sembuf structures to lock and unlock the semaphore
82 * (used to implement a mutex)
84 struct sembuf sem_lock={ /* to lock semaphore */
85 0, /* semaphore number (only one so 0) */
86 -1, /* operation (-1 to use resource) */
87 SEM_UNDO}; /* flag (set for undo at exit) */
88 struct sembuf sem_ulock={ /* to unlock semaphore */
89 0, /* semaphore number (only one so 0) */
90 1, /* operation (1 to release resource) */
91 SEM_UNDO}; /* flag (in this case 0) */
93 * Function MutexLock: to lock a mutex/semaphore
95 * Input: a semaphore id #
96 * Output: semop return code (0 OK, -1 KO)
98 int MutexLock(int sem_id)
100 return semop(sem_id, &sem_lock, 1);
103 * Function MutexUnlock: to unlock a mutex/semaphore
105 * Input: a semaphore id #
106 * Return: semop return code (0 OK, -1 KO)
108 int MutexUnlock(int sem_id)
110 return semop(sem_id, &sem_ulock, 1);
113 * Function MutexRemove: remove a mutex/semaphore
115 * Input: a semaphore id #
116 * Return: return code of semctl
118 int MutexRemove(int sem_id)
120 return semctl(sem_id, 0, IPC_RMID);
122 /*****************************************************************************
126 * Create a mutex usinf file locking. Use file locking to lock a file
127 * as a mutex request, and unlock it as a mutex release.
129 * Author: S. Piccardi Dec. 2002
131 *****************************************************************************/
133 * Function CreateMutex: Create a mutex using file locking.
135 * Open a new lock file (creating it if not existent, and giving error
136 * otherwise). Is a simple wrapper for open.
139 * Output: a file descriptor (>0 OK, -1 KO)
141 int CreateMutex(const char *path_name)
143 return open(path_name, O_EXCL|O_CREAT);
146 * Function UnlockMutex: unlock a file.
148 * Open a lock file (failing if not existent). Is a simple wrapper for
152 * Output: a return code (>0 OK, -1 KO)
154 int FindMutex(const char *path_name)
156 return open(path_name, O_RDWR);
159 * Function LockMutex: lock mutex using file locking.
161 * Input: a mutex (i.e. a file descriptor)
162 * Output: a return code (0 OK, -1 KO)
164 int LockMutex(int fd)
166 struct flock lock; /* file lock structure */
167 /* first open the file (creating it if not existent) */
168 /* set flock structure */
169 lock.l_type = F_WRLCK; /* set type: read or write */
170 lock.l_whence = SEEK_SET; /* start from the beginning of the file */
171 lock.l_start = 0; /* set the start of the locked region */
172 lock.l_len = 0; /* set the length of the locked region */
174 return fcntl(fd, F_SETLKW, &lock);
177 * Function UnlockMutex: unlock a file.
179 * Input: a mutex (i.e. a file descriptor)
180 * Output: a return code (0 OK, -1 KO)
182 int UnlockMutex(int fd)
184 struct flock lock; /* file lock structure */
185 /* set flock structure */
186 lock.l_type = F_UNLCK; /* set type: unlock */
187 lock.l_whence = SEEK_SET; /* start from the beginning of the file */
188 lock.l_start = 0; /* set the start of the locked region */
189 lock.l_len = 0; /* set the length of the locked region */
191 return fcntl(fd, F_SETLK, &lock);
194 * Function RemoveMutex: remove a mutex (unlinking the lock file).
196 * Just remove the lock file.
199 * Output: a return code (0 OK, -1 KO)
201 int RemoveMutex(const char *path_name)
203 return unlink(path_name);
206 * Function ReadMutex: read a mutex status.
208 * Read the status for a mutex.
210 * Input: a mutex (i.e. a file descriptor)
211 * Output: the lock type (F_UNLCK, F_RDLCK or F_WRLCK, or -1 if KO)
213 int ReadMutex(int fd)
216 struct flock lock; /* file lock structure */
217 /* set flock structure */
218 lock.l_type = F_WRLCK; /* set type: unlock */
219 lock.l_whence = SEEK_SET; /* start from the beginning of the file */
220 lock.l_start = 0; /* set the start of the locked region */
221 lock.l_len = 0; /* set the length of the locked region */
223 if ( (res = fcntl(fd, F_GETLK, &lock)) ) {