main_connected (gpointer data)
{
DEBUG ("connected");
+ ASSERT_IS_MAIN_THREAD ();
gtk_label_set_text (GTK_LABEL (ca_error), NULL);
main_disconnected (gpointer data)
{
DEBUG ("disconnected");
+ ASSERT_IS_MAIN_THREAD ();
+
gtk_widget_show (connection_area);
gtk_widget_hide (login_area);
return FALSE;
main_logged_in (gpointer data)
{
DEBUG ("logged in");
+ ASSERT_IS_MAIN_THREAD ();
+
gtk_widget_hide (login_area);
return FALSE;
}
main_logged_out (gpointer data)
{
DEBUG ("logged out");
+ ASSERT_IS_MAIN_THREAD ();
+
if (wui_thread_is_connected ())
gtk_widget_show (login_area);
return FALSE;
GdkWindow *gdk_window;
DEBUG ("busy");
+ ASSERT_IS_MAIN_THREAD ();
gdk_window = gtk_widget_get_window (window);
if (gdk_window) {
GdkWindow *gdk_window;
DEBUG ("idle");
+ ASSERT_IS_MAIN_THREAD ();
gdk_window = gtk_widget_get_window (window);
if (gdk_window) {
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);
char *str = (char *) _str;
DEBUG ("login error: %s", str);
+ ASSERT_IS_MAIN_THREAD ();
/*
gtk_label_set_text (GTK_LABEL (ca_error), str);
char *str = (char *) _str;
DEBUG ("status error: %s", str);
+ ASSERT_IS_MAIN_THREAD ();
/*
gtk_label_set_text (GTK_LABEL (ca_error), str);
/* 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
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 ();
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.
*
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);
{
struct message *msg;
+ ASSERT_IS_MAIN_THREAD ();
+
msg = g_new (struct message, 1);
msg->type = CONNECT;
msg->str1 = g_strdup (uri);
{
struct message *msg;
+ ASSERT_IS_MAIN_THREAD ();
+
msg = g_new (struct message, 1);
msg->type = DISCONNECT;
g_async_queue_push (wui_thread_queue, msg);
{
struct message *msg;
+ ASSERT_IS_MAIN_THREAD ();
+
msg = g_new (struct message, 1);
msg->type = LOGIN;
msg->str1 = g_strdup (username);
{
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);
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
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);
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);
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);
{
gboolean ret;
+ ASSERT_IS_MAIN_THREAD ();
+
g_static_mutex_lock (&state_mutex);
ret = connected;
g_static_mutex_unlock (&state_mutex);
{
gboolean ret;
+ ASSERT_IS_MAIN_THREAD ();
+
g_static_mutex_lock (&state_mutex);
ret = logged_in;
g_static_mutex_unlock (&state_mutex);
{
gboolean ret;
+ ASSERT_IS_MAIN_THREAD ();
+
g_static_mutex_lock (&state_mutex);
ret = busy;
g_static_mutex_unlock (&state_mutex);
static gboolean
process_message (struct message *msg)
{
+ ASSERT_IS_WUI_THREAD ();
+
switch (msg->type) {
case QUIT:
write_fn_discard_capture_buffer ();
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;
static void
write_fn_start_capture (void)
{
+ ASSERT_IS_WUI_THREAD ();
+
write_fn_discard_capture_buffer ();
write_fn_buffer = NULL;
write_fn_len = 0;
{
char *ret = write_fn_buffer;
+ ASSERT_IS_WUI_THREAD ();
+
write_fn_buffer = NULL;
write_fn_len = -1;
return ret;
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;
header_fn (void *ptr, size_t size, size_t nmemb, void *stream)
{
int bytes = size * nmemb;
+
+ ASSERT_IS_WUI_THREAD ();
+
return bytes;
}
{
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");
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));
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;
char *xml;
DEBUG ("refreshing list of VMs");
+ ASSERT_IS_WUI_THREAD ();
/* Generate the vms URI from the base URI. */
len = strlen (uri) + 4 + 1;
{
gboolean ret;
+ ASSERT_IS_MAIN_THREAD ();
+
g_static_mutex_lock (&vmlist_mutex);
ret = vmlist_valid;
g_static_mutex_unlock (&vmlist_mutex);
{
gboolean r;
+ ASSERT_IS_MAIN_THREAD ();
+
r = FALSE;
*ret = NULL;