⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lock.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * $Id: lock.c,v 1.47 2004/08/24 09:00:41 janakj Exp $ * * 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: *    info@iptel.org * * 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 *//* * History: * -------- *  2003-03-17  converted to locking.h (andrei) *  2004-07-28  s/lock_set_t/gen_lock_set_t/ because of a type conflict *              on darwin (andrei) */#include "defs.h"#include <errno.h>#include "lock.h"#include "timer.h"#include "../../dprint.h"#ifndef GEN_LOCK_T_PREFERED /* semaphore probing limits */#define SEM_MIN		16#define SEM_MAX		4096/* we implement mutex here using lock sets; as the number of   semaphores may be limited (e.g. sysv) and number of synchronized    elements high, we partition the synced SER elements and share    semaphores in each of the partitions; we try to use as many    semaphores as OS gives us for finest granularity.    we allocate the locks according to the following plans:   1) transaction timer lists have each a semaphore in      a semaphore set   2) retransmission timer lists have each a semaphore      in a semaphore set   3) we allocate a semaphore set for hash_entries and      try to use as many semaphores in it as OS allows;      we partition the the hash_entries by available      semaphores which are shared  in each partition   4) cells get always the same semaphore as its hash      entry in which they live*//* and the maximum number of semaphores in the entry_semaphore set */static int sem_nr;gen_lock_set_t* timer_semaphore=0;gen_lock_set_t* entry_semaphore=0;gen_lock_set_t* reply_semaphore=0;#endif/* timer group locks */static ser_lock_t* timer_group_lock=0; /* pointer to a TG_NR lock array,								    it's safer if we alloc this in shared mem 									( required for fast lock ) *//* initialize the locks; return 0 on success, -1 otherwise*/int lock_initialize(){	int i;#ifndef GEN_LOCK_T_PREFERED	int probe_run;#endif	/* first try allocating semaphore sets with fixed number of semaphores */	DBG("DEBUG: lock_initialize: lock initialization started\n");	timer_group_lock=shm_malloc(TG_NR*sizeof(ser_lock_t));	if (timer_group_lock==0){		LOG(L_CRIT, "ERROR: lock_initialize: out of shm mem\n");		goto error;	}#ifdef GEN_LOCK_T_PREFERED	for(i=0;i<TG_NR;i++) lock_init(&timer_group_lock[i]);#else	/* transaction timers */	if (((timer_semaphore= lock_set_alloc( TG_NR ) ) == 0)||			(lock_set_init(timer_semaphore)==0)){		if (timer_semaphore) lock_set_destroy(timer_semaphore);		LOG(L_CRIT, "ERROR: lock_initialize:  "			"transaction timer semaphore initialization failure: %s\n",				strerror(errno));		goto error;	}	for (i=0; i<TG_NR; i++) {		timer_group_lock[i].semaphore_set = timer_semaphore;		timer_group_lock[i].semaphore_index = timer_group[ i ];	}	i=SEM_MIN;	/* probing phase: 0=initial, 1=after the first failure */	probe_run=0;again:	do {		if (entry_semaphore!=0){ /* clean-up previous attempt */			lock_set_destroy(entry_semaphore);			lock_set_dealloc(entry_semaphore);		}		if (reply_semaphore!=0){			lock_set_destroy(reply_semaphore);			lock_set_dealloc(reply_semaphore);		}				if (i==0){			LOG(L_CRIT, "lock_initialize: could not allocate semaphore"					" sets\n");			goto error;		}				if (((entry_semaphore=lock_set_alloc(i))==0)||			(lock_set_init(entry_semaphore)==0)) {			DBG("DEBUG: lock_initialize: entry semaphore "					"initialization failure:  %s\n", strerror( errno ) );			if (entry_semaphore){				lock_set_dealloc(entry_semaphore);				entry_semaphore=0;			}			/* first time: step back and try again */			if (probe_run==0) {					DBG("DEBUG: lock_initialize: first time "								"semaphore allocation failure\n");					i--;					probe_run=1;					continue;				/* failure after we stepped back; give up */			} else {					DBG("DEBUG: lock_initialize:   second time semaphore"							" allocation failure\n");					goto error;			}		}		/* allocation succeeded */		if (probe_run==1) { /* if ok after we stepped back, we're done */			break;		} else { /* if ok otherwise, try again with larger set */			if (i==SEM_MAX) break;			else {				i++;				continue;			}		}	} while(1);	sem_nr=i;	if (((reply_semaphore=lock_set_alloc(i))==0)||		(lock_set_init(reply_semaphore)==0)){			if (reply_semaphore){				lock_set_dealloc(reply_semaphore);				reply_semaphore=0;			}			DBG("DEBUG:lock_initialize: reply semaphore initialization"				" failure: %s\n", strerror(errno));			probe_run=1;			i--;			goto again;	}	/* return success */	LOG(L_INFO, "INFO: semaphore arrays of size %d allocated\n", sem_nr );#endif /* GEN_LOCK_T_PREFERED*/	return 0;error:	lock_cleanup();	return -1;}#ifdef GEN_LOCK_T_PREFEREDvoid lock_cleanup(){	/* must check if someone uses them, for now just leave them allocated*/	if (timer_group_lock) shm_free((void*)timer_group_lock);}#else/* remove the semaphore set from system */void lock_cleanup(){	/* that's system-wide; all other processes trying to use	   the semaphore will fail! call only if it is for sure	   no other process lives 	*/	/* sibling double-check missing here; install a signal handler */	if (entry_semaphore !=0){		lock_set_destroy(entry_semaphore);		lock_set_dealloc(entry_semaphore);	};	if (timer_semaphore !=0){		lock_set_destroy(timer_semaphore);		lock_set_dealloc(timer_semaphore);	};	if (reply_semaphore !=0) {		lock_set_destroy(reply_semaphore);		lock_set_dealloc(reply_semaphore);	};	entry_semaphore = timer_semaphore = reply_semaphore = 0;	if (timer_group_lock) shm_free(timer_group_lock);}#endif /*GEN_LOCK_T_PREFERED*/int init_cell_lock( struct cell *cell ){#ifdef GEN_LOCK_T_PREFERED	lock_init(&cell->reply_mutex);#else	cell->reply_mutex.semaphore_set=reply_semaphore;	cell->reply_mutex.semaphore_index = cell->hash_index % sem_nr;#endif /* GEN_LOCK_T_PREFERED */	return 0;}int init_entry_lock( struct s_table* ht, struct entry *entry ){#ifdef GEN_LOCK_T_PREFERED	lock_init(&entry->mutex);#else	/* just advice which of the available semaphores to use;	   specifically, all entries are partitioned into as	   many partitions as number of available semaphores allows        */	entry->mutex.semaphore_set=entry_semaphore;	entry->mutex.semaphore_index = ( ((char *)entry - (char *)(ht->entrys ) )               / sizeof(struct entry) ) % sem_nr;#endif	return 0;}int release_cell_lock( struct cell *cell ){#ifndef GEN_LOCK_T_PREFERED	/* don't do anything here -- the init_*_lock procedures	   just advised on usage of shared semaphores but did not	   generate them	*/#endif	return 0;}int release_entry_lock( struct entry *entry ){	/* the same as above */	return 0;}int release_timerlist_lock( struct timer *timerlist ){	/* the same as above */	return 0;}int init_timerlist_lock( enum lists timerlist_id){	get_timertable()->timers[timerlist_id].mutex=		&(timer_group_lock[ timer_group[timerlist_id] ]);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -