[Freeswitch-svn] [commit] r5147 - freeswitch/trunk/libs/iax/src

Freeswitch SVN anthm at freeswitch.org
Fri May 11 11:01:24 EDT 2007


Author: anthm
Date: Fri May 11 11:01:23 2007
New Revision: 5147

Modified:
   freeswitch/trunk/libs/iax/src/iax.c

Log:
fix liax

Modified: freeswitch/trunk/libs/iax/src/iax.c
==============================================================================
--- freeswitch/trunk/libs/iax/src/iax.c	(original)
+++ freeswitch/trunk/libs/iax/src/iax.c	Fri May 11 11:01:23 2007
@@ -40,16 +40,12 @@
 
 #else
 
+#define _BSD_SOURCE 1
 #include <netdb.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/time.h>
 #include <stdlib.h>
-#ifdef __GNUC__
-#ifndef __USE_SVID
-#define __USE_SVID
-#endif
-#endif
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -60,7 +56,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <time.h>
-
+       
 #endif
 
 #include "iax2.h"
@@ -70,7 +66,7 @@
 #ifdef NEWJB
 #include "jitterbuf.h"
 #endif
-
+#include "iax-mutex.h"
 /*
 	work around jitter-buffer shrinking in asterisk:
 	channels/chan_iax2.c:schedule_delivery() shrinks jitter buffer by 2.
@@ -330,6 +326,8 @@
 	struct iax_sched *next;
 };
 
+static mutex_t *sched_mutex = NULL;
+static mutex_t *session_mutex = NULL;
 static struct iax_sched *schedq = NULL;
 static struct iax_session *sessions = NULL;
 static int callnums = 1;
@@ -412,6 +410,7 @@
 		sched->func = func;
 		sched->arg = arg;
 		/* Put it in the list, in order */
+		iax_mutex_lock(sched_mutex);
 		cur = schedq;
 		while(cur && cur->when <= sched->when) {
 			prev = cur;
@@ -423,6 +422,7 @@
 		} else {
 			schedq = sched;
 		}
+		iax_mutex_unlock(sched_mutex);
 		return 0;
 	} else {
 		DEBU(G "Out of memory!\n");
@@ -433,7 +433,9 @@
 static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all)
 {
 	struct iax_sched *cur, *tmp, *prev = NULL;
+	int ret = 0;
 
+	iax_mutex_lock(sched_mutex);
 	cur = schedq;
 	while (cur) {
 		if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) {
@@ -444,13 +446,18 @@
 			tmp = cur;
 			cur = cur->next;	
 			free(tmp);
-			if (!all)
-				return -1;
+			if (!all) {
+				ret = -1;
+				goto done;
+			}
 		} else {
 			prev = cur;
 			cur = cur->next;
 		}
 	}
+ done:
+	iax_mutex_unlock(sched_mutex);
+
 	return 0;
 
 }
@@ -458,24 +465,31 @@
 
 time_in_ms_t iax_time_to_next_event(void)
 {
-	struct iax_sched *cur = schedq;
+	struct iax_sched *cur = NULL;
 	time_in_ms_t minimum = 999999999;
 	
+	iax_mutex_lock(sched_mutex);
+	cur = schedq;
+
 	/* If there are no pending events, we don't need to timeout */
-	if (!cur)
+	if (!cur) {
+		iax_mutex_unlock(sched_mutex);
 		return -1;
-
+	}
 	while(cur) {
 		if (cur->when < minimum) {
 			minimum = cur->when;
 		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(sched_mutex);
 
 	if (minimum <= 0) {
 		return -1;
 	}
 
+
+
 	return minimum - current_time_in_ms();
 }
 
@@ -497,7 +511,7 @@
 			callnums = 1;
 		s->peercallno = 0;
 		s->transferpeer = 0;		/* for attended transfer */
-		s->next = sessions;
+
 		s->sendto = iax_sendto;
 		s->pingid = -1;
 #ifdef NEWJB
@@ -510,7 +524,10 @@
 			jb_setconf(s->jb, &jbconf);
 		}
 #endif
+		iax_mutex_lock(session_mutex);
+		s->next = sessions;
 		sessions = s;
+		iax_mutex_unlock(session_mutex);
 	}
 	return s;
 }
