Browse Source

- preliminary general locking stuff (uses fast lock, pthread sems, posix sems or sys v sems depending on what USE_* is defined)

Andrei Pelinescu-Onciul 22 years ago
parent
commit
01fd8ca61e
1 changed files with 186 additions and 0 deletions
  1. 186 0
      locking.h

+ 186 - 0
locking.h

@@ -0,0 +1,186 @@
+/* $Id$ */
+/*
+ *
+ * Copyright (C) 2001-2003 Fhg Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+    ser locking library
+    - created 16.12.2003 (andrei)
+
+Implements:
+
+	lock_t* lock_alloc();                    - allocates a lock in shared mem.
+	lock_t* lock_init(lock_t* lock);         - inits the lock
+	void    lock_destroy(lock_t* lock);      - removes the lock (e.g sysv rmid)
+	void    lock_dealloc(lock_t* lock);      - deallocates the lock's shared m.
+	void    lock_get(lock_t* lock);          - lock (mutex down)
+	void    lock_release(lock_t* lock);      - unlock (mutex up)
+*/
+
+#ifndef _locking_h
+#define _locking_h
+
+#include "mem/mem.h"
+#ifdef SHM_MEM
+#include "mem/shm_mem.h"
+#else
+#error "locking requires shared memroy support"
+#endif
+
+#ifdef FAST_LOCK
+#include "fastlock.h"
+
+typedef fl_lock_t lock_t;
+
+#define lock_alloc() shm_malloc(sizeof(lock_t))
+#define lock_destroy(lock) /* do nothing */ 
+#define lock_dealloc(lock) shm_free(lock)
+
+inline static lock_t* lock_init(lock_t* lock)
+{
+	init_lock(*lock);
+	return lock;
+}
+
+#define lock_get(lock) get_lock(lock)
+#define lock_release(lock) release_lock(lock)
+
+
+
+#elif defined USE_PTHREAD_MUTEX
+#include <pthread.h>
+
+typedef pthread_mutex_t lock_t;
+
+#define lock_alloc() shm_malloc(sizeof(lock_t))
+#define lock_destroy(lock) /* do nothing */ 
+#define lock_dealloc(lock) shm_free(lock)
+
+inline static lock_t* lock_init(lock_t* lock)
+{
+	if (pthread_mutex_init(lock, 0)==0) return lock;
+	else return 0;
+}
+
+#define lock_get(lock) pthread_mutex_lock(lock)
+#define lock_release(lock) pthread_mutex_unlock(lock)
+
+
+
+#elif defined USE_POSIX_SEM
+#include <semaphore.h>
+
+typedef sem_t lock_t;
+
+#define lock_alloc() shm_malloc(sizeof(lock_t))
+#define lock_destroy(lock) /* do nothing */ 
+#define lock_dealloc(lock) shm_free(lock)
+
+inline static lock_t* lock_init(lock_t* lock)
+{
+	if (sem_init(lock, 0, 1)<0) return 0;
+	return lock;
+}
+
+#define lock_get(lock) sem_wait(lock)
+#define lock_release(lock) sem_release(lock)
+
+
+#elif defined USE_SYSV_SEM
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if ((defined(HAVE_UNION_SEMUN) || defined(__GNU_LIBRARY__) )&& !defined(_SEM_SEMUN_UNDEFINED)) 
+	
+	/* union semun is defined by including sem.h */
+#else
+	/* according to X/OPEN we have to define it ourselves */
+	union semun {
+		int val;                      /* value for SETVAL */
+		struct semid_ds *buf;         /* buffer for IPC_STAT, IPC_SET */
+		unsigned short int *array;    /* array for GETALL, SETALL */
+		struct seminfo *__buf;        /* buffer for IPC_INFO */
+	};
+#endif
+
+typedef int lock_t;
+
+inline static lock_t* lock_alloc()
+{
+	lock_t* l;
+	
+	l=shm_malloc(sizeof(lock_t));
+	if (l==0) return 0;
+	*l=semget(IPC_PRIVATE, 1, 0700);
+	if (*l==-1) return 0;
+	return l;
+}
+
+
+inline static lock_t* lock_init(lock_t* lock)
+{
+	union semun su;
+	su.val=1;
+	if (semctl(*lock, 0, SETVAL, su)==-1){
+		/* init error*/
+		return 0;
+	}
+	return lock;
+}
+
+inline static void lock_destroy(lock_t* lock)
+{
+	semctl(*lock, 0, IPC_RMID, (union semun)(int)0);
+}
+
+#define lock_dealloc(lock) shm_free(lock)
+
+inline void lock_get(lock_t* lock)
+{
+	struct sembuf sop;
+
+	sop.sem_num=0;
+	sop.sem_op=-1; /* down */
+	sop.sem_flg=0; /*SEM_UNDO*/
+	semop(*lock, &sop, 1);
+}
+
+inline void lock_release(lock_t* lock)
+{
+	struct sembuf sop;
+	
+	sop.sem_num=0;
+	sop.sem_op=1; /* up */
+	sop.sem_flg=0; /* SEM_UNDO*/
+	semop(*lock, &sop, 1);
+}
+
+#else
+#error "no locking method selected"
+#endif
+
+
+
+#endif