Merge major BSD mutex and symbol conflict patches (bug #1816) (link patch still pending)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3273 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer 2004-06-22 17:42:14 +00:00
parent 2f4a0dc3f5
commit 5546e32355
30 changed files with 432 additions and 164 deletions

View File

@ -26,15 +26,12 @@ PROC=k8
#PROC=athlon
OPTIONS+=-m64
endif
else
ifeq (${OSARCH},FreeBSD)
PROC=$(shell uname -m)
else
ifeq (${OSARCH},OpenBSD)
endif
ifeq ($(findstring BSD,${OSARCH}),BSD)
PROC=$(shell uname -m)
endif
endif
endif
# Pentium Pro Optimize
#PROC=i686
@ -120,10 +117,15 @@ CFLAGS=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarati
CFLAGS+=$(OPTIMIZE)
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
ifeq (${OSARCH},FreeBSD)
CFLAGS+=-pthread
OSVERSION=$(shell make -V OSVERSION -f /usr/share/mk/bsd.port.subdir.mk)
CFLAGS+=$(if ${OSVERSION}<500016,-D_THREAD_SAFE)
LIBS+=$(if ${OSVERSION}<502102,-lc_r,-pthread)
INCLUDE+=-I/usr/local/include
endif
CFLAGS+=$(shell if [ -d /usr/local/include/spandsp ]; then echo "-I/usr/local/include/spandsp"; fi)
endif # FreeBSD
ifeq (${OSARCH},OpenBSD)
CFLAGS+=-pthread
endif
@ -161,14 +163,6 @@ SUBDIRS=res channels pbx apps codecs formats agi cdr astman stdtime
ifeq (${OSARCH},Linux)
LIBS=-ldl -lpthread
endif
ifeq (${OSARCH},OpenBSD)
LIBS=-pthread
else
ifeq (${OSARCH},FreeBSD)
LIBS=-pthread
else
endif
endif
LIBS+=-lncurses -lm
ifeq (${OSARCH},Linux)
LIBS+=-lresolv #-lnjamd

View File

@ -22,10 +22,10 @@ install: all
for x in $(AGIS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(AGI_DIR) ; done
eagi-test: eagi-test.o
$(CC) -o eagi-test eagi-test.o
$(CC) $(CFLAGS) -o eagi-test eagi-test.o
eagi-sphinx-test: eagi-sphinx-test.o
$(CC) -o eagi-sphinx-test eagi-sphinx-test.o
$(CC) $(CFLAGS) -o eagi-sphinx-test eagi-sphinx-test.o
clean:
rm -f *.so *.o look .depend eagi-test eagi-sphinx-test

View File

@ -122,7 +122,7 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
}
}
#define MAX 256
#define AST_MAX_WATCHERS 256
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, int *sentringing)
{
@ -133,7 +133,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
int orig = *to;
struct ast_frame *f;
struct ast_channel *peer = NULL;
struct ast_channel *watchers[MAX];
struct ast_channel *watchers[AST_MAX_WATCHERS];
int pos;
int single;
struct ast_channel *winner;

View File

@ -330,6 +330,7 @@ static void destroy_queue(struct ast_call_queue *q)
}
ast_mutex_unlock(&qlock);
free_members(q, 1);
ast_mutex_destroy(&q->lock);
free(q);
}
@ -628,7 +629,7 @@ static int valid_exit(struct queue_ent *qe, char digit)
return 0;
}
#define MAX 256
#define AST_MAX_WATCHERS 256
static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, char *digit)
{
@ -641,7 +642,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
int orig = *to;
struct ast_frame *f;
struct localuser *peer = NULL;
struct ast_channel *watchers[MAX];
struct ast_channel *watchers[AST_MAX_WATCHERS];
int pos;
struct ast_channel *winner;
struct ast_channel *in = qe->chan;

View File

@ -2113,7 +2113,10 @@ static int rpt_exec(struct ast_channel *chan, void *data)
int unload_module(void)
{
int i;
STANDARD_HANGUP_LOCALUSERS;
for(i = 0; i < nrpts; i++) {
ast_mutex_destroy(&rpt_vars[i].lock);
return ast_unregister_application(app);
return 0;
}

View File

@ -330,7 +330,7 @@ static void apply_options(struct ast_vm_user *vmu, char *options)
PGconn *dbhandler;
char dboption[256];
ast_mutex_t postgreslock;
AST_MUTEX_DEFINE_STATIC(postgreslock);
static int sql_init(void)
{
@ -342,8 +342,6 @@ static int sql_init(void)
ast_log(LOG_WARNING, "Error Logging into database %s: %s\n",dboption,PQerrorMessage(dbhandler));
return(-1);
}
ast_mutex_init(&postgreslock);
/* fprintf(stderr,"postgres login OK\n"); */
return(0);
}

View File

@ -49,6 +49,7 @@
#include "asterisk.h"
#include <asterisk/config.h>
#include <asterisk/config_pvt.h>
#include <sys/resource.h>
#if defined(__FreeBSD__)
#include <netdb.h>
@ -1561,6 +1562,11 @@ int main(int argc, char *argv[])
term_init();
printf(term_end());
fflush(stdout);
/* Test recursive mutex locking. */
if(test_for_thread_safety())
ast_verbose("Warning! Asterisk is not thread safe.\n");
if (option_console && !option_verbose)
ast_verbose("[ Reading Master Configuration ]");
ast_readconfig();

View File

@ -4,7 +4,7 @@
CFLAGS+=-DNO_AST_MM
OSARCH=$(shell uname -s)
ifeq (${OSARCH},FreeBSD)
ifeq ($(findstring BSD,${OSARCH}),BSD)
CFLAGS+=-I/usr/local/include -L/usr/local/lib
endif

View File

@ -213,8 +213,8 @@ static struct agent_pvt *add_agent(char *agent, int pending)
if (p) {
memset(p, 0, sizeof(struct agent_pvt));
strncpy(p->agent, tmp, sizeof(p->agent) -1);
ast_mutex_init( &p->lock );
ast_mutex_init( &p->app_lock );
ast_mutex_init(&p->lock);
ast_mutex_init(&p->app_lock);
p->owning_app = (pthread_t) -1;
p->app_sleep_cond = 1;
p->group = group;
@ -252,8 +252,11 @@ static int agent_cleanup(struct agent_pvt *p)
ast_mutex_unlock(&p->app_lock);
if (chan)
ast_channel_free(chan);
if (p->dead)
if (p->dead) {
ast_mutex_destroy(&p->lock);
ast_mutex_destroy(&p->app_lock);
free(p);
}
return 0;
}
@ -571,6 +574,8 @@ static int agent_hangup(struct ast_channel *ast)
kill it later */
p->abouttograb = 0;
} else if (p->dead) {
ast_mutex_destroy(&p->lock);
ast_mutex_destroy(&p->app_lock);
free(p);
} else {
if (p->chan) {
@ -844,6 +849,8 @@ static int read_agent_config(void)
/* Destroy if appropriate */
if (!p->owner) {
if (!p->chan) {
ast_mutex_destroy(&p->lock);
ast_mutex_destroy(&p->app_lock);
free(p);
} else {
/* Cause them to hang up */
@ -1425,8 +1432,11 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Agent '%s' logged out\n", p->agent);
/* If there is no owner, go ahead and kill it now */
if (p->dead && !p->owner)
if (p->dead && !p->owner) {
ast_mutex_destroy(&p->lock);
ast_mutex_destroy(&p->app_lock);
free(p);
}
}
else {
ast_mutex_unlock(&p->lock);

View File

@ -55,7 +55,8 @@
#include <fcntl.h>
#include <netdb.h>
#include <sys/signal.h>
#ifdef __OpenBSD__
#include <sys/param.h>
#if defined(BSD)
#include <netinet/in_systm.h>
#ifndef IPTOS_MINCOST
#define IPTOS_MINCOST 0x02
@ -186,8 +187,10 @@ static void __oh323_destroy(struct oh323_pvt *p)
}
if (!cur) {
ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
} else
} else {
ast_mutex_destroy(&p->lock);
free(p);
}
}
static void oh323_destroy(struct oh323_pvt *p)
@ -1840,11 +1843,14 @@ static struct ast_rtp_protocol oh323_rtp = {
set_rtp_peer: oh323_set_rtp_peer,
};
int load_module()
{
int res;
ast_mutex_init(&userl.lock);
ast_mutex_init(&peerl.lock);
ast_mutex_init(&aliasl.lock);
res = reload_config();
if (res) {
@ -1948,6 +1954,7 @@ int unload_module()
pl = p;
p = p->next;
/* free associated memory */
ast_mutex_destroy(&pl->lock);
free(pl);
}
iflist = NULL;

View File

@ -447,7 +447,7 @@ static struct iax_dpcache {
struct iax_dpcache *peer; /* For linking in peers */
} *dpcache;
static ast_mutex_t dpcache_lock;
AST_MUTEX_DEFINE_STATIC(dpcache_lock);
#ifdef DEBUG_SUPPORT
static void showframe(struct ast_iax_frame *f, struct ast_iax_full_hdr *fhi, int rx, struct sockaddr_in *sin)
@ -5369,6 +5369,12 @@ static int __unload_module(void)
int unload_module()
{
int x;
for (x=0;x<AST_IAX_MAX_CALLS;x++)
ast_mutex_destroy(&iaxsl[x]);
ast_mutex_destroy(&iaxq.lock);
ast_mutex_destroy(&userl.lock);
ast_mutex_destroy(&peerl.lock);
return __unload_module();
}
@ -5403,7 +5409,6 @@ int load_module(void)
ast_mutex_init(&iaxq.lock);
ast_mutex_init(&userl.lock);
ast_mutex_init(&peerl.lock);
ast_mutex_init(&dpcache_lock);
ast_cli_register(&cli_show_users);
ast_cli_register(&cli_show_channels);

View File

@ -507,7 +507,7 @@ static struct iax2_dpcache {
struct iax2_dpcache *peer; /* For linking in peers */
} *dpcache;
static ast_mutex_t dpcache_lock;
AST_MUTEX_DEFINE_STATIC(dpcache_lock);
static void iax_debug_output(const char *data)
{
@ -4434,6 +4434,7 @@ static int timing_read(int *id, int fd, short events, void *cbdata)
ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
free(drop->trunkdata);
ast_mutex_unlock(&drop->lock);
ast_mutex_destroy(&drop->lock);
free(drop);
}
@ -6820,6 +6821,10 @@ static int __unload_module(void)
int unload_module()
{
ast_mutex_destroy(&iaxq.lock);
ast_mutex_destroy(&userl.lock);
ast_mutex_destroy(&peerl.lock);
ast_mutex_destroy(&waresl.lock);
return __unload_module();
}
@ -6867,6 +6872,7 @@ int load_module(void)
ast_mutex_init(&iaxq.lock);
ast_mutex_init(&userl.lock);
ast_mutex_init(&peerl.lock);
ast_mutex_init(&waresl.lock);
ast_cli_register(&cli_show_users);
ast_cli_register(&cli_show_channels);

View File

@ -87,6 +87,7 @@ retrylock:
/* We had a glare on the hangup. Forget all this business,
return and destroy p. */
ast_mutex_unlock(&p->lock);
ast_mutex_destroy(&p->lock);
free(p);
return -1;
}
@ -271,6 +272,7 @@ static void local_destroy(struct local_pvt *p)
prev->next = cur->next;
else
locals = cur->next;
ast_mutex_destroy(cur);
free(cur);
break;
}
@ -324,8 +326,10 @@ static int local_hangup(struct ast_channel *ast)
}
ast_mutex_unlock(&locallock);
/* And destroy */
if (!glaredetect)
if (!glaredetect) {
ast_mutex_destroy(&p->lock);
free(p);
}
return 0;
}
if (p->chan && !p->launchedpbx)
@ -366,6 +370,7 @@ static struct local_pvt *local_alloc(char *data, int format)
tmp->reqformat = format;
if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->context, tmp->exten);
ast_mutex_destroy(&tmp->lock);
free(tmp);
tmp = NULL;
} else {

View File

@ -3423,15 +3423,19 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
gw->expire = -1;
gw->dynamic = 0;
if (ast_get_ip(&gw->addr, v->value)) {
if (!gw_reload)
if (!gw_reload) {
ast_mutex_destroy(&gw->msgs_lock);
free(gw);
}
return NULL;
}
}
} else if (!strcasecmp(v->name, "defaultip")) {
if (ast_get_ip(&gw->defaddr, v->value)) {
if (!gw_reload)
if (!gw_reload) {
ast_mutex_destroy(&gw->msgs_lock);
free(gw);
}
return NULL;
}
} else if (!strcasecmp(v->name, "permit") ||
@ -3501,15 +3505,17 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
}
if (!e) {
/* Allocate wildcard endpoint */
e = malloc(sizeof(struct mgcp_endpoint));
ep_reload = 0;
}
/* Allocate wildcard endpoint */
e = malloc(sizeof(struct mgcp_endpoint));
if (e) {
if (!ep_reload) {
memset(e, 0, sizeof(struct mgcp_endpoint));
ast_mutex_init(&e->lock);
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
strncpy(e->name, v->value, sizeof(e->name) - 1);
e->needaudit = 1;
}
@ -3545,6 +3551,8 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
if (sub) {
ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name);
memset(sub, 0, sizeof(struct mgcp_subchannel));
ast_mutex_init(&sub->lock);
ast_mutex_init(&sub->cx_queue_lock);
sub->parent = e;
sub->id = i;
snprintf(sub->txident, sizeof(sub->txident), "%08x", rand());
@ -3594,6 +3602,9 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
if (e) {
if (!ep_reload) {
memset(e, 0, sizeof(struct mgcp_endpoint));
ast_mutex_init(&e->lock);
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
strncpy(e->name, v->value, sizeof(e->name) - 1);
e->needaudit = 1;
}
@ -3633,8 +3644,6 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
/* ASSUME we're onhook */
e->hookstate = MGCP_ONHOOK;
snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand());
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
}
for (i = 0, sub = NULL; i < MAX_SUBS; i++) {
@ -3652,13 +3661,14 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
if (!ep_reload) {
ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name);
memset(sub, 0, sizeof(struct mgcp_subchannel));
ast_mutex_init(&sub->lock);
ast_mutex_init(&sub->cx_queue_lock);
strncpy(sub->magic, MGCP_SUBCHANNEL_MAGIC, sizeof(sub->magic) - 1);
sub->parent = e;
sub->id = i;
snprintf(sub->txident, sizeof(sub->txident), "%08x", rand());
sub->cxmode = MGCP_CX_INACTIVE;
sub->next = e->sub;
ast_mutex_init(&sub->cx_queue_lock);
e->sub = sub;
}
sub->nat = nat;
@ -3690,8 +3700,10 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
}
if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) {
ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name);
if (!gw_reload)
if (!gw_reload) {
ast_mutex_destroy(&gw->msgs_lock);
free(gw);
}
return NULL;
}
if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port))
@ -3803,8 +3815,13 @@ static void destroy_endpoint(struct mgcp_endpoint *e)
for (i = 0; (i < MAX_SUBS) && sub; i++) {
s = sub;
sub = sub->next;
ast_mutex_destroy(&s->lock);
ast_mutex_destroy(&s->cx_queue_lock);
free(s);
}
ast_mutex_destroy(&e->lock);
ast_mutex_destroy(&e->rqnt_queue_lock);
ast_mutex_destroy(&e->cmd_queue_lock);
free(e);
}
@ -4132,6 +4149,9 @@ int unload_module()
pl = p;
p = p->next;
/* Free associated memory */
ast_mutex_destroy(&pl->lock);
ast_mutex_destroy(&pl->rqnt_queue_lock);
ast_mutex_destroy(&pl->cmd_queue_lock);
free(pl);
}
iflist = NULL;

