Hi,all
I found an implict multithread problem. I want to see
whether anybody could give me more information about it.

In function message-list.c:mail_regen_list,
a new message is created and put into a thread queue,
meanwhile, the message is also prepended to a regen list of the message
list.
But, the regen list is not protected by a mutex which maybe lead to a
severe problem because
it will be changed in thread function "regen_list_free" and
"regen_list_regened",
is this a bug of evolution?



/* if we're busy already kick off timeout processing, so normal updates
are immediate */
        if (ml->regen == NULL)
*****************************************************************
the new message is put into a thread queue
****************************************************************
                ml_regen_timeout(m); 
        else {
                ml->regen_timeout_msg = m;
                ml->regen_timeout_id = g_timeout_add(500,
(GSourceFunc)ml_regen_timeout, m);
        }



static gboolean
ml_regen_timeout(struct _regen_list_msg *m)
{
        e_profile_event_emit("list.regenerate", m->folder->full_name,
0);

        ***************************************************
        This code is not protected
        ***************************************************
        m->ml->regen = g_list_prepend(m->ml->regen, m);                 
        /* TODO: we should manage our own thread stuff, would make
cancelling outstanding stuff easier */
        e_thread_put (mail_thread_queued, (EMsg *)m);

        m->ml->regen_timeout_msg = NULL;
        m->ml->regen_timeout_id = 0;

        return FALSE;
}

regen_list_free (struct _mail_msg *mm)
{
        struct _regen_list_msg *m = (struct _regen_list_msg *)mm;
        int i;

        e_profile_event_emit("list.regenerated", m->folder->full_name,
0);

        if (m->summary) {
                for (i = 0; i < m->summary->len; i++)
                        camel_folder_free_message_info (m->folder,
m->summary->pdata[i]);
                g_ptr_array_free (m->summary, TRUE);
        }

        if (m->tree)
                camel_folder_thread_messages_unref (m->tree);

        g_free (m->search);
        g_free (m->hideexpr);

        camel_object_unref (m->folder);

        if (m->changes)
                camel_folder_change_info_free (m->changes);

        /* we have to poke this here as well since we might've been
cancelled and regened wont get called */
        *****************************************************
        This code is not protected
        *****************************************************
        m->ml->regen = g_list_remove(m->ml->regen, m);

        g_object_unref(m->ml);
}


Jeff Cai

_______________________________________________
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers

Reply via email to