[svn-commits] rmudgett: branch 1.6.2 r206765 - in /branches/1.6.2: ./ channels/misdn/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jul 15 16:50:49 CDT 2009


Author: rmudgett
Date: Wed Jul 15 16:50:46 2009
New Revision: 206765

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=206765
Log:
Merged revisions 206707 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r206707 | rmudgett | 2009-07-15 16:14:41 -0500 (Wed, 15 Jul 2009) | 33 lines
  
  Merged revisions 206706 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ................
    r206706 | rmudgett | 2009-07-15 15:44:55 -0500 (Wed, 15 Jul 2009) | 26 lines
    
    Merged revision 206700 from
    https://origsvn.digium.com/svn/asterisk/be/branches/C.2-...
    
    ..........
      Fixed chan_misdn crash because mISDNuser library is not thread safe.
    
      With Asterisk the mISDNuser library is driven by two threads concurrently:
      1. channels/misdn/isdn_lib.c::manager_event_handler()
      2. channels/misdn/isdn_lib.c::misdn_lib_isdn_event_catcher()
    
      Calls into the library are done concurrently and recursively from
      isdn_lib.c.
    
      Both threads can fiddle with the master/child layer3_proc_t lists.  One
      thread may traverse the list when the other interrupts it and then removes
      the list element which the first thread was currently handling.  This is
      exactly what caused the crash.  About 60 calls were needed to a Gigaset
      CX475 before it occurred once.
    
      This patch adds locking when calling into the mISDNuser library.
      This also fixes some cb_log calls with wrong port parameter.
    
      JIRA ABE-1913
          Patches: misdn-locking.patch (Modified with mostly cosmetic changes)
    ..........
  ................
................

Modified:
    branches/1.6.2/   (props changed)
    branches/1.6.2/channels/misdn/isdn_lib.c
    branches/1.6.2/channels/misdn/isdn_lib_intern.h

Propchange: branches/1.6.2/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.2/channels/misdn/isdn_lib.c
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.6.2/channels/misdn/isdn_lib.c?view=diff&rev=206765&r1=206764&r2=206765
==============================================================================
--- branches/1.6.2/channels/misdn/isdn_lib.c (original)
+++ branches/1.6.2/channels/misdn/isdn_lib.c Wed Jul 15 16:50:46 2009
@@ -819,9 +819,10 @@
 		/* L2 */
 		dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
 		
+		pthread_mutex_lock(&stack->nstlock);
 		if (stack->nst.manager_l3(&stack->nst, dmsg))
 			free_msg(dmsg);
-		
+		pthread_mutex_unlock(&stack->nstlock);
 	} else {
 		iframe_t act;
 		
@@ -860,9 +861,10 @@
 		/* L2 */
 		dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
 		
+		pthread_mutex_lock(&stack->nstlock);
 		if (stack->nst.manager_l3(&stack->nst, dmsg))
 			free_msg(dmsg);
-		
+		pthread_mutex_unlock(&stack->nstlock);
 	} else {
 		iframe_t act;
 		
@@ -1369,6 +1371,7 @@
 			stack->nst.l2_id = stack->upper_id;
 			
 			msg_queue_init(&stack->nst.down_queue);
+			pthread_mutex_init(&stack->nstlock, NULL);
 			
 			Isdnl2Init(&stack->nst);
 			Isdnl3Init(&stack->nst);
@@ -1410,6 +1413,7 @@
 	if (!stack) return;
 
 	if (stack->nt) {
+		pthread_mutex_destroy(&stack->nstlock);
 		cleanup_Isdnl2(&stack->nst);
 		cleanup_Isdnl3(&stack->nst);
 	}
@@ -1846,17 +1850,22 @@
 	manager_t *mgr = (manager_t *)dat;
 	msg_t *msg = (msg_t *)arg;
 	mISDNuser_head_t *hh;
+	struct misdn_stack *stack;
 	int reject=0;
-
-	struct misdn_stack *stack=find_stack_by_mgr(mgr);
-	int port;
 
 	if (!msg || !mgr)
 		return(-EINVAL);
 
+	stack = find_stack_by_mgr(mgr);
 	hh=(mISDNuser_head_t*)msg->data;
-	port=stack->port;
-	
+
+	/*
+	 * When we are called from the mISDNuser lib, the nstlock is held and it
+	 * must be held when we return.  We unlock here because the lib may be
+	 * entered again recursively.
+	 */
+	pthread_mutex_unlock(&stack->nstlock);
+
 	cb_log(5, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
 	{
 		switch(hh->prim){
@@ -1876,6 +1885,7 @@
 				msg_t *dmsg;
 				cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
 				dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
+				pthread_mutex_lock(&stack->nstlock);
 				stack->nst.manager_l3(&stack->nst, dmsg);
 				free_msg(msg);
 				return 0;
@@ -1907,12 +1917,16 @@
 			int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
 			cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID  is %x\n",l3id );
 	
-			if (!bc) { cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n"); return 0; }
-			cb_log (2,bc->port,"I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
-			bc->l3_id=l3id;
-			cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
+			if (bc) {
+				cb_log (2, bc->port, "I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
+				bc->l3_id = l3id;
+				cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
+			} else {
+				cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n");
+			}
 		}
 		free_msg(msg);
+		pthread_mutex_lock(&stack->nstlock);
 		return 0;
       
 		case CC_SETUP|INDICATION:
@@ -1924,6 +1938,7 @@
 				msg_t *dmsg;
 				cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
 				dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
+				pthread_mutex_lock(&stack->nstlock);
 				stack->nst.manager_l3(&stack->nst, dmsg);
 				free_msg(msg);
 				return 0;
@@ -1980,6 +1995,7 @@
 			msg_t *dmsg;
 			cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
 			dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
+			pthread_mutex_lock(&stack->nstlock);
 			stack->nst.manager_l3(&stack->nst, dmsg);
 			free_msg(msg);
 			return 0;
@@ -2005,6 +2021,7 @@
 		case CC_RELEASE_CR|INDICATION:
 			release_cr(stack, hh);
 			free_msg(msg);
+			pthread_mutex_lock(&stack->nstlock);
 			return 0 ;
 		break;
       
@@ -2014,7 +2031,11 @@
 		{
 			struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
 			int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
-			if (!bc) { cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n"); return -1;};
+			if (!bc) {
+				cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n");
+				pthread_mutex_lock(&stack->nstlock);
+				return -1;
+			}
 			if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
 				cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
 				stack->procids[bc->l3_id&0xff] = 0 ;
@@ -2025,6 +2046,7 @@
 			cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
 	
 			free_msg(msg);
+			pthread_mutex_lock(&stack->nstlock);
 			return 0;
 		}
       
@@ -2051,6 +2073,7 @@
 			stack->l2upcnt=0;
 			
 			free_msg(msg);
+			pthread_mutex_lock(&stack->nstlock);
 			return 0;
 		}
 		break;
@@ -2079,6 +2102,7 @@
 			
 			stack->l2link = 0;
 			free_msg(msg);
+			pthread_mutex_lock(&stack->nstlock);
 			return 0;
 		}
 		break;
@@ -2152,6 +2176,7 @@
 	}
 
 
+	pthread_mutex_lock(&stack->nstlock);
 	return 0;
 }
 
@@ -2194,7 +2219,9 @@
 				ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
 							MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
 				test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
+				pthread_mutex_lock(&stack->nstlock);
 				ret = it->function(it->data);
+				pthread_mutex_unlock(&stack->nstlock);
 				free_msg(msg);
 				return 1;
 			}
@@ -2610,8 +2637,9 @@
 	}
 
 	
+	pthread_mutex_lock(&stack->nstlock);
 	if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
-    
+		pthread_mutex_unlock(&stack->nstlock);
 		if (nt_err_cnt > 0 ) {
 			if (nt_err_cnt < 100) {
 				nt_err_cnt++; 
@@ -2623,9 +2651,8 @@
 		}
 		free_msg(msg);
 		return 1;
-		
-	}
-	
+	}
+	pthread_mutex_unlock(&stack->nstlock);
 	return 1;
 }
 