View File

@ -2042,11 +2042,11 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
struct sip_pvt *p;
p = malloc(sizeof(struct sip_pvt));
ast_mutex_init(&p->lock);
if (!p)
return NULL;
/* Keep track of stuff */
memset(p, 0, sizeof(struct sip_pvt));
ast_mutex_init(&p->lock);
p->initid = -1;
p->autokillid = -1;
p->stateid = -1;
@ -8326,6 +8326,7 @@ int unload_module()
pl = p;
p = p->next;
/* Free associated memory */
ast_mutex_destroy(&pl->lock);
free(pl);
}
iflist = NULL;
@ -8338,6 +8339,9 @@ int unload_module()
if (localaddr) {
ast_free_ha(localaddr);
}
ast_mutex_destroy(&userl.lock);
ast_mutex_destroy(&peerl.lock);
ast_mutex_destroy(&regl.lock);
return 0;
}

View File

@ -1104,6 +1104,7 @@ static struct skinny_device *build_device(char *cat, struct ast_variable *v)
l = malloc(sizeof(struct skinny_line));;
if (l) {
memset(l, 0, sizeof(struct skinny_line));
ast_mutex_init(&l->lock);
strncpy(l->name, v->value, sizeof(l->name) - 1);
/* XXX Should we check for uniqueness?? XXX */
@ -1145,6 +1146,7 @@ static struct skinny_device *build_device(char *cat, struct ast_variable *v)
if (sub) {
ast_verbose(VERBOSE_PREFIX_3 "Allocating Skinny subchannel '%d' on %s@%s\n", i, l->name, d->name);
memset(sub, 0, sizeof(struct skinny_subchannel));
ast_mutex_init(&sub->lock);
sub->parent = l;
/* Make a call*ID */
sub->callid = callnums;
@ -2262,6 +2264,7 @@ static void destroy_session(struct skinnysession *s)
sessions = cur->next;
if (s->fd > -1)
close(s->fd);
ast_mutex_destroy(&s->lock);
free(s);
} else
ast_log(LOG_WARNING, "Trying to delete non-existant session %p?\n", s);
@ -2662,10 +2665,12 @@ void delete_devices(void)
for (sub=l->sub;sub;) {
slast = sub;
sub = sub->next;
ast_mutex_destroy(&slast->lock);
free(slast);
}
llast = l;
l = l->next;
ast_mutex_destroy(&llast->lock);
free(llast);
}
dlast = d;
@ -2758,6 +2763,7 @@ int unload_module()
pl = p;
p = p->next;
/* Free associated memory */
ast_mutex_destroy(&pl->lock);
free(pl);
}
iflist = NULL;