@@ -518,12 +535,19 @@
 static int iax_session_valid(struct iax_session *session)
 {
 	/* Return -1 on a valid iax session pointer, 0 on a failure */
-	struct iax_session *cur = sessions;
+	struct iax_session *cur;
+
+	iax_mutex_lock(session_mutex);
+	cur = sessions;
 	while(cur) {
-		if (session == cur)
+		if (session == cur) {
+			iax_mutex_unlock(session_mutex);
 			return -1;
+		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(session_mutex);
+
 	return 0;
 }
 
@@ -865,26 +889,29 @@
 
 int __iax_shutdown(void)
 {
+	struct iax_sched *sp, *fp;
+
 	/* Hangup Calls */
 	if (sessions) {
 		struct iax_session *sp = NULL, *fp = NULL;
+		iax_mutex_lock(session_mutex); 
 		for(sp = sessions; sp ;) {
 			iax_hangup(sp, "System Shutdown");
 			fp = sp;
 			sp = sp->next;
 			destroy_session(fp);
 		}
+		iax_mutex_unlock(session_mutex); 
 	}
 
 	/* Clear Scheduler */
-	if(schedq) {
-		struct iax_sched *sp, *fp;
-		for(sp = schedq; sp ;) {
-			fp = sp;
-			sp = sp->next;
-			free(fp);
-		}
+	iax_mutex_lock(sched_mutex);
+	for(sp = schedq; sp ;) {
+		fp = sp;
+		sp = sp->next;
+		free(fp);
 	}
+	iax_mutex_unlock(sched_mutex);
 	
 	if (netfd > -1) {
 		shutdown(netfd, 2);
@@ -893,6 +920,9 @@
 
 	time_end();
 
+	iax_mutex_destroy(sched_mutex);
+	iax_mutex_destroy(session_mutex);
+
 	return 0;
 }
 
@@ -910,6 +940,9 @@
 
 	init_time();
 
+	iax_mutex_create(&sched_mutex);
+	iax_mutex_create(&session_mutex);
+
 	if(iax_recvfrom == (recvfrom_t) recvfrom) {
 	    if (netfd > -1) {
 		    /* Sokay, just don't do anything */
@@ -1229,12 +1262,14 @@
 {
 	struct iax_sched *sch;
 
+	iax_mutex_lock(sched_mutex);
 	sch = schedq;
 	while(sch) {
 		if (sch->frame && (sch->frame->session == session))
 					sch->frame->retries = -1;
 		sch = sch->next;
 	}
+	iax_mutex_unlock(sched_mutex);
 }	/* stop_transfer */
 
 static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq)
@@ -1356,14 +1391,18 @@
 
 static struct iax_session *iax_find_session2(short callno)
 {
-	struct iax_session *cur = sessions;
+	struct iax_session *cur;
 
+	iax_mutex_lock(session_mutex); 
+	cur = sessions;
 	while(cur) {
 		if (callno == cur->callno && callno != 0)  {
+			iax_mutex_unlock(session_mutex); 
 			return cur;
 		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(session_mutex); 
 
 	return NULL;
 }
@@ -1431,6 +1470,8 @@
 	struct iax_session *cur, *prev=NULL;
 	struct iax_sched *curs, *prevs=NULL, *nexts=NULL;
 	int    loop_cnt=0;
+
+	iax_mutex_lock(sched_mutex);
 	curs = schedq;
 	while(curs) {
 		nexts = curs->next;
@@ -1451,7 +1492,9 @@
 		curs = nexts;
 		loop_cnt++;
 	}
-		
+	iax_mutex_unlock(sched_mutex);
+	
+
 	cur = sessions;
 	while(cur) {
 		if (cur == session) {
@@ -2081,9 +2124,13 @@
 											short dcallno,
 											int makenew)
 {
-	struct iax_session *cur = sessions;
+	struct iax_session *cur;
+
+	iax_mutex_lock(session_mutex); 
+	cur = sessions;
 	while(cur) {
 		if (forward_match(sin, callno, dcallno, cur)) {
+			iax_mutex_unlock(session_mutex); 
 			return cur;
 		}
 		cur = cur->next;
@@ -2092,11 +2139,14 @@
 	cur = sessions;
 	while(cur) {
 		if (reverse_match(sin, callno, cur)) {
+			iax_mutex_unlock(session_mutex); 
 			return cur;
 		}
 		cur = cur->next;
 	}
 
+	iax_mutex_unlock(session_mutex); 
+
 	if (makenew && !dcallno) {
 		cur = iax_session_new();
 		cur->peercallno = callno;
@@ -2108,6 +2158,7 @@
 	} else {
 		DEBU(G "No session, peer = %d, us = %d\n", callno, dcallno);
 	}
+
 	return cur;	
 }
 
@@ -2428,6 +2479,7 @@
 				for (x=session->rseqno; x != fh->iseqno; x++) {
 					/* Ack the packet with the given timestamp */
 					DEBU(G "Cancelling transmission of packet %d\n", x);
+					iax_mutex_lock(sched_mutex);
 					sch = schedq;
 					while(sch) {
 						if (sch->frame && (sch->frame->session == session) && 
@@ -2435,6 +2487,7 @@
 							sch->frame->retries = -1;
 						sch = sch->next;
 					}
+					iax_mutex_unlock(sched_mutex);
 				}
 				/* Note how much we've received acknowledgement for */
 				session->rseqno = fh->iseqno;
@@ -2846,15 +2899,17 @@
 
 void iax_destroy(struct iax_session *session)
 {
+	iax_mutex_lock(session_mutex); 
 	destroy_session(session);
+	iax_mutex_unlock(session_mutex); 
 }
 
 static struct iax_event *iax_net_read(void)
 {
 	unsigned char buf[65536];
-	int res;
+	int res, sinlen;
 	struct sockaddr_in sin;
-	unsigned int sinlen;
+
 	sinlen = sizeof(sin);
 	res = iax_recvfrom(netfd, buf, sizeof(buf), 0, (struct sockaddr *) &sin, &sinlen);
 
@@ -2894,6 +2949,7 @@
 	if (!ies.transferid) {
 		return NULL;	/* TXCNT without proper IAX_IE_TRANSFERID */
 	}
+	iax_mutex_lock(session_mutex); 
 	for( cur=sessions; cur; cur=cur->next ) {
 		if ((cur->transferring) && (cur->transferid == ies.transferid) &&
 		   	(cur->callno == dcallno) && (cur->transfercallno == callno)) {
@@ -2906,6 +2962,7 @@
 			break;		
 		}
 	}
+	iax_mutex_unlock(session_mutex); 
 	return cur;
 }
 
@@ -2958,6 +3015,7 @@
 static struct iax_sched *iax_get_sched(time_in_ms_t time_in_ms)
 {
 	struct iax_sched *cur, *prev=NULL;
+	iax_mutex_lock(sched_mutex);
 	cur = schedq;
 	/* Check the event schedule first. */
 	while(cur) {
@@ -2968,10 +3026,12 @@
 			} else {
 				schedq = cur->next;
 			}
+			iax_mutex_unlock(sched_mutex);
 			return cur;
 		}
 		cur = cur->next;
 	}
+	iax_mutex_unlock(sched_mutex);
 	return NULL;
 }
 
@@ -3005,8 +3065,11 @@
 			if (frame->retries < 0) {
 				/* It's been acked.  No need to send it.   Destroy the old
 				   frame. If final, destroy the session. */
-				if (frame->final)
+				if (frame->final) {
+					iax_mutex_lock(session_mutex); 
 					destroy_session(frame->session);
+					iax_mutex_unlock(session_mutex); 
+				}
 				if (frame->data)
 					free(frame->data);
 				free(frame);
@@ -3023,7 +3086,9 @@
 					/* We haven't been able to get an ACK on this packet. If a 
 					   final frame, destroy the session, otherwise, pass up timeout */
 					if (frame->final) {
+						iax_mutex_lock(session_mutex); 
 						destroy_session(frame->session);
+						iax_mutex_unlock(session_mutex); 
 						if (frame->data)
 							free(frame->data);
 						free(frame);
@@ -3070,54 +3135,59 @@
 	{
 	    struct iax_session *cur;
 	    jb_frame frame;
+		iax_mutex_lock(session_mutex); 
 	    for(cur=sessions; cur; cur=cur->next) {
-		int ret;
-		time_in_ms_t now;
-		time_in_ms_t next;
-
-		now = time_in_ms - cur->rxcore;
-		if(now > (next = jb_next(cur->jb))) {
-		    /* FIXME don't hardcode interpolation frame length in jb_get */
-		    ret = jb_get(cur->jb,&frame,now,20);
-		    switch(ret) {
-			case JB_OK:
-//			    if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
-			    event = frame.data;
-			    event = handle_event(event);
-			    if (event) {
-				    return event;
-			    }
-			break;
-			case JB_INTERP:
-//			    if(next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
-			    /* create an interpolation frame */
-			    //fprintf(stderr, "Making Interpolation frame\n");
-			    event = (struct iax_event *)malloc(sizeof(struct iax_event));
-			    if (event) {
-				    event->etype    = IAX_EVENT_VOICE;
-				    event->subclass = cur->voiceformat;
-				    event->ts	    = now; /* XXX: ??? applications probably ignore this anyway */
-				    event->session  = cur;
-				    event->datalen  = 0;
-				    event = handle_event(event);
-				    if(event)
-					return event;
-			    }
-			break;
-			case JB_DROP:
-//			    if(next != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(cur->jb), next);
-			    iax_event_free(frame.data);
-			break;
-			case JB_NOFRAME:
-			case JB_EMPTY:
-			    /* do nothing */
-			break;
-			default:
-			    /* shouldn't happen */
-			break;
-		    }
-		}
+			int ret;
+			time_in_ms_t now;
+			time_in_ms_t next;
+
+			now = time_in_ms - cur->rxcore;
+			if(now > (next = jb_next(cur->jb))) {
+				/* FIXME don't hardcode interpolation frame length in jb_get */
+				ret = jb_get(cur->jb,&frame,now,20);
+				switch(ret) {
+				case JB_OK:
+					//			    if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
+					event = frame.data;
+					event = handle_event(event);
+					if (event) {
+						iax_mutex_unlock(session_mutex);
+						return event;
+					}
+					break;
+				case JB_INTERP:
+					//			    if(next + 20 != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(cur->jb), next);
+					/* create an interpolation frame */
+					//fprintf(stderr, "Making Interpolation frame\n");
+					event = (struct iax_event *)malloc(sizeof(struct iax_event));
+					if (event) {
+						event->etype    = IAX_EVENT_VOICE;
+						event->subclass = cur->voiceformat;
+						event->ts	    = now; /* XXX: ??? applications probably ignore this anyway */
+						event->session  = cur;
+						event->datalen  = 0;
+						event = handle_event(event);
+						if(event) {
+							iax_mutex_unlock(session_mutex);
+							return event;
+						}
+					}
+					break;
+				case JB_DROP:
+					//			    if(next != jb_next(cur->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(cur->jb), next);
+					iax_event_free(frame.data);
+					break;
+				case JB_NOFRAME:
+				case JB_EMPTY:
+					/* do nothing */
+					break;
+				default:
+					/* shouldn't happen */
+					break;
+				}
+			}
 	    }
+		iax_mutex_unlock(session_mutex);
 	}
 
 #endif
@@ -3169,8 +3239,10 @@
 
 void iax_session_destroy(struct iax_session **session) 
 {
+	iax_mutex_lock(session_mutex); 
 	destroy_session(*session);
 	*session = NULL;
+	iax_mutex_unlock(session_mutex); 
 }
 
 void iax_event_free(struct iax_event *event)
@@ -3185,7 +3257,9 @@
 	case IAX_EVENT_HANGUP:
 		/* Destroy this session -- it's no longer valid */
 		if (event->session) { /* maybe the user did it already */
+			iax_mutex_lock(session_mutex); 
 			destroy_session(event->session);
+			iax_mutex_unlock(session_mutex); 
 		}
 		break;
 	}



More information about the Freeswitch-svn mailing list