Package: epiphany-browser Version: 3.4.2-2 Severity: serious Tags: patch
Machine: Dell PowerEdge 3250 Processor: 2x Itanium Madison 1.5GHz 6M Memory: 16GWhile 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
history-thread-startup-race.patch
Description: history-thread-startup-race.patch

