Add assertions about which thread we are running in.
authorRichard Jones <rjones@redhat.com>
Sat, 29 Nov 2008 13:23:52 +0000 (13:23 +0000)
committerRichard Jones <rjones@redhat.com>
Sat, 29 Nov 2008 13:23:52 +0000 (13:23 +0000)
internal.h
main.c
wui_thread.c

index 2fbf2c7..77b3907 100644 (file)
@@ -61,6 +61,12 @@ extern gboolean check_cert;
 extern void start_wui_thread (void);
 extern void stop_wui_thread (void);
 
+extern void assert_is_main_thread (const char *, int);
+extern void assert_is_wui_thread (const char *, int);
+
+#define ASSERT_IS_MAIN_THREAD() assert_is_main_thread(__FILE__,__LINE__)
+#define ASSERT_IS_WUI_THREAD() assert_is_wui_thread(__FILE__,__LINE__)
+
 /* These are messages (instructions) which can be sent from the main
  * thread to the WUI thread.
  */
diff --git a/main.c b/main.c
index 0545ec4..0425128 100644 (file)
--- a/main.c
+++ b/main.c
@@ -415,6 +415,7 @@ gboolean
 main_connected (gpointer data)
 {
   DEBUG ("connected");
+  ASSERT_IS_MAIN_THREAD ();
 
   gtk_label_set_text (GTK_LABEL (ca_error), NULL);
 
@@ -429,6 +430,8 @@ gboolean
 main_disconnected (gpointer data)
 {
   DEBUG ("disconnected");
+  ASSERT_IS_MAIN_THREAD ();
+
   gtk_widget_show (connection_area);
   gtk_widget_hide (login_area);
   return FALSE;
@@ -439,6 +442,8 @@ gboolean
 main_logged_in (gpointer data)
 {
   DEBUG ("logged in");
+  ASSERT_IS_MAIN_THREAD ();
+
   gtk_widget_hide (login_area);
   return FALSE;
 }
@@ -448,6 +453,8 @@ gboolean
 main_logged_out (gpointer data)
 {
   DEBUG ("logged out");
+  ASSERT_IS_MAIN_THREAD ();
+
   if (wui_thread_is_connected ())
     gtk_widget_show (login_area);
   return FALSE;
@@ -460,6 +467,7 @@ main_busy (gpointer data)
   GdkWindow *gdk_window;
 
   DEBUG ("busy");
+  ASSERT_IS_MAIN_THREAD ();
 
   gdk_window = gtk_widget_get_window (window);
   if (gdk_window) {
@@ -477,6 +485,7 @@ main_idle (gpointer data)
   GdkWindow *gdk_window;
 
   DEBUG ("idle");
+  ASSERT_IS_MAIN_THREAD ();
 
   gdk_window = gtk_widget_get_window (window);
   if (gdk_window) {
@@ -496,6 +505,7 @@ main_connection_error (gpointer _str)
   char *str = (char *) _str;
 
   DEBUG ("connection error: %s", str);
+  ASSERT_IS_MAIN_THREAD ();
 
   gtk_label_set_text (GTK_LABEL (ca_error), str);
   g_free (str);
@@ -512,6 +522,7 @@ main_login_error (gpointer _str)
   char *str = (char *) _str;
 
   DEBUG ("login error: %s", str);
+  ASSERT_IS_MAIN_THREAD ();
 
   /*
   gtk_label_set_text (GTK_LABEL (ca_error), str);
@@ -530,6 +541,7 @@ main_status_error (gpointer _str)
   char *str = (char *) _str;
 
   DEBUG ("status error: %s", str);
+  ASSERT_IS_MAIN_THREAD ();
 
   /*
   gtk_label_set_text (GTK_LABEL (ca_error), str);
index 49dc270..94631b6 100644 (file)
@@ -64,6 +64,7 @@ struct message {
 
 /* Start the WUI thread.  See main() for explanation of the threading model. */
 static GThread *wui_gthread = NULL;
+static GThread *main_gthread = NULL;
 static GAsyncQueue *wui_thread_queue = NULL;
 
 void
@@ -73,6 +74,10 @@ start_wui_thread (void)
 
   DEBUG ("starting the WUI thread");
 
+  assert (wui_gthread == NULL);
+
+  main_gthread = g_thread_self ();
+
   /* Create the message queue for main -> WUI thread communications. */
   wui_thread_queue = g_async_queue_new ();
 
@@ -88,7 +93,9 @@ void
 stop_wui_thread (void)
 {
   DEBUG ("stopping the WUI thread");
-  assert (wui_gthread);
+
+  assert (wui_gthread != NULL);
+  ASSERT_IS_MAIN_THREAD ();
 
   /* Send a quit message then wait for the WUI thread to join.
    *
@@ -107,12 +114,32 @@ stop_wui_thread (void)
   wui_gthread = NULL;
 }
 
+void
+assert_is_wui_thread (const char *filename, int lineno)
+{
+  if (g_thread_self () != wui_gthread) {
+    fprintf (stderr, "%s:%d: internal error: this function should only run in the context of the WUI thread\n", filename, lineno);
+    abort ();
+  }
+}
+
+void
+assert_is_main_thread (const char *filename, int lineno)
+{
+  if (g_thread_self () != main_gthread) {
+    fprintf (stderr, "%s:%d: internal error: this function should only run in the context of the main thread\n", filename, lineno);
+    abort ();
+  }
+}
+
 /* Send the quit message to the WUI thread. */
 static void
 wui_thread_send_quit (void)
 {
   struct message *msg;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   msg = g_new (struct message, 1);
   msg->type = QUIT;
   g_async_queue_push (wui_thread_queue, msg);
@@ -124,6 +151,8 @@ wui_thread_send_connect (const char *uri)
 {
   struct message *msg;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   msg = g_new (struct message, 1);
   msg->type = CONNECT;
   msg->str1 = g_strdup (uri);
@@ -136,6 +165,8 @@ wui_thread_send_disconnect (void)
 {
   struct message *msg;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   msg = g_new (struct message, 1);
   msg->type = DISCONNECT;
   g_async_queue_push (wui_thread_queue, msg);
@@ -147,6 +178,8 @@ wui_thread_send_login (const char *username, const char *password)
 {
   struct message *msg;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   msg = g_new (struct message, 1);
   msg->type = LOGIN;
   msg->str1 = g_strdup (username);
@@ -160,6 +193,8 @@ wui_thread_send_refresh_vm_list (void)
 {
   struct message *msg;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   msg = g_new (struct message, 1);
   msg->type = REFRESH_VM_LIST;
   g_async_queue_push (wui_thread_queue, msg);
@@ -205,6 +240,8 @@ wui_thread (gpointer _queue)
 
   DEBUG ("WUI thread starting up");
 
+  ASSERT_IS_WUI_THREAD ();
+
   g_async_queue_ref (queue);
 
   /* In the thread's loop we check for new instructions from the main
@@ -254,6 +291,8 @@ wui_thread (gpointer _queue)
 static void
 set_connected (gboolean new_connected)
 {
+  ASSERT_IS_WUI_THREAD ();
+
   g_static_mutex_lock (&state_mutex);
   connected = new_connected;
   g_static_mutex_unlock (&state_mutex);
@@ -267,6 +306,8 @@ set_connected (gboolean new_connected)
 static void
 set_logged_in (gboolean new_logged_in)
 {
+  ASSERT_IS_WUI_THREAD ();
+
   g_static_mutex_lock (&state_mutex);
   logged_in = new_logged_in;
   g_static_mutex_unlock (&state_mutex);
@@ -280,6 +321,8 @@ set_logged_in (gboolean new_logged_in)
 static void
 set_busy (gboolean new_busy)
 {
+  ASSERT_IS_WUI_THREAD ();
+
   g_static_mutex_lock (&state_mutex);
   busy = new_busy;
   g_static_mutex_unlock (&state_mutex);
@@ -298,6 +341,8 @@ wui_thread_is_connected (void)
 {
   gboolean ret;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   g_static_mutex_lock (&state_mutex);
   ret = connected;
   g_static_mutex_unlock (&state_mutex);
@@ -309,6 +354,8 @@ wui_thread_is_logged_in (void)
 {
   gboolean ret;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   g_static_mutex_lock (&state_mutex);
   ret = logged_in;
   g_static_mutex_unlock (&state_mutex);
@@ -320,6 +367,8 @@ wui_thread_is_busy (void)
 {
   gboolean ret;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   g_static_mutex_lock (&state_mutex);
   ret = busy;
   g_static_mutex_unlock (&state_mutex);
@@ -330,6 +379,8 @@ wui_thread_is_busy (void)
 static gboolean
 process_message (struct message *msg)
 {
+  ASSERT_IS_WUI_THREAD ();
+
   switch (msg->type) {
   case QUIT:
     write_fn_discard_capture_buffer ();
@@ -432,6 +483,8 @@ write_fn (void *ptr, size_t size, size_t nmemb, void *stream)
   int bytes = size * nmemb;
   int old_start;
 
+  ASSERT_IS_WUI_THREAD ();
+
   if (write_fn_len >= 0) {     /* We're capturing. */
     old_start = write_fn_len;
     write_fn_len += bytes;
@@ -446,6 +499,8 @@ write_fn (void *ptr, size_t size, size_t nmemb, void *stream)
 static void
 write_fn_start_capture (void)
 {
+  ASSERT_IS_WUI_THREAD ();
+
   write_fn_discard_capture_buffer ();
   write_fn_buffer = NULL;
   write_fn_len = 0;
@@ -457,6 +512,8 @@ write_fn_finish_capture (void)
 {
   char *ret = write_fn_buffer;
 
+  ASSERT_IS_WUI_THREAD ();
+
   write_fn_buffer = NULL;
   write_fn_len = -1;
   return ret;
@@ -466,6 +523,8 @@ write_fn_finish_capture (void)
 static void
 write_fn_discard_capture_buffer (void)
 {
+  ASSERT_IS_WUI_THREAD ();
+
   g_free (write_fn_buffer);
   write_fn_buffer = NULL;
   write_fn_len = -1;
@@ -475,6 +534,9 @@ static size_t
 header_fn (void *ptr, size_t size, size_t nmemb, void *stream)
 {
   int bytes = size * nmemb;
+
+  ASSERT_IS_WUI_THREAD ();
+
   return bytes;
 }
 
@@ -484,6 +546,8 @@ do_curl_init (void)
 {
   DEBUG ("initializing libcurl");
 
+  ASSERT_IS_WUI_THREAD ();
+
   curl = curl_easy_init ();
   if (!curl) {            /* This is probably quite bad, so abort. */
     DEBUG ("curl_easy_init failed");
@@ -522,6 +586,7 @@ do_connect (void)
   char *error_str;
 
   DEBUG ("connecting to uri %s", uri);
+  ASSERT_IS_WUI_THREAD ();
 
   /* Set the URI for libcurl. */
   CURL_CHECK_ERROR (curl_easy_setopt, (curl, CURLOPT_URL, uri));
@@ -561,6 +626,7 @@ do_login (void)
   long code = 0;
 
   DEBUG ("logging in with username %s, password *****", username);
+  ASSERT_IS_WUI_THREAD ();
 
   /* Generate the login URI from the base URI. */
   len = strlen (uri) + 6 + 1;
@@ -630,6 +696,7 @@ refresh_vm_list (void)
   char *xml;
 
   DEBUG ("refreshing list of VMs");
+  ASSERT_IS_WUI_THREAD ();
 
   /* Generate the vms URI from the base URI. */
   len = strlen (uri) + 4 + 1;
@@ -749,6 +816,8 @@ wui_thread_has_valid_vmlist (void)
 {
   gboolean ret;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   g_static_mutex_lock (&vmlist_mutex);
   ret = vmlist_valid;
   g_static_mutex_unlock (&vmlist_mutex);
@@ -772,6 +841,8 @@ wui_thread_get_vmlist (GSList **ret)
 {
   gboolean r;
 
+  ASSERT_IS_MAIN_THREAD ();
+
   r = FALSE;
   *ret = NULL;