@@ -2803,8 +2830,10 @@
 		
 		if (stack->nt) {
 			
+			pthread_mutex_lock(&stack->nstlock);
 			if (stack->nst.l1_l2(&stack->nst, msg))
 				free_msg(msg);
+			pthread_mutex_unlock(&stack->nstlock);
 
 			if (stack->ptp)
 				misdn_lib_get_l2_up(stack);
@@ -2845,8 +2874,10 @@
 #endif
 		
 		if (stack->nt) {
+			pthread_mutex_lock(&stack->nstlock);
 			if (stack->nst.l1_l2(&stack->nst, msg))
 				free_msg(msg);
+			pthread_mutex_unlock(&stack->nstlock);
 		} else {
 			free_msg(msg);
 		}
@@ -2935,16 +2966,16 @@
 	switch(frm->prim) {
 	case MGR_SHORTSTATUS | INDICATION:
 	case MGR_SHORTSTATUS | CONFIRM:
-		cb_log(5, 0, "MGMT: Short status dinfo %x\n",frm->dinfo);
+		cb_log(5, stack->port, "MGMT: Short status dinfo %x\n",frm->dinfo);
 		
 		switch (frm->dinfo) {
 		case SSTATUS_L1_ACTIVATED:
-			cb_log(3, 0, "MGMT: SSTATUS: L1_ACTIVATED \n");
+			cb_log(3, stack->port, "MGMT: SSTATUS: L1_ACTIVATED \n");
 			stack->l1link=1;
 		
 			break;
 		case SSTATUS_L1_DEACTIVATED:
-			cb_log(3, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
+			cb_log(3, stack->port, "MGMT: SSTATUS: L1_DEACTIVATED \n");
 			stack->l1link=0;
 #if 0
 			clear_l3(stack);
@@ -3969,9 +4000,10 @@
 		     
 			while ( (msg=msg_dequeue(&stack->downqueue)) ) {
 				if (stack->nt ) {
+					pthread_mutex_lock(&stack->nstlock);
 					if (stack->nst.manager_l3(&stack->nst, msg))
 						cb_log(0, stack->port, "Error@ Sending Message in NT-Stack.\n");
-	  
+					pthread_mutex_unlock(&stack->nstlock);
 				} else {
 					iframe_t *frm = (iframe_t *)msg->data;
 					struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo);

Modified: branches/1.6.2/channels/misdn/isdn_lib_intern.h
URL: http://svn.asterisk.org/svn-view/asterisk/branches/1.6.2/channels/misdn/isdn_lib_intern.h?view=diff&rev=206765&r1=206764&r2=206765
==============================================================================
--- branches/1.6.2/channels/misdn/isdn_lib_intern.h (original)
+++ branches/1.6.2/channels/misdn/isdn_lib_intern.h Wed Jul 15 16:50:46 2009
@@ -58,6 +58,7 @@
 	/** is first element because &nst equals &mISDNlist **/
 	net_stack_t nst;
 	manager_t mgr;
+	pthread_mutex_t nstlock;
 
 	/*! \brief D Channel mISDN driver stack ID (Parent stack ID) */
 	int d_stid;




More information about the svn-commits mailing list