From 306f229d64783b12088561afe09ebb05636afe7e Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Thu, 19 Feb 2009 22:33:00 +0000 Subject: Merged revisions 177536 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r177536 | tilghman | 2009-02-19 16:26:01 -0600 (Thu, 19 Feb 2009) | 7 lines 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 ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@177537 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_voicemail.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'apps') diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 257ebae2b..8cfe1c958 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -115,6 +115,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/res_odbc.h" #endif +#ifdef IMAP_STORAGE +#include "asterisk/threadstorage.h" +#endif + /*** DOCUMENTATION @@ -297,6 +301,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") ***/ #ifdef IMAP_STORAGE +AST_MUTEX_DEFINE_STATIC(imaptemp_lock); +static char imaptemp[1024]; static char imapserver[48]; static char imapport[8]; static char imapflags[128]; @@ -313,6 +319,8 @@ static char delimiter = '\0'; struct vm_state; struct ast_vm_user; +AST_THREADSTORAGE(ts_vmstate, ts_vmstate_init); + /* Forward declarations for IMAP */ static int init_mailstream(struct vm_state *vms, int box); static void write_file(char *filename, char *buffer, unsigned long len); @@ -2496,7 +2504,7 @@ static void mm_parsequota(MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pqu pquota = pquota->next; } - if (!(user = get_user_by_mailbox(mailbox, buf, sizeof(buf))) || !(vms = get_vm_state_by_imapuser(user, 2))) { + if (!(user = get_user_by_mailbox(mailbox, buf, sizeof(buf))) || (!(vms = get_vm_state_by_imapuser(user, 2)) && !(vms = get_vm_state_by_imapuser(user, 0)))) { ast_log(AST_LOG_ERROR, "No state found.\n"); return; } @@ -2559,6 +2567,9 @@ static struct vm_state *create_vm_state_from_user(struct ast_vm_user *vmu) { 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(AST_LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser); if (!(vms_p = ast_calloc(1, sizeof(*vms_p)))) @@ -2581,6 +2592,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_LIST_LOCK(&vmstates); AST_LIST_TRAVERSE(&vmstates, vlist, list) { if (!vlist->vms) { @@ -2610,6 +2627,12 @@ static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, const char 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_LIST_LOCK(&vmstates); AST_LIST_TRAVERSE(&vmstates, vlist, list) { if (!vlist->vms) { @@ -2656,9 +2679,13 @@ static void vmstate_insert(struct vm_state *vms) /* 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; } if (!(v = ast_calloc(1, sizeof(*v)))) @@ -2685,6 +2712,10 @@ static void vmstate_delete(struct vm_state *vms) altvms->newmessages = vms->newmessages; altvms->oldmessages = vms->oldmessages; altvms->updated = 1; + vms->mailstream = mail_close(vms->mailstream); + + /* Interactive states are not stored within the persistent list */ + return; } ast_debug(3, "Removing vm_state for user:%s, mailbox %s\n", vms->imapuser, vms->username); @@ -8892,6 +8923,9 @@ static int vm_execmain(struct ast_channel *chan, void *data) 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) @@ -9462,6 +9496,9 @@ out: if (vms.heard) ast_free(vms.heard); +#ifdef IMAP_STORAGE + pthread_setspecific(ts_vmstate.key, NULL); +#endif return res; } -- cgit v1.2.3