Bug#697173: ia64 (Itanium), race condition on the start of the history service thread

Stephan Schreiber info at fs-driver.org
Wed Jan 2 07:15:01 UTC 2013


Package: epiphany-browser
Version: 3.4.2-2
Severity: serious
Tags: patch


Machine: Dell PowerEdge 3250
Processor: 2x Itanium Madison 1.5GHz 6M
Memory: 16G


While working on bug#642750, I realized a failing assertion in the  
epiphany browser:
     at lib/history/ephy-history-service.c:363
	  g_assert (priv->history_thread == g_thread_self ());

The assertion failed almost often upon the start of epiphany browser;  
sometimes epiphany could start with success.


The ephy_history_service_init() function creates a new thread (using  
g_thread_new()); run_history_service_thread() is the starting function  
of the thread.

static void
ephy_history_service_init (EphyHistoryService *self)
{
   self->priv = EPHY_HISTORY_SERVICE_GET_PRIVATE (self);

   self->priv->history_thread = g_thread_new ("EphyHistoryService",  
(GThreadFunc) run_history_service_thread, self);
   self->priv->queue = g_async_queue_new ();
}


static gpointer
run_history_service_thread (EphyHistoryService *self)
{
   EphyHistoryServicePrivate *priv = self->priv;
   EphyHistoryServiceMessage *message;

   g_assert (priv->history_thread == g_thread_self ());

   if (ephy_history_service_open_database_connections (self) == FALSE)
     return NULL;

   do {
     message = g_async_queue_try_pop (priv->queue);
     if (!message) {
       /* Schedule commit if needed. */
       if (ephy_history_service_is_scheduled_to_commit (self))
         ephy_history_service_commit (self);

       /* Block the thread until there's data in the queue. */
       message = g_async_queue_pop (priv->queue);
     }

     /* Process item. */
     ephy_history_service_process_message (self, message);

   } while (!ephy_history_service_is_scheduled_to_quit (self));

   ephy_history_service_close_database_connections (self);
   ephy_history_service_execute_quit (self, NULL, NULL);

   return NULL;
}

The third non-empty line of run_history_service_thread() is the  
failing assertion.

The assertion fails because the created thread can execute its code  
before g_thread_new() returns and before the history_thread member is  
initialized.
Whether it happens or not depends on how the operating system  
schedules the processors to the threads.

The history_thread member isn't any problem; it is used just for the  
assertions.
But there is also an async queue (->queue) which is initialized  
*after* creating the new thread in ephy_history_service_init(). This  
means that the code in run_history_service_thread() touches the queue  
when it isn't initialized or while the queue is being initialized by  
the main thread.
That isn't healthy; this can result in data corruption.

The patch
- fixes the issue with the queue, and
- fixes the mentioned assertion.

Although it was experienced on ia64, the bug affects all archs.


You can find a link to the built debs on bug report#642750.

Stephan

-------------- next part --------------
A non-text attachment was scrubbed...
Name: history-thread-startup-race.patch
Type: application/octet-stream
Size: 1791 bytes
Desc: history-thread-startup-race.patch
URL: <http://lists.alioth.debian.org/pipermail/pkg-gnome-maintainers/attachments/20130102/ae6b1e13/attachment-0001.obj>


More information about the pkg-gnome-maintainers mailing list