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