mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 02:26:23 +00:00
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/branches/1.4@177536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -107,6 +107,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IMAP_STORAGE
|
#ifdef IMAP_STORAGE
|
||||||
|
#include "asterisk/threadstorage.h"
|
||||||
|
|
||||||
AST_MUTEX_DEFINE_STATIC(imaptemp_lock);
|
AST_MUTEX_DEFINE_STATIC(imaptemp_lock);
|
||||||
static char imaptemp[1024];
|
static char imaptemp[1024];
|
||||||
static char imapserver[48];
|
static char imapserver[48];
|
||||||
@@ -123,6 +125,8 @@ static const long DEFAULT_IMAP_TCP_TIMEOUT = 60L;
|
|||||||
struct vm_state;
|
struct vm_state;
|
||||||
struct ast_vm_user;
|
struct ast_vm_user;
|
||||||
|
|
||||||
|
AST_THREADSTORAGE(ts_vmstate, ts_vmstate_init);
|
||||||
|
|
||||||
static int init_mailstream (struct vm_state *vms, int box);
|
static int init_mailstream (struct vm_state *vms, int box);
|
||||||
static void write_file (char *filename, char *buffer, unsigned long len);
|
static void write_file (char *filename, char *buffer, unsigned long len);
|
||||||
/*static void status (MAILSTREAM *stream); */ /* No need for this. */
|
/*static void status (MAILSTREAM *stream); */ /* No need for this. */
|
||||||
@@ -1613,6 +1617,9 @@ void mm_searched(MAILSTREAM *stream, unsigned long number)
|
|||||||
mailbox = stream->mailbox;
|
mailbox = stream->mailbox;
|
||||||
user = get_user_by_mailbox(mailbox);
|
user = get_user_by_mailbox(mailbox);
|
||||||
vms = get_vm_state_by_imapuser(user,2);
|
vms = get_vm_state_by_imapuser(user,2);
|
||||||
|
if (!vms) {
|
||||||
|
vms = get_vm_state_by_imapuser(user, 0);
|
||||||
|
}
|
||||||
if (vms) {
|
if (vms) {
|
||||||
if (option_debug > 2)
|
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);
|
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;
|
mailbox = stream->mailbox;
|
||||||
user = get_user_by_mailbox(mailbox);
|
user = get_user_by_mailbox(mailbox);
|
||||||
vms = get_vm_state_by_imapuser(user,2);
|
vms = get_vm_state_by_imapuser(user,2);
|
||||||
|
if (!vms) {
|
||||||
|
vms = get_vm_state_by_imapuser(user, 0);
|
||||||
|
}
|
||||||
if (vms) {
|
if (vms) {
|
||||||
if (option_debug > 2)
|
if (option_debug > 2)
|
||||||
ast_log (LOG_DEBUG, "User %s usage is %lu, limit is %lu\n",user,usage,limit);
|
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;
|
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)
|
if (option_debug > 4)
|
||||||
ast_log(LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
|
ast_log(LOG_DEBUG,"Adding new vmstate for %s\n",vmu->imapuser);
|
||||||
if (!(vms_p = ast_calloc(1, sizeof(*vms_p))))
|
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;
|
struct vmstate *vlist = NULL;
|
||||||
|
|
||||||
|
if (interactive) {
|
||||||
|
struct vm_state *vms;
|
||||||
|
vms = pthread_getspecific(ts_vmstate.key);
|
||||||
|
return vms;
|
||||||
|
}
|
||||||
|
|
||||||
ast_mutex_lock(&vmstate_lock);
|
ast_mutex_lock(&vmstate_lock);
|
||||||
vlist = vmstates;
|
vlist = vmstates;
|
||||||
while (vlist) {
|
while (vlist) {
|
||||||
@@ -1954,6 +1973,12 @@ static struct vm_state *get_vm_state_by_mailbox(const char *mailbox, const char
|
|||||||
struct vmstate *vlist = NULL;
|
struct vmstate *vlist = NULL;
|
||||||
const char *local_context = S_OR(context, "default");
|
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);
|
ast_mutex_lock(&vmstate_lock);
|
||||||
vlist = vmstates;
|
vlist = vmstates;
|
||||||
if (option_debug > 2)
|
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 (vlist->vms->username && vlist->vms->context) {
|
||||||
if (option_debug > 2)
|
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);
|
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)
|
if (option_debug > 2)
|
||||||
ast_log(LOG_DEBUG, " Found it!\n");
|
ast_log(LOG_DEBUG, " Found it!\n");
|
||||||
ast_mutex_unlock(&vmstate_lock);
|
ast_mutex_unlock(&vmstate_lock);
|
||||||
@@ -2008,9 +2033,13 @@ static void vmstate_insert(struct vm_state *vms)
|
|||||||
/* get a pointer to the persistent store */
|
/* get a pointer to the persistent store */
|
||||||
vms->persist_vms = altvms;
|
vms->persist_vms = altvms;
|
||||||
/* Reuse the mailstream? */
|
/* Reuse the mailstream? */
|
||||||
|
#ifdef REALLY_FAST_EVEN_IF_IT_MEANS_RESOURCE_LEAKS
|
||||||
vms->mailstream = altvms->mailstream;
|
vms->mailstream = altvms->mailstream;
|
||||||
/* vms->mailstream = NIL; */
|
#else
|
||||||
|
vms->mailstream = NIL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = (struct vmstate *)malloc(sizeof(struct vmstate));
|
v = (struct vmstate *)malloc(sizeof(struct vmstate));
|
||||||
@@ -2042,6 +2071,10 @@ static void vmstate_delete(struct vm_state *vms)
|
|||||||
altvms->oldmessages = vms->oldmessages;
|
altvms->oldmessages = vms->oldmessages;
|
||||||
altvms->updated = 1;
|
altvms->updated = 1;
|
||||||
}
|
}
|
||||||
|
vms->mailstream = mail_close(vms->mailstream);
|
||||||
|
|
||||||
|
/* Interactive states are not stored within the persistent list */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_mutex_lock(&vmstate_lock);
|
ast_mutex_lock(&vmstate_lock);
|
||||||
@@ -7324,6 +7357,9 @@ static int vm_execmain(struct ast_channel *chan, void *data)
|
|||||||
adsi_begin(chan, &useadsi);
|
adsi_begin(chan, &useadsi);
|
||||||
|
|
||||||
#ifdef IMAP_STORAGE
|
#ifdef IMAP_STORAGE
|
||||||
|
pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
|
||||||
|
pthread_setspecific(ts_vmstate.key, &vms);
|
||||||
|
|
||||||
vms.interactive = 1;
|
vms.interactive = 1;
|
||||||
vms.updated = 1;
|
vms.updated = 1;
|
||||||
if (vmu)
|
if (vmu)
|
||||||
@@ -7756,8 +7792,11 @@ out:
|
|||||||
free(vms.deleted);
|
free(vms.deleted);
|
||||||
if (vms.heard)
|
if (vms.heard)
|
||||||
free(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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user