5 #define EVENT_TIMEOUT_MICROSECONDS (3000000)
7 static GQueue *event_queue = NULL;
8 static GMutex *event_lock = NULL;
9 static GCond *event_queue_not_empty = NULL;
10 static GCond *event_queue_not_full = NULL;
12 /* Internal function: initialize the event_queue, locking and signalling
17 event_queue = g_queue_new();
18 event_lock = g_mutex_new();
19 event_queue_not_empty = g_cond_new();
20 event_queue_not_full = g_cond_new();
23 /* Internal function: free the event queue and all the objects allocated in
28 g_mutex_lock(event_lock);
29 g_queue_foreach(event_queue, (GFunc)g_free, NULL);
30 g_queue_free(event_queue);
31 g_cond_free(event_queue_not_empty);
32 g_cond_free(event_queue_not_full);
34 g_mutex_unlock(event_lock);
35 g_mutex_free(event_lock);
38 /* Internal function: push an event onto the event queue. If the event queue is
39 full, wait for max three seconds and then drop the event. If the event queue is
40 NULL, i.e. freed, then fail silently. */
42 event_throw(glui32 type, winid_t win, glui32 val1, glui32 val2)
48 g_get_current_time(&timeout);
49 g_time_val_add(&timeout, EVENT_TIMEOUT_MICROSECONDS);
51 g_mutex_lock(event_lock);
53 /* Wait for room in the event queue */
54 while( g_queue_get_length(event_queue) >= EVENT_QUEUE_MAX_LENGTH )
55 if( !g_cond_timed_wait(event_queue_not_full, event_lock, &timeout) )
57 /* Drop the event after 3 seconds */
58 g_mutex_unlock(event_lock);
62 event_t *event = g_new0(event_t, 1);
67 g_queue_push_head(event_queue, event);
69 /* Signal that there is an event */
70 g_cond_signal(event_queue_not_empty);
72 g_mutex_unlock(event_lock);
77 * @event: Pointer to an #event_t.
79 * Causes the program to wait for an event, and then store it in the structure
80 * pointed to by @event. Unlike most Glk functions that take pointers, the
81 * argument of glk_select() may not be %NULL.
83 * Most of the time, you only get the events that you request. However, there
84 * are some events which can arrive at any time. This is why you must always
85 * call glk_select() in a loop, and continue the loop until you get the event
89 glk_select(event_t *event)
91 g_return_if_fail(event != NULL);
93 g_mutex_lock(event_lock);
95 /* Wait for an event */
96 while( g_queue_is_empty(event_queue) )
97 g_cond_wait(event_queue_not_empty, event_lock);
99 event_t *retrieved_event = g_queue_pop_tail(event_queue);
100 if(retrieved_event == NULL)
102 g_mutex_unlock(event_lock);
103 g_warning("%s: Retrieved NULL event from non-empty event queue", __func__);
106 memcpy(event, retrieved_event, sizeof(event_t));
107 g_free(retrieved_event);
109 /* Signal that the event queue is no longer full */
110 g_cond_signal(event_queue_not_full);
112 g_mutex_unlock(event_lock);
114 /* Check for interrupt */
117 /* If an abort event was generated, the thread should have exited by now */
118 g_assert(event->type != evtype_Abort);