diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-02-19 22:26:01 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-02-19 22:26:01 +0000 |
commit | fec1153e822e14299f07afcec59f31f4344fc9ec (patch) | |
tree | ba95ffc9a3231aff1ed345c4b083c35f61cbf46e /apps/app_voicemail.c | |
parent | 91fcfca23578d8a592ff4c56c06df357d1900936 (diff) |
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: http://svn.digium.com/svn/asterisk/branches/1.4@177536 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_voicemail.c')
-rw-r--r-- | apps/app_voicemail.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 3566e71f4..019df23ff 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -107,6 +107,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #endif #ifdef IMAP_STORAGE +#include "asterisk/threadstorage.h" + AST_MUTEX_DEFINE_STATIC(imaptemp_lock); static char imaptemp[1024]; static char imapserver[48]; @@ -123,6 +125,8 @@ static const long DEFAULT_IMAP_TCP_TIMEOUT = 60L; 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); /*static void status (MAILSTREAM *stream); */ /* No need for this. */ @@ -1613,6 +1617,9 @@ void mm_searched(MAILSTREAM *stream, unsigned long number) 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 @@ static void mm_parsequota(MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pqu 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 @@ 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(LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser); if (!(vms_p = ast_calloc(1, sizeof(*vms_p)))) @@ -1919,6 +1932,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; while (vlist) { @@ -1954,6 +1973,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_mutex_lock(&vmstate_lock); vlist = vmstates; if (option_debug > 2) @@ -1963,7 +1988,7 @@ static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, const char 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 @@ 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; } v = (struct vmstate *)malloc(sizeof(struct vmstate)); @@ -2042,6 +2071,10 @@ static void vmstate_delete(struct vm_state *vms) 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 @@ 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) @@ -7756,8 +7792,11 @@ out: free(vms.deleted); if (vms.heard) free(vms.heard); - ast_module_user_remove(u); +#ifdef IMAP_STORAGE + pthread_setspecific(ts_vmstate.key, NULL); +#endif + ast_module_user_remove(u); return res; } |