View File

@ -279,8 +279,6 @@ static int vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
bridges[i].fo = fo;
bridges[i].c0 = c0;
bridges[i].c1 = c1;
ast_mutex_init(&bridges[i].lock);
pthread_cond_init(&bridges[i].cond, NULL);
}
} ast_mutex_unlock(&bridge_lock);
@ -356,8 +354,6 @@ static int vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
ast_mutex_lock(&bridge_lock); {
bridges[i].inuse = 0;
ast_mutex_destroy(&bridges[i].lock);
pthread_cond_destroy(&bridges[i].cond);
} ast_mutex_unlock(&bridge_lock);
p0->bridge = NULL;
@ -975,8 +971,13 @@ static void mkbrd(vpb_model_t model, int echo_cancel)
bridges = (vpb_bridge_t *)malloc(max_bridges * sizeof(vpb_bridge_t) );
if(!bridges)
ast_log(LOG_ERROR, "Failed to initialize bridges\n");
else
else {
memset(bridges,0,max_bridges * sizeof(vpb_bridge_t));
for(int i = 0; i < max_bridges; i++ ) {
ast_mutex_init(&bridges[i].lock);
pthread_cond_init(&bridges[i].cond, NULL);
}
}
}
if(!echo_cancel) {
if (model==vpb_model_v4pci) {
@ -1062,6 +1063,7 @@ struct vpb_pvt *mkif(int board, int channel, int mode, float txgain, float rxgai
tmp->vpb_model = vpb_model_v4pci;
}
ast_mutex_init(&tmp->owner_lock);
ast_mutex_init(&tmp->lock);
ast_mutex_init(&tmp->record_lock);
ast_mutex_init(&tmp->play_lock);
@ -2080,6 +2082,7 @@ int unload_module()
p = iflist;
ast_mutex_destroy(&p->lock);
pthread_cancel(p->readthread);
ast_mutex_destroy(&p->owner_lock);
ast_mutex_destroy(&p->record_lock);
ast_mutex_destroy(&p->play_lock);
ast_mutex_destroy(&p->play_dtmf_lock);
@ -2098,6 +2101,10 @@ int unload_module()
memset(bridges, 0, sizeof bridges);
} ast_mutex_unlock(&bridge_lock);
ast_mutex_destroy(&bridge_lock);
for(int i = 0; i < max_bridges; i++ ) {
ast_mutex_destroy(&bridges[i].lock);
pthread_cond_destroy(&bridges[i].cond, NULL);
}
free(bridges);
return 0;

View File

@ -1756,6 +1756,14 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
return 0;
}
static void destroy_zt_pvt(struct zt_pvt **pvt)
{
struct zt_pvt *p = *pvt;
ast_mutex_destroy(&p->lock);
free(p);
*pvt = NULL;
}
static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
{
int owned = 0;
@ -1788,7 +1796,7 @@ static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
if (cur->subs[SUB_REAL].zfd > -1) {
zt_close(cur->subs[SUB_REAL].zfd);
}
free(cur);
destroy_zt_pvt(&cur);
}
} else {
if (prev) {
@ -1807,7 +1815,7 @@ static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
if (cur->subs[SUB_REAL].zfd > -1) {
zt_close(cur->subs[SUB_REAL].zfd);
}
free(cur);
destroy_zt_pvt(&cur);
}
return 0;
}
@ -5751,10 +5759,11 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
tmp = (struct zt_pvt*)malloc(sizeof(struct zt_pvt));
if (!tmp) {
ast_log(LOG_ERROR, "MALLOC FAILED\n");
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
memset(tmp, 0, sizeof(struct zt_pvt));
ast_mutex_init(&tmp->lock);
ifcount++;
for (x=0;x<3;x++)
tmp->subs[x].zfd = -1;
@ -5811,20 +5820,19 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
/* Allocate a zapata structure */
if (tmp->subs[SUB_REAL].zfd < 0) {
ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
memset(&p, 0, sizeof(p));
res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
if (res < 0) {
ast_log(LOG_ERROR, "Unable to get parameters\n");
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (p.sigtype != (signalling & 0x3ffff)) {
ast_log(LOG_ERROR, "Signalling requested is %s but line is in %s signalling\n", sig2str(signalling), sig2str(p.sigtype));
free(tmp);
tmp = NULL;
destroy_zt_pvt(&tmp);
return tmp;
}
if (here) {
@ -5855,18 +5863,18 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
offset = 0;
if ((signalling == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (span >= NUM_SPANS) {
ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
} else {
si.spanno = 0;
if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
/* Store the logical span first based upon the real span */
@ -5874,7 +5882,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
if (span < 0) {
ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (signalling == SIG_PRI)
@ -5895,43 +5903,43 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
if (!matchesdchan) {
if (pris[span].nodetype && (pris[span].nodetype != pritype)) {
ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if ((pris[span].dialplan) && (pris[span].dialplan != dialplan)) {
ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, pri_plan2str(pris[span].dialplan));
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, idledial)) {
ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, idledial);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, idleext)) {
ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, idleext);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (pris[span].minunused && (pris[span].minunused != minunused)) {
ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, minunused);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (pris[span].minidle && (pris[span].minidle != minidle)) {
ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, minidle);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (pris[span].numchans >= MAX_CHANNELS) {
ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
pris[span].trunkgroup);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
pris[span].nodetype = pritype;
@ -5949,7 +5957,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
tmp->call = NULL;
} else {
ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
}
@ -5968,7 +5976,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
if (!tmp->r2) {
ast_log(LOG_WARNING, "Unable to create r2 call :(\n");
zt_close(tmp->subs[SUB_REAL].zfd);
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
} else {
@ -6021,7 +6029,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
if (res < 0) {
ast_log(LOG_ERROR, "Unable to set parameters\n");
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
}
@ -6081,7 +6089,6 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
tmp->propconfno = -1;
}
tmp->transfer = transfer;
ast_mutex_init(&tmp->lock);
strncpy(tmp->defcontext,context,sizeof(tmp->defcontext)-1);
strncpy(tmp->language, language, sizeof(tmp->language)-1);
strncpy(tmp->musicclass, musicclass, sizeof(tmp->musicclass)-1);
@ -6117,7 +6124,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio, struct zt_p
memset(&si, 0, sizeof(si));
if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
free(tmp);
destroy_zt_pvt(&tmp);
return NULL;
}
if (si.alarms) tmp->inalarm = 1;
@ -6222,11 +6229,12 @@ static struct zt_pvt *chandup(struct zt_pvt *src)
p = malloc(sizeof(struct zt_pvt));
if (p) {
memcpy(p, src, sizeof(struct zt_pvt));
ast_mutex_init(&p->lock);
p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
/* Allocate a zapata structure */
if (p->subs[SUB_REAL].zfd < 0) {
ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
free(p);
destroy_zt_pvt(&p);
return NULL;
}
res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
@ -8280,8 +8288,8 @@ static int __unload_module(void)
p = p->next;
x++;
/* Free associated memory */
if(p)
free(pl);
if(pl)
destroy_zt_pvt(&pl);
ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
}
iflist = NULL;
@ -8302,6 +8310,11 @@ static int __unload_module(void)
int unload_module()
{
#ifdef ZAPATA_PRI
int y;
for (y=0;y<NUM_SPANS;y++)
ast_mutex_destroy(&pris[y].lock);
#endif
return __unload_module();
}
@ -8922,6 +8935,7 @@ int load_module(void)
int y,i;
memset(pris, 0, sizeof(pris));
for (y=0;y<NUM_SPANS;y++) {
ast_mutex_init(&pris[y].lock);
pris[y].offset = -1;
pris[y].master = AST_PTHREADT_NULL;
for (i=0;i<NUM_DCHANS;i++)
@ -9028,9 +9042,13 @@ static int reload_zt(void)
#if 0
#ifdef ZAPATA_PRI
memset(pris, 0, sizeof(pris));
for (y=0;y<NUM_SPANS;y++)
ast_mutex_destroy(&pris[y]->lock);
memset(pris, 0, sizeof(pris));
for (y=0;y<NUM_SPANS;y++) {
ast_mutex_init(&pris[y]->lock);
pris[y].fd = -1;
}
#endif
#endif /* 0 */

View File

@ -6,3 +6,13 @@ You only need to do 'make opt'. Anything else you will be simply waisting time a
Also, you will notice they never tell you to 'make install' so don't do it.
On FreeBSD, the Makefiles are configured to
locate the compiled openh323 port, if it has
been built. Here is one way to build
openh323 and ptlib on such that the Makefiles
find it:
# cd /usr/ports/net/openh323
# make
It is not necessary to install the port. The
asterisk makefiles do not use any files
installed by the port.

View File

@ -19,8 +19,15 @@ endif
#
# This needs to be updated to deal with more than just little endian machines
#
CFLAGS += -march=$(shell uname -m) -DPBYTE_ORDER=PLITTLE_ENDIAN
OSARCH=$(shell uname -s)
ifneq (${OSARCH},FreeBSD)
CFLAGS += -march=$(shell uname -m)
endif
CFLAGS += -DPBYTE_ORDER=PLITTLE_ENDIAN
ifeq (${OSARCH},Linux)
LDLIBS+=-ldl
endif
#############################################
#
@ -38,16 +45,22 @@ CFLAGS += -march=$(shell uname -m) -DPBYTE_ORDER=PLITTLE_ENDIAN
# Pre Janus release directives
CFLAGS += -DNDEBUG -DDO_CRASH -DDEBUG_THREADS
CFLAGS += -pipe -Wall -fPIC -Wmissing-prototypes -Wmissing-declarations
CFLAGS += -pipe -Wall -fPIC
ifeq (${OSARCH},Linux)
CFLAGS += -DP_LINUX
LIBS+=-lpthread
endif
ifeq ($(findstring BSD,${OSARCH}),BSD)
CFLAGS += -pthread
endif
CFLAGS += -D_REENTRANT -D_GNU_SOURCE
CFLAGS += -DP_HAS_SEMAPHORES -DP_SSL -DP_PTHREADS
CFLAGS += -DPHAS_TEMPLATES -DPTRACING -DP_USE_PRAGMA
CFLAGS += -I../../include
CFLAGS += -I$(PWLIBDIR)/include/ptlib/unix -I$(PWLIBDIR)/include
CFLAGS += -I$(OPENH323DIR)/include -Wno-missing-prototypes -Wno-missing-declarations
CFLAGS += -I$(OPENH323DIR)/include
CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations
LIBS+= -lcrypto -lssl -lexpat
all: libchanh323.a
@ -59,19 +72,19 @@ samples:
ast_h323.o: ast_h323.cpp
g++ -g -c -fno-rtti -o $@ $(CFLAGS) $<
$(CXX) -g -c -fno-rtti -o $@ $(CFLAGS) $<
libchanh323.a: ast_h323.o
ar cr libchanh323.a ast_h323.o
chan_h323.so:
g++ -g -shared -Xlinker -x -o chan_h323.so chan_h323.o ast_h323.o -L$(PWLIBDIR)/lib -lpt_linux_x86_r -L$(OPENH323DIR)/lib -lh323_linux_x86_r -L/usr/lib -lpthread -ldl -lcrypto -lssl -lexpat
$(CXX) -g -shared -Xlinker -x -o chan_h323.so chan_h323.o ast_h323.o -L$(PWLIBDIR)/lib -lpt_linux_x86_r -L$(OPENH323DIR)/lib -lh323_linux_x86_r -L/usr/lib $(CHANH323LIB)
chan_h323_d.so: chan_h323.o ast_h323.o
g++ -shared -Xlinker -x -o chan_h323.so chan_h323.o ast_h323.o -L$(PWLIBDIR)/lib -lpt_linux_x86_d -L$(OPENH323DIR)/lib -lh323_linux_x86_d -L/usr/lib -lpthread -ldl -lcrypto -lssl -lexpat
$(CXX) -shared -Xlinker -x -o chan_h323.so chan_h323.o ast_h323.o -L$(PWLIBDIR)/lib -lpt_linux_x86_d -L$(OPENH323DIR)/lib -lh323_linux_x86_d -L/usr/lib $(CHANH323LIB)
chan_h323_s.so: chan_h323.o ast_h323.o
g++ -shared -Xlinker -x -o chan_h323.so chan_h323.o ast_h323.o -L$(PWLIBDIR)/lib -lpt_linux_x86_r_s -L$(OPENH323DIR)/lib -lh323_linux_x86_r_s -L/usr/lib -lpthread -ldl -lcrypto -lssl -lexpat
$(CXX) -shared -Xlinker -x -o chan_h323.so chan_h323.o ast_h323.o -L$(PWLIBDIR)/lib -lpt_linux_x86_r_s -L$(OPENH323DIR)/lib -lh323_linux_x86_r_s -L/usr/lib $(CHANH323LIB)
clean:
rm -f *.o *.so core.* libchanh323.a

10
cli.c
View File

@ -181,8 +181,8 @@ static char *format_uptimestr(time_t timeval)
char timestr[256];
int pos = 0;
#define SECOND (1)
#define MIN (SECOND*60)
#define HOUR (MIN*60)
#define MINUTE (SECOND*60)
#define HOUR (MINUTE*60)
#define DAY (HOUR*24)
#define WEEK (DAY*7)
#define YEAR (DAY*365)
@ -222,9 +222,9 @@ static char *format_uptimestr(time_t timeval)
else
pos += sprintf(timestr + pos, "1 hour, ");
}
if (timeval > MIN) {
mins = (timeval / MIN);
timeval -= (mins * MIN);
if (timeval > MINUTE) {
mins = (timeval / MINUTE);
timeval -= (mins * MINUTE);
if (mins > 1)
pos += sprintf(timestr + pos, "%d minutes, ", mins);
else if (mins > 0)

View File

@ -64,8 +64,8 @@ PG =
# CC = /usr/lang/acc
# CCFLAGS = -c -O
CC = gcc $(OPTIMIZE) -fomit-frame-pointer
CCFLAGS += -c -DNeedFunctionPrototypes=1 -funroll-loops -fPIC
CC ?= gcc
CCFLAGS += -c -DNeedFunctionPrototypes=1 -funroll-loops -fPIC $(OPTIMIZE) -fomit-frame-pointer
LD = $(CC)
@ -150,7 +150,7 @@ INC = $(ROOT)/inc
DEBUG = -DNDEBUG
######### Remove -DNDEBUG to enable assertions.
CFLAGS = $(PG) $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) \
CFLAGS += $(PG) $(CCFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) \
$(LTP_CUT) $(WAV49) $(K6OPT) $(CCINC) -I$(INC)
######### It's $(CC) $(CFLAGS)

View File

@ -3,7 +3,7 @@
#
# default C compiler
CC= gcc
CC?= gcc
#
# These definitions for CFLAGS and LIB_TARGET_DIR are used when one
@ -22,11 +22,12 @@ LIB_TARGET_DIR = .
#
WARNINGS = -Wall -Wno-comment -Wno-error
CFLAGS = $(OPTIMIZE) -I$(LIB_TARGET_DIR) $(WARNINGS) -fPIC
CFLAGS += $(OPTIMIZE) -I$(LIB_TARGET_DIR) $(WARNINGS) -fPIC
#CFLAGS+= $(shell if uname -m | grep -q 86; then echo "-mpentium" ; fi)
#fix for PPC processors and ALPHA too
ifneq ($(OSARCH),Darwin)
ifneq ($(findstring BSD,${OSARCH}),BSD)
ifneq ($(PROC),ppc)
ifneq ($(PROC),x86_64)
ifneq ($(PROC),alpha)
@ -35,6 +36,7 @@ endif
endif
endif
endif
endif
LIB = $(LIB_TARGET_DIR)/liblpc10.a

View File

@ -16,6 +16,8 @@
#include <pthread.h>
#include <netdb.h>
#include <time.h>
#include <sys/param.h>
#define AST_PTHREADT_NULL (pthread_t) -1
#define AST_PTHREADT_STOP (pthread_t) -2
@ -28,13 +30,23 @@
0x20 } }
#endif
#ifdef __FreeBSD__
#ifdef BSD
#ifdef __GNUC__
#define AST_MUTEX_INIT_W_CONSTRUCTORS
#else
#define AST_MUTEX_INIT_ON_FIRST_USE
#endif
#endif /* __FreeBSD__ */
#endif /* BSD */
/* From now on, Asterisk REQUIRES Recursive (not error checking) mutexes
and will not run without them. */
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
#else
#define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
#ifdef DEBUG_THREADS
@ -47,15 +59,7 @@
#include <stdio.h>
#include <unistd.h>
/* From now on, Asterisk REQUIRES Recursive (not error checking) mutexes
and will not run without them. */
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#define AST_MUTEX_INIT_VAULE { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
#else
#define AST_MUTEX_INIT_VAULE { PTHREAD_MUTEX_INITIALIZER, NULL, 0, NULL, 0 }
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
#define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, NULL, 0, NULL, 0 }
struct ast_mutex_info {
pthread_mutex_t mutex;
@ -67,28 +71,88 @@ struct ast_mutex_info {
typedef struct ast_mutex_info ast_mutex_t;
static inline int ast_pthread_mutex_init(ast_mutex_t *t, pthread_mutexattr_t *attr)
static inline int __ast_pthread_mutex_init_attr(char *filename, int lineno, char *func,
char* mutex_name, ast_mutex_t *t,
pthread_mutexattr_t *attr)
{
t->file = NULL;
t->lineno = 0;
t->func = 0;
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
if((t->mutex) != ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)) {
fprintf(stderr, "%s line %d (%s): Error: mutex '%s' is already initialized.\n",
filename, lineno, func, mutex_name);
fprintf(stderr, "%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
t->file, t->lineno, t->func, mutex_name);
#ifdef THREAD_CRASH
DO_THREAD_CRASH;
#endif
return 0;
}
#endif
t->file = filename;
t->lineno = lineno;
t->func = func;
t->thread = 0;
return pthread_mutex_init(&t->mutex, attr);
}
static inline int ast_mutex_init(ast_mutex_t *t)
static inline int __ast_pthread_mutex_init(char *filename, int lineno, char *func,
char* mutex_name, ast_mutex_t *t)
{
static pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
return ast_pthread_mutex_init(t, &attr);
return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
}
#define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
#define ast_pthread_mutex_init(pmutex,attr) __ast_pthread_mutex_init_attr(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex, attr)
static inline int __ast_pthread_mutex_destroy(char *filename, int lineno, char *func,
char* mutex_name, ast_mutex_t *t)
{
int res;
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
if((t->mutex) == ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)) {
fprintf(stderr, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
filename, lineno, func, mutex_name);
}
#endif
res = pthread_mutex_trylock(&t->mutex);
switch( res ) {
case 0:
pthread_mutex_unlock(&t->mutex);
break;
case EINVAL:
fprintf(stderr, "%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
filename, lineno, func, mutex_name);
break;
case EBUSY:
fprintf(stderr, "%s line %d (%s): Error: attemp to destroy locked mutex '%s'.\n",
filename, lineno, func, mutex_name);
fprintf(stderr, "%s line %d (%s): Error: '%s' was locked here.\n",
t->file, t->lineno, t->func, mutex_name);
break;
}
res = pthread_mutex_destroy(&t->mutex);
if (res)
fprintf(stderr, "%s line %d (%s): Error destroying mutex: %s\n",
filename, lineno, func, strerror(res));
#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
else
t->mutex = PTHREAD_MUTEX_INIT_VALUE;
#endif
t->file = filename;
t->lineno = lineno;
t->func = func;
return res;
}
#define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
/* if AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
constrictors/destructors to create/destroy mutexes. */
constrictors/destructors to create/destroy mutexes. */
#define __AST_MUTEX_DEFINE(scope,mutex) \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE; \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
static void __attribute__ ((constructor)) init_##mutex(void) \
{ \
ast_mutex_init(&mutex); \
@ -97,24 +161,54 @@ static void __attribute__ ((destructor)) fini_##mutex(void) \
{ \
ast_mutex_destroy(&mutex); \
}
#elif defined(AST_MUTEX_INIT_ON_FIRST_USE) || !defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
#elif defined(AST_MUTEX_INIT_ON_FIRST_USE)
/* if AST_MUTEX_INIT_ON_FIRST_USE is defined, mutexes are created on
first use. The performance impact on FreeBSD should be small since
the pthreads library does this itself to initialize errror checking
(defaulty type) mutexes. If nither is defined, the pthreads librariy
does the initialization itself on first use. */
#define __AST_MUTEX_DEFINE(scope,mutex) \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE
scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
#else /* AST_MUTEX_INIT_W_CONSTRUCTORS */
/* By default, use static initialization of mutexes.*/
#define __AST_MUTEX_DEFINE(scope,mutex) \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
static inline int __ast_pthread_mutex_lock(char *filename, int lineno, char *func, ast_mutex_t *t)
static inline int __ast_pthread_mutex_lock(char *filename, int lineno, char *func,
char* mutex_name, ast_mutex_t *t)
{
int res;
#ifdef AST_MUTEX_INIT_ON_FIRST_USE
if(*t->mutex == (ast_mutex_t)AST_MUTEX_KIND)
ast_mutex_init(t->mutex);
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE)
if((t->mutex) == ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)) {
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
fprintf(stderr, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
filename, lineno, func, mutex_name);
#endif
res = pthread_mutex_lock(&t->mutex);
ast_mutex_init(t);
}
#endif /* definded(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE) */
#ifdef DETECT_DEADLOCKS
{
time_t seconds seconds = time(NULL);
do {
res = pthread_mutex_trylock(&t->mutex);
if(res == EBUSY) {
if((time(NULL) - seconds) % 5) {
fprintf(stderr, "%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
filename, lineno, func, (time(NULL) - seconds), mutex_name);
fprintf(stderr, "%s line %d (%s): '%s' was locked here.\n",
t->file, t->lineno, t->func, mutex_name);
}
usleep(200);
}
} while (res == EBUSY);
}
#else
res = pthread_mutex_lock(&t->mutex);
#endif /* DETECT_DEADLOCKS */
if (!res) {
t->file = filename;
t->lineno = lineno;
@ -130,14 +224,21 @@ static inline int __ast_pthread_mutex_lock(char *filename, int lineno, char *fun
return res;
}
#define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
#define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
static inline int __ast_pthread_mutex_trylock(char *filename, int lineno, char *func, ast_mutex_t *t) {
static inline int __ast_pthread_mutex_trylock(char *filename, int lineno, char *func,
char* mutex_name, ast_mutex_t *t)
{
int res;
#ifdef AST_MUTEX_INIT_ON_FIRST_USE
if(*t->mutex == (ast_mutex_t)AST_MUTEX_KIND)
ast_mutex_init(t->mutex);
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE)
if((t->mutex) == ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)) {
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
fprintf(stderr, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
filename, lineno, func, mutex_name);
#endif
ast_mutex_init(t);
}
#endif /* definded(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE) */
res = pthread_mutex_trylock(&t->mutex);
if (!res) {
t->file = filename;
@ -148,10 +249,17 @@ static inline int __ast_pthread_mutex_trylock(char *filename, int lineno, char *
return res;
}
#define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
#define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
static inline int __ast_pthread_mutex_unlock(char *filename, int lineno, char *func, ast_mutex_t *t) {
static inline int __ast_pthread_mutex_unlock(char *filename, int lineno, char *func,
char* mutex_name, ast_mutex_t *t) {
int res;
#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
if((t->mutex) == ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)) {
fprintf(stderr, "%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
filename, lineno, func, mutex_name);
}
#endif
/* Assumes lock is actually held */
t->file = NULL;
t->lineno = 0;
@ -168,23 +276,7 @@ static inline int __ast_pthread_mutex_unlock(char *filename, int lineno, char *f
return res;
}
#define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
static inline int __ast_pthread_mutex_destroy(char *filename, int lineno, char *func, ast_mutex_t *t)
{
int res;
t->file = NULL;
t->lineno = 0;
t->func = NULL;
t->thread = 0;
res = pthread_mutex_destroy(&t->mutex);
if (res)
fprintf(stderr, "%s line %d (%s): Error destroying mutex: %s\n",
filename, lineno, func, strerror(res));
return res;
}
#define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
#define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
#define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
#define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
@ -195,15 +287,9 @@ static inline int __ast_pthread_mutex_destroy(char *filename, int lineno, char *
#else /* DEBUG_THREADS */
/* From now on, Asterisk REQUIRES Recursive (not error checking) mutexes
and will not run without them. */
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#define AST_MUTEX_INIT_VAULE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
#else
#define AST_MUTEX_INIT_VAULE PTHREAD_MUTEX_INITIALIZER
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
#define AST_MUTEX_INIT_VALUE PTHREAD_MUTEX_INIT_VALUE
typedef pthread_mutex_t ast_mutex_t;
@ -222,7 +308,7 @@ static inline int ast_mutex_init(ast_mutex_t *pmutex)
/* if AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope
constrictors/destructors to create/destroy mutexes. */
#define __AST_MUTEX_DEFINE(scope,mutex) \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE; \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
static void __attribute__ ((constructor)) init_##mutex(void) \
{ \
ast_mutex_init(&mutex); \
@ -241,7 +327,7 @@ static void __attribute__ ((destructor)) fini_##mutex(void) \
the pthreads library does this itself to initialize errror checking
(defaulty type) mutexes.*/
#define __AST_MUTEX_DEFINE(scope,mutex) \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE
scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
static inline int ast_mutex_lock(ast_mutex_t *pmutex)
{
@ -258,7 +344,7 @@ static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
#else
/* By default, use static initialization of mutexes.*/
#define __AST_MUTEX_DEFINE(scope,mutex) \
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE
scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
#define ast_mutex_lock(pmutex) pthread_mutex_lock(pmutex)
#define ast_mutex_trylock(pmutex) pthread_mutex_trylock(pmutex)
#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
@ -270,6 +356,7 @@ static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
#define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
#define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
#endif

View File

@ -26,4 +26,6 @@ struct ast_hostent {
extern struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
extern int test_for_thread_safety(void);
#endif

View File

@ -5,7 +5,7 @@
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License

View File

@ -220,6 +220,7 @@ static void destroy_session(struct mansession *s)
sessions = cur->next;
if (s->fd > -1)
close(s->fd);
ast_mutex_destroy(&s->lock);
free(s);
} else
ast_log(LOG_WARNING, "Trying to delete non-existant session %p?\n", s);

1
pbx.c
View File

@ -4173,6 +4173,7 @@ void __ast_context_destroy(struct ast_context *con, char *registrar)
e = e->next;
destroy_exten(el);
}
ast_mutex_destroy(&tmp->lock);
free(tmp);
if (!con) {
/* Might need to get another one -- restart */

View File

@ -22,6 +22,7 @@
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <asterisk/sched.h>
#include <asterisk/logger.h>
@ -63,6 +64,7 @@ struct sched_context *sched_context_create(void)
struct sched_context *tmp;
tmp = malloc(sizeof(struct sched_context));
if (tmp) {
memset(tmp, 0, sizeof(struct sched_context));
ast_mutex_init(&tmp->lock);
tmp->eventcnt = 1;
tmp->schedcnt = 0;
@ -97,6 +99,7 @@ void sched_context_destroy(struct sched_context *con)
}
/* And the context */
ast_mutex_unlock(&con->lock);
ast_mutex_destroy(&con->lock);
free(con);
}

65
utils.c
View File

@ -11,6 +11,8 @@
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/utils.h>
@ -22,9 +24,9 @@
AST_MUTEX_DEFINE_STATIC(__mutex);
int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result,
int *h_errnop)
static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result,
int *h_errnop)
{
int hsave;
struct hostent *ph;
@ -143,3 +145,60 @@ struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
return NULL;
return &hp->hp;
}
/* This is a regression test for recursive mutexes.
test_for_thread_safety() will return 0 if recursive mutex locks are
working properly, and non-zero if they are not working properly. */
AST_MUTEX_DEFINE_STATIC(test_lock);
AST_MUTEX_DEFINE_STATIC(test_lock2);
static pthread_t test_thread;
static int lock_count = 0;
static int test_errors = 0;
static void *test_thread_body(void *data)
{
ast_mutex_lock(&test_lock);
lock_count += 10;
if(lock_count != 10) test_errors++;
ast_mutex_lock(&test_lock);
lock_count += 10;
if(lock_count != 20) test_errors++;
ast_mutex_lock(&test_lock2);
ast_mutex_unlock(&test_lock);
lock_count -= 10;
if(lock_count != 10) test_errors++;
ast_mutex_unlock(&test_lock);
lock_count -= 10;
ast_mutex_unlock(&test_lock2);
if(lock_count != 0) test_errors++;
return NULL;
}
int test_for_thread_safety(void)
{
ast_mutex_lock(&test_lock2);
ast_mutex_lock(&test_lock);
lock_count += 1;
ast_mutex_lock(&test_lock);
lock_count += 1;
pthread_create(&test_thread, NULL, test_thread_body, NULL);
pthread_yield();
usleep(100);
if(lock_count != 2) test_errors++;
ast_mutex_unlock(&test_lock);
lock_count -= 1;
pthread_yield();
usleep(100);
if(lock_count != 1) test_errors++;
ast_mutex_unlock(&test_lock);
lock_count -= 1;
if(lock_count != 0) test_errors++;
ast_mutex_unlock(&test_lock2);
pthread_yield();
usleep(100);
if(lock_count != 0) test_errors++;
pthread_join(test_thread, NULL);
return(test_errors); /* return 0 on success. */
}