[asterisk-commits] tilghman: branch 1.4 r177536 - /branches/1.4/apps/app_voicemail.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Feb 19 16:26:01 CST 2009


Author: tilghman
Date: Thu Feb 19 16:26:01 2009
New Revision: 177536

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=177536
Log:
Fix up potential crashes, by reducing the sharing between interactive and non-interactive threads.
(closes issue #14253)
 Reported by: Skavin
 Patches: 
       20090219__bug14253.diff.txt uploaded by Corydon76 (license 14)
 Tested by: Skavin

Modified:
    branches/1.4/apps/app_voicemail.c

Modified: branches/1.4/apps/app_voicemail.c
URL: http://svn.digium.com/svn-view/asterisk/branches/1.4/apps/app_voicemail.c?view=diff&rev=177536&r1=177535&r2=177536
==============================================================================
--- branches/1.4/apps/app_voicemail.c (original)
+++ branches/1.4/apps/app_voicemail.c Thu Feb 19 16:26:01 2009
@@ -107,6 +107,8 @@
 #endif
 
 #ifdef IMAP_STORAGE
+#include "asterisk/threadstorage.h"
+
 AST_MUTEX_DEFINE_STATIC(imaptemp_lock);
 static char imaptemp[1024];
 static char imapserver[48];
@@ -122,6 +124,8 @@
 
 struct vm_state;
 struct ast_vm_user;
+
+AST_THREADSTORAGE(ts_vmstate, ts_vmstate_init);
 
 static int init_mailstream (struct vm_state *vms, int box);
 static void write_file (char *filename, char *buffer, unsigned long len);
@@ -1613,6 +1617,9 @@
 	mailbox = stream->mailbox;
 	user = get_user_by_mailbox(mailbox);
 	vms = get_vm_state_by_imapuser(user,2);
+	if (!vms) {
+		vms = get_vm_state_by_imapuser(user, 0);
+	}
 	if (vms) {
 		if (option_debug > 2)
 			ast_log (LOG_DEBUG, "saving mailbox message number %lu as message %d. Interactive set to %d\n",number,vms->vmArrayIndex,vms->interactive);
@@ -1827,6 +1834,9 @@
 	mailbox = stream->mailbox;
 	user = get_user_by_mailbox(mailbox);
 	vms = get_vm_state_by_imapuser(user,2);
+	if (!vms) {
+		vms = get_vm_state_by_imapuser(user, 0);
+	}
 	if (vms) {
 		if (option_debug > 2)
 			ast_log (LOG_DEBUG, "User %s usage is %lu, limit is %lu\n",user,usage,limit);
@@ -1897,6 +1907,9 @@
 {
 	struct vm_state *vms_p;
 
+	if ((vms_p = pthread_getspecific(ts_vmstate.key)) && !strcmp(vms_p->imapuser, vmu->imapuser) && !strcmp(vms_p->username, vmu->mailbox)) {
+		return vms_p;
+	}
 	if (option_debug > 4)
 		ast_log(LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
 	if (!(vms_p = ast_calloc(1, sizeof(*vms_p))))
@@ -1918,6 +1931,12 @@
 static struct vm_state *get_vm_state_by_imapuser(char *user, int interactive)
 {
 	struct vmstate *vlist = NULL;
+
+	if (interactive) {
+		struct vm_state *vms;
+		vms = pthread_getspecific(ts_vmstate.key);
+		return vms;
+	}
 
 	ast_mutex_lock(&vmstate_lock);
 	vlist = vmstates;
@@ -1954,6 +1973,12 @@
 	struct vmstate *vlist = NULL;
 	const char *local_context = S_OR(context, "default");
 
+	if (interactive) {
+		struct vm_state *vms;
+		vms = pthread_getspecific(ts_vmstate.key);
+		return vms;
+	}
+
 	ast_mutex_lock(&vmstate_lock);
 	vlist = vmstates;
 	if (option_debug > 2) 
@@ -1963,7 +1988,7 @@
 			if (vlist->vms->username && vlist->vms->context) {
 				if (option_debug > 2)
 					ast_log(LOG_DEBUG, "	comparing mailbox %s (i=%d) to vmstate mailbox %s (i=%d)\n",mailbox,interactive,vlist->vms->username,vlist->vms->interactive);
-				if (!strcmp(vlist->vms->username,mailbox) && !(strcmp(vlist->vms->context, local_context)) && vlist->vms->interactive == interactive) {
+				if (!strcmp(vlist->vms->username,mailbox) && !(strcmp(vlist->vms->context, local_context))) {
 					if (option_debug > 2)
 						ast_log(LOG_DEBUG, "	Found it!\n");
 					ast_mutex_unlock(&vmstate_lock);
@@ -2008,9 +2033,13 @@
 			/* get a pointer to the persistent store */
 			vms->persist_vms = altvms;
 			/* Reuse the mailstream? */
+#ifdef REALLY_FAST_EVEN_IF_IT_MEANS_RESOURCE_LEAKS
 			vms->mailstream = altvms->mailstream;
-			/* vms->mailstream = NIL; */
-		}
+#else
+			vms->mailstream = NIL;
+#endif
+		}
+		return;
 	}
 
 	v = (struct vmstate *)malloc(sizeof(struct vmstate));
@@ -2042,6 +2071,10 @@
 			altvms->oldmessages = vms->oldmessages;
 			altvms->updated = 1;
 		}
+		vms->mailstream = mail_close(vms->mailstream);
+
+		/* Interactive states are not stored within the persistent list */
+		return;
 	}
 
 	ast_mutex_lock(&vmstate_lock);
@@ -7324,6 +7357,9 @@
 	adsi_begin(chan, &useadsi);
 
 #ifdef IMAP_STORAGE
+	pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
+	pthread_setspecific(ts_vmstate.key, &vms);
+
 	vms.interactive = 1;
 	vms.updated = 1;
 	if (vmu)
@@ -7756,8 +7792,11 @@
 		free(vms.deleted);
 	if (vms.heard)
 		free(vms.heard);
+
+#ifdef IMAP_STORAGE
+	pthread_setspecific(ts_vmstate.key, NULL);
+#endif
 	ast_module_user_remove(u);
-
 	return res;
 }
 




More information about the asterisk-commits mailing list