]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkeventloop-quartz.c
Fix broken quartz build from df3e19b
[~andy/gtk] / gdk / quartz / gdkeventloop-quartz.c
1 #include "config.h"
2
3 #include <glib.h>
4 #include <pthread.h>
5 #include <sys/types.h>
6 #include <sys/uio.h>
7 #include <unistd.h>
8
9 #include "gdkprivate-quartz.h"
10 #include <gdk/gdkdisplayprivate.h>
11
12 /* 
13  * This file implementations integration between the GLib main loop and
14  * the native system of the Core Foundation run loop and Cocoa event
15  * handling. There are basically two different cases that we need to
16  * handle: either the GLib main loop is in control (the application
17  * has called gtk_main(), or is otherwise iterating the main loop), or
18  * CFRunLoop is in control (we are in a modal operation such as window
19  * resizing or drag-and-drop.)
20  *
21  * When the GLib main loop is in control we integrate in native event
22  * handling in two ways: first we add a GSource that handles checking
23  * whether there are native events available, translating native events
24  * to GDK events, and dispatching GDK events. Second we replace the
25  * "poll function" of the GLib main loop with our own version that knows
26  * how to wait for both the file descriptors and timeouts that GLib is
27  * interested in and also for incoming native events.
28  *
29  * When CFRunLoop is in control, we integrate in GLib main loop handling
30  * by adding a "run loop observer" that gives us notification at various
31  * points in the run loop cycle. We map these points onto the corresponding
32  * stages of the GLib main loop (prepare, check, dispatch), and make the
33  * appropriate calls into GLib.
34  *
35  * Both cases share a single problem: the OS X API's don't allow us to
36  * wait simultaneously for file descriptors and for events. So when we
37  * need to do a blocking wait that includes file descriptor activity, we
38  * push the actual work of calling select() to a helper thread (the
39  * "select thread") and wait for native events in the main thread.
40  *
41  * The main known limitation of this code is that if a callback is triggered
42  * via the OS X run loop while we are "polling" (in either case described
43  * above), iteration of the GLib main loop is not possible from within
44  * that callback. If the programmer tries to do so explicitly, then they
45  * will get a warning from GLib "main loop already active in another thread".
46  */
47
48 /******* State for run loop iteration *******/
49
50 /* Count of number of times we've gotten an "Entry" notification for
51  * our run loop observer.
52  */
53 static int current_loop_level = 0;
54
55 /* Run loop level at which we acquired ownership of the GLib main
56  * loop. See note in run_loop_entry(). -1 means that we don't have
57  * ownership
58  */ 
59 static int acquired_loop_level = -1;
60
61 /* Between run_loop_before_waiting() and run_loop_after_waiting();
62  * whether we we need to call select_thread_collect_poll()
63  */
64 static gboolean run_loop_polling_async = FALSE;
65
66 /* Between run_loop_before_waiting() and run_loop_after_waiting();
67  * max_prioritiy to pass to g_main_loop_check()
68  */
69 static gint run_loop_max_priority;
70
71 /* Timer that we've added to wake up the run loop when a GLib timeout
72  */
73 static CFRunLoopTimerRef run_loop_timer = NULL;
74
75 /* These are the file descriptors that are we are polling out of
76  * the run loop. (We keep the array around and reuse it to avoid
77  * constant allocations.)
78  */
79 #define RUN_LOOP_POLLFDS_INITIAL_SIZE 16
80 static GPollFD *run_loop_pollfds;
81 static guint run_loop_pollfds_size; /* Allocated size of the array */
82 static guint run_loop_n_pollfds;    /* Number of file descriptors in the array */
83
84 /******* Other global variables *******/
85
86 /* Since we count on replacing the GLib main loop poll function as our
87  * method of integrating Cocoa event handling into the GLib main loop
88  * we need to make sure that the poll function is always called even
89  * when there are no file descriptors that need to be polled. To do
90  * this, we add a dummy GPollFD to our event source with a file
91  * descriptor of '-1'. Then any time that GLib is polling the event
92  * source, it will call our poll function.
93  */
94 static GPollFD event_poll_fd;
95
96 /* Current NSEvents that we've gotten from Cocoa but haven't yet converted
97  * to GdkEvents. We wait until our dispatch() function to do the conversion
98  * since the conversion can conceivably cause signals to be emmitted
99  * or other things that shouldn't happen inside a poll function.
100  */
101 static GQueue *current_events;
102
103 /* The default poll function for GLib; we replace this with our own
104  * Cocoa-aware version and then call the old version to do actual
105  * file descriptor polling. There's no actual need to chain to the
106  * old one; we could reimplement the same functionality from scratch,
107  * but since the default implementation does the right thing, why
108  * bother.
109  */
110 static GPollFunc old_poll_func;
111
112 /* Reference to the run loop of the main thread. (There is a unique
113  * CFRunLoop per thread.)
114  */
115 static CFRunLoopRef main_thread_run_loop;
116
117 /* Normally the Cocoa main loop maintains an NSAutoReleasePool and frees
118  * it on every iteration. Since we are replacing the main loop we have
119  * to provide this functionality ourself. We free and replace the
120  * auto-release pool in our sources prepare() function.
121  */
122 static NSAutoreleasePool *autorelease_pool;
123
124 /* Flag when we've called nextEventMatchingMask ourself; this triggers
125  * a run loop iteration, so we need to detect that and avoid triggering
126  * our "run the GLib main looop while the run loop is active machinery.
127  */
128 static gint getting_events = 0;
129
130 /************************************************************
131  *********              Select Thread               *********
132  ************************************************************/
133
134 /* The states in our state machine, see comments in select_thread_func()
135  * for descriptiions of each state
136  */
137 typedef enum {
138   BEFORE_START,
139   WAITING,
140   POLLING_QUEUED,
141   POLLING_RESTART,
142   POLLING_DESCRIPTORS,
143 } SelectThreadState;
144
145 #ifdef G_ENABLE_DEBUG
146 static const char *const state_names[]  = {
147   "BEFORE_START",
148   "WAITING",
149   "POLLING_QUEUED",
150   "POLLING_RESTART",
151   "POLLING_DESCRIPTORS"
152 };
153 #endif
154
155 static SelectThreadState select_thread_state = BEFORE_START;
156
157 static pthread_t select_thread;
158 static pthread_mutex_t select_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
159 static pthread_cond_t select_thread_cond = PTHREAD_COND_INITIALIZER;
160
161 #define SELECT_THREAD_LOCK() pthread_mutex_lock (&select_thread_mutex)
162 #define SELECT_THREAD_UNLOCK() pthread_mutex_unlock (&select_thread_mutex)
163 #define SELECT_THREAD_SIGNAL() pthread_cond_signal (&select_thread_cond)
164 #define SELECT_THREAD_WAIT() pthread_cond_wait (&select_thread_cond, &select_thread_mutex)
165
166 /* These are the file descriptors that the select thread is currently
167  * polling.
168  */
169 static GPollFD *current_pollfds;
170 static guint current_n_pollfds;
171
172 /* These are the file descriptors that the select thread should pick
173  * up and start polling when it has a chance.
174  */
175 static GPollFD *next_pollfds;
176 static guint next_n_pollfds;
177
178 /* Pipe used to wake up the select thread */
179 static gint select_thread_wakeup_pipe[2];
180
181 /* Run loop source used to wake up the main thread */
182 static CFRunLoopSourceRef select_main_thread_source;
183
184 static void
185 select_thread_set_state (SelectThreadState new_state)
186 {
187   gboolean old_state;
188
189   if (select_thread_state == new_state)
190     return;
191
192   GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Select thread state: %s => %s\n", state_names[select_thread_state], state_names[new_state]));
193
194   old_state = select_thread_state;
195   select_thread_state = new_state;
196   if (old_state == WAITING && new_state != WAITING)
197     SELECT_THREAD_SIGNAL ();
198 }
199
200 static void
201 signal_main_thread (void)
202 {
203   GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Waking up main thread\n"));
204
205   /* If we are in nextEventMatchingMask, then we need to make sure an
206    * event gets queued, otherwise it's enough to simply wake up the
207    * main thread run loop
208    */
209   if (!run_loop_polling_async)
210     CFRunLoopSourceSignal (select_main_thread_source);
211
212   /* Don't check for CFRunLoopIsWaiting() here because it causes a
213    * race condition (the loop could go into waiting state right after
214    * we checked).
215    */
216   CFRunLoopWakeUp (main_thread_run_loop);
217 }
218
219 static void *
220 select_thread_func (void *arg)
221 {
222   char c;
223   
224   SELECT_THREAD_LOCK ();
225
226   while (TRUE)
227     {
228       switch (select_thread_state)
229         {
230         case BEFORE_START:
231           /* The select thread has not been started yet
232            */
233           g_assert_not_reached ();
234           
235         case WAITING:
236           /* Waiting for a set of file descriptors to be submitted by the main thread
237            *
238            *  => POLLING_QUEUED: main thread thread submits a set of file descriptors
239            */ 
240           SELECT_THREAD_WAIT ();
241           break;
242           
243         case POLLING_QUEUED:
244           /* Waiting for a set of file descriptors to be submitted by the main thread
245            *
246            *  => POLLING_DESCRIPTORS: select thread picks up the file descriptors to begin polling
247            */ 
248           if (current_pollfds)
249             g_free (current_pollfds);
250           
251           current_pollfds = next_pollfds;
252           current_n_pollfds = next_n_pollfds;
253
254           next_pollfds = NULL;
255           next_n_pollfds = 0;
256
257           select_thread_set_state (POLLING_DESCRIPTORS);
258           break;
259           
260         case POLLING_RESTART:
261           /* Select thread is currently polling a set of file descriptors, main thread has
262            * began a new iteration with the same set of file descriptors. We don't want to
263            * wake the select thread up and wait for it to restart immediately, but to avoid
264            * a race (described below in select_thread_start_polling()) we need to recheck after
265            * polling completes.
266            *
267            * => POLLING_DESCRIPTORS: select completes, main thread rechecks by polling again
268            * => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled
269            */
270           select_thread_set_state (POLLING_DESCRIPTORS);
271           break;
272
273         case POLLING_DESCRIPTORS:
274           /* In the process of polling the file descriptors
275            *
276            *  => WAITING: polling completes when a file descriptor becomes active
277            *  => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled
278            *  => POLLING_RESTART: main thread begins a new iteration with the same set file descriptors
279            */ 
280           SELECT_THREAD_UNLOCK ();
281           old_poll_func (current_pollfds, current_n_pollfds, -1);
282           SELECT_THREAD_LOCK ();
283
284           read (select_thread_wakeup_pipe[0], &c, 1);
285
286           if (select_thread_state == POLLING_DESCRIPTORS)
287             {
288               signal_main_thread ();
289               select_thread_set_state (WAITING);
290             }
291           break;
292         }
293     }
294 }
295
296 static void 
297 got_fd_activity (void *info)
298 {
299   NSEvent *event;
300
301   /* Post a message so we'll break out of the message loop */
302   event = [NSEvent otherEventWithType: NSApplicationDefined
303                              location: NSZeroPoint
304                         modifierFlags: 0
305                             timestamp: 0
306                          windowNumber: 0
307                               context: nil
308                               subtype: GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP
309                                 data1: 0 
310                                 data2: 0];
311
312   [NSApp postEvent:event atStart:YES];
313 }
314
315 static void
316 select_thread_start (void)
317 {
318   g_return_if_fail (select_thread_state == BEFORE_START);
319   
320   pipe (select_thread_wakeup_pipe);
321   fcntl (select_thread_wakeup_pipe[0], F_SETFL, O_NONBLOCK);
322
323   CFRunLoopSourceContext source_context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, got_fd_activity };
324   select_main_thread_source = CFRunLoopSourceCreate (NULL, 0, &source_context);
325   
326   CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopCommonModes);
327
328   select_thread_state = WAITING;
329   
330   while (TRUE)
331     {
332       if (pthread_create (&select_thread, NULL, select_thread_func, NULL) == 0)
333           break;
334
335       g_warning ("Failed to create select thread, sleeping and trying again");
336       sleep (1);
337     }
338 }
339
340 #ifdef G_ENABLE_DEBUG
341 static void
342 dump_poll_result (GPollFD *ufds,
343                   guint    nfds)
344 {
345   gint i;
346
347   for (i = 0; i < nfds; i++)
348     {
349       if (ufds[i].fd >= 0 && ufds[i].revents)
350         {
351           g_print (" %d:", ufds[i].fd);
352           if (ufds[i].revents & G_IO_IN)
353             g_print (" in");
354           if (ufds[i].revents & G_IO_OUT)
355             g_print (" out");
356           if (ufds[i].revents & G_IO_PRI)
357             g_print (" pri");
358           g_print ("\n");
359         }
360     }
361 }
362 #endif
363
364 gboolean
365 pollfds_equal (GPollFD *old_pollfds,
366                guint    old_n_pollfds,
367                GPollFD *new_pollfds,
368                guint    new_n_pollfds)
369 {
370   gint i;
371   
372   if (old_n_pollfds != new_n_pollfds)
373     return FALSE;
374
375   for (i = 0; i < old_n_pollfds; i++)
376     {
377       if (old_pollfds[i].fd != new_pollfds[i].fd ||
378           old_pollfds[i].events != new_pollfds[i].events)
379         return FALSE;
380     }
381
382   return TRUE;
383 }
384
385 /* Begins a polling operation with the specified GPollFD array; the 
386  * timeout is used only to tell if the polling operation is blocking
387  * or non-blocking.
388  *
389  * Return value:
390  *  -1: No file descriptors ready, began asynchronous poll
391  *   0: No file descriptors ready, asynchronous poll not needed
392  * > 0: Number of file descriptors ready
393  */
394 static gint
395 select_thread_start_poll (GPollFD *ufds,
396                           guint    nfds,                          gint     timeout)
397 {
398   gint n_ready;
399   gboolean have_new_pollfds = FALSE;
400   gint poll_fd_index = -1;
401   gint i;
402
403   for (i = 0; i < nfds; i++)
404     if (ufds[i].fd == -1)
405       {
406         poll_fd_index = i;
407         break;
408       }
409   
410   if (nfds == 0 ||
411       (nfds == 1 && poll_fd_index >= 0))
412     {
413       GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Nothing to poll\n"));
414       return 0;
415     }
416
417   /* If we went immediately to an async poll, then we might decide to
418    * dispatch idle functions when higher priority file descriptor sources
419    * are ready to be dispatched. So we always need to first check
420    * check synchronously with a timeout of zero, and only when no
421    * sources are immediately ready, go to the asynchronous poll.
422    *
423    * Of course, if the timeout passed in is 0, then the synchronous
424    * check is sufficient and we never need to do the asynchronous poll.
425    */
426   n_ready = old_poll_func (ufds, nfds, 0);
427   if (n_ready > 0 || timeout == 0)
428     {
429 #ifdef G_ENABLE_DEBUG
430       if ((_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) && n_ready > 0)
431         {
432           g_print ("EventLoop: Found ready file descriptors before waiting\n");
433           dump_poll_result (ufds, nfds);
434         }
435 #endif
436   
437       return n_ready;
438     }
439   
440   SELECT_THREAD_LOCK ();
441
442   if (select_thread_state == BEFORE_START)
443     {
444       select_thread_start ();
445     }
446   
447   if (select_thread_state == POLLING_QUEUED)
448     {
449       /* If the select thread hasn't picked up the set of file descriptors yet
450        * then we can simply replace an old stale set with a new set.
451        */
452       if (!pollfds_equal (ufds, nfds, next_pollfds, next_n_pollfds - 1))
453         {
454           g_free (next_pollfds);
455           next_pollfds = NULL;
456           next_n_pollfds = 0;
457           
458           have_new_pollfds = TRUE;
459         }
460     }
461   else if (select_thread_state == POLLING_RESTART || select_thread_state == POLLING_DESCRIPTORS)
462     {
463       /* If we are already in the process of polling the right set of file descriptors,
464        * there's no need for us to immediately force the select thread to stop polling
465        * and then restart again. And avoiding doing so increases the efficiency considerably
466        * in the common case where we have a set of basically inactive file descriptors that
467        * stay unchanged present as we process many events.
468        *
469        * However, we have to be careful that we don't hit the following race condition
470        *  Select Thread              Main Thread
471        *  -----------------          ---------------
472        *  Polling Completes
473        *                             Reads data or otherwise changes file descriptor state
474        *                             Checks if polling is current
475        *                             Does nothing (*)
476        *                             Releases lock
477        *  Acquires lock
478        *  Marks polling as complete
479        *  Wakes main thread
480        *                             Receives old stale file descriptor state
481        * 
482        * To avoid this, when the new set of poll descriptors is the same as the current
483        * one, we transition to the POLLING_RESTART stage at the point marked (*). When
484        * the select thread wakes up from the poll because a file descriptor is active, if
485        * the state is POLLING_RESTART it immediately begins polling same the file descriptor
486        * set again. This normally will just return the same set of active file descriptors
487        * as the first time, but in sequence described above will properly update the
488        * file descriptor state.
489        *
490        * Special case: this RESTART logic is not needed if the only FD is the internal GLib
491        * "wakeup pipe" that is presented when threads are initialized.
492        *
493        * P.S.: The harm in the above sequence is mostly that sources can be signalled
494        *   as ready when they are no longer ready. This may prompt a blocking read
495        *   from a file descriptor that hangs.
496        */
497       if (!pollfds_equal (ufds, nfds, current_pollfds, current_n_pollfds - 1))
498         have_new_pollfds = TRUE;
499       else
500         {
501           if (!((nfds == 1 && poll_fd_index < 0 && g_thread_supported ()) ||
502                 (nfds == 2 && poll_fd_index >= 0 && g_thread_supported ())))
503             select_thread_set_state (POLLING_RESTART);
504         }
505     }
506   else
507     have_new_pollfds = TRUE;
508
509   if (have_new_pollfds)
510     {
511       GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Submitting a new set of file descriptor to the select thread\n"));
512       
513       g_assert (next_pollfds == NULL);
514       
515       next_n_pollfds = nfds + 1;
516       next_pollfds = g_new (GPollFD, nfds + 1);
517       memcpy (next_pollfds, ufds, nfds * sizeof (GPollFD));
518   
519       next_pollfds[nfds].fd = select_thread_wakeup_pipe[0];
520       next_pollfds[nfds].events = G_IO_IN;
521   
522       if (select_thread_state != POLLING_QUEUED && select_thread_state != WAITING)
523         {
524           if (select_thread_wakeup_pipe[1])
525             {
526               char c = 'A';
527               write (select_thread_wakeup_pipe[1], &c, 1);
528             }
529         }
530       
531       select_thread_set_state (POLLING_QUEUED);
532     }
533   
534   SELECT_THREAD_UNLOCK ();
535
536   return -1;
537 }
538
539 /* End an asynchronous polling operation started with
540  * select_thread_collect_poll(). This must be called if and only if
541  * select_thread_start_poll() return -1. The GPollFD array passed
542  * in must be identical to the one passed to select_thread_start_poll().
543  *
544  * The results of the poll are written into the GPollFD array passed in.
545  *
546  * Return Value: number of file descriptors ready
547  */
548 static int
549 select_thread_collect_poll (GPollFD *ufds, guint nfds)
550 {
551   gint i;
552   gint n_ready = 0;
553   
554   SELECT_THREAD_LOCK ();
555
556   if (select_thread_state == WAITING) /* The poll completed */
557     {
558       for (i = 0; i < nfds; i++)
559         {
560           if (ufds[i].fd == -1)
561             continue;
562           
563           g_assert (ufds[i].fd == current_pollfds[i].fd);
564           g_assert (ufds[i].events == current_pollfds[i].events);
565
566           if (current_pollfds[i].revents)
567             {
568               ufds[i].revents = current_pollfds[i].revents;
569               n_ready++;
570             }
571         }
572       
573 #ifdef G_ENABLE_DEBUG
574       if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP)
575         {
576           g_print ("EventLoop: Found ready file descriptors after waiting\n");
577           dump_poll_result (ufds, nfds);
578         }
579 #endif
580     }
581
582   SELECT_THREAD_UNLOCK ();
583
584   return n_ready;
585 }
586
587 /************************************************************
588  *********             Main Loop Source             *********
589  ************************************************************/
590
591 gboolean
592 _gdk_quartz_event_loop_check_pending (void)
593 {
594   return current_events && current_events->head;
595 }
596
597 NSEvent*
598 _gdk_quartz_event_loop_get_pending (void)
599 {
600   NSEvent *event = NULL;
601
602   if (current_events)
603     event = g_queue_pop_tail (current_events);
604
605   return event;
606 }
607
608 void
609 _gdk_quartz_event_loop_release_event (NSEvent *event)
610 {
611   [event release];
612 }
613
614 static gboolean
615 gdk_event_prepare (GSource *source,
616                    gint    *timeout)
617 {
618   gboolean retval;
619
620   gdk_threads_enter ();
621   
622   *timeout = -1;
623
624   if (_gdk_display->event_pause_count > 0)
625     retval = FALSE;
626   else
627     retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
628               _gdk_quartz_event_loop_check_pending ());
629
630   gdk_threads_leave ();
631
632   return retval;
633 }
634
635 static gboolean
636 gdk_event_check (GSource *source)
637 {
638   gboolean retval;
639
640   gdk_threads_enter ();
641
642   if (_gdk_display->event_pause_count > 0)
643     retval = FALSE;
644   else
645     retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
646               _gdk_quartz_event_loop_check_pending ());
647
648   gdk_threads_leave ();
649
650   return retval;
651 }
652
653 static gboolean
654 gdk_event_dispatch (GSource     *source,
655                     GSourceFunc  callback,
656                     gpointer     user_data)
657 {
658   GdkEvent *event;
659
660   gdk_threads_enter ();
661
662   /* Refresh the autorelease pool if we're at the base CFRunLoop level
663    * (indicated by current_loop_level) and the base g_main_loop level
664    * (indicated by g_main_depth()). Messing with the autorelease pool at
665    * any level of nesting can cause access to deallocated memory because
666    * autorelease_pool is static and releasing a pool will cause all pools
667    * allocated inside of it to be released as well.
668    */
669   if (current_loop_level == 0 && g_main_depth() == 0)
670     {
671       if (autorelease_pool)
672         [autorelease_pool drain];
673
674       autorelease_pool = [[NSAutoreleasePool alloc] init];
675     }
676
677   _gdk_quartz_display_queue_events (_gdk_display);
678
679   event = _gdk_event_unqueue (_gdk_display);
680
681   if (event)
682     {
683       _gdk_event_emit (event);
684
685       gdk_event_free (event);
686     }
687
688   gdk_threads_leave ();
689
690   return TRUE;
691 }
692
693 static GSourceFuncs event_funcs = {
694   gdk_event_prepare,
695   gdk_event_check,
696   gdk_event_dispatch,
697   NULL
698 };
699
700 /************************************************************
701  *********             Our Poll Function            *********
702  ************************************************************/
703
704 static gint
705 poll_func (GPollFD *ufds,
706            guint    nfds,
707            gint     timeout_)
708 {
709   NSEvent *event;
710   NSDate *limit_date;
711   gint n_ready;
712
713   static GPollFD *last_ufds;
714
715   last_ufds = ufds;
716
717   n_ready = select_thread_start_poll (ufds, nfds, timeout_);
718   if (n_ready > 0)
719     timeout_ = 0;
720
721   if (timeout_ == -1)
722     limit_date = [NSDate distantFuture];
723   else if (timeout_ == 0)
724     limit_date = [NSDate distantPast];
725   else
726     limit_date = [NSDate dateWithTimeIntervalSinceNow:timeout_/1000.0];
727
728   getting_events++;
729   event = [NSApp nextEventMatchingMask: NSAnyEventMask
730                              untilDate: limit_date
731                                 inMode: NSDefaultRunLoopMode
732                                dequeue: YES];
733   getting_events--;
734
735   /* We check if last_ufds did not change since the time this function was
736    * called. It is possible that a recursive main loop (and thus recursive
737    * invocation of this poll function) is triggered while in
738    * nextEventMatchingMask:. If during that time new fds are added,
739    * the cached fds array might be replaced in g_main_context_iterate().
740    * So, we should avoid accessing the old fd array (still pointed at by
741    * ufds) here in that case, since it might have been freed. We avoid this
742    * by not calling the collect stage.
743    */
744   if (last_ufds == ufds && n_ready < 0)
745     n_ready = select_thread_collect_poll (ufds, nfds);
746       
747   if (event &&
748       [event type] == NSApplicationDefined &&
749       [event subtype] == GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP)
750     {
751       /* Just used to wake us up; if an event and a FD arrived at the same
752        * time; could have come from a previous iteration in some cases,
753        * but the spurious wake up is harmless if a little inefficient.
754        */
755       event = NULL;
756     }
757
758   if (event) 
759     {
760       if (!current_events)
761         current_events = g_queue_new ();
762       g_queue_push_head (current_events, [event retain]);
763     }
764
765   return n_ready;
766 }
767
768 /************************************************************
769  *********  Running the main loop out of CFRunLoop  *********
770  ************************************************************/
771
772 /* Wrapper around g_main_context_query() that handles reallocating
773  * run_loop_pollfds up to the proper size
774  */
775 static gint
776 query_main_context (GMainContext *context,
777                     int           max_priority,
778                     int          *timeout)
779 {
780   gint nfds;
781   
782   if (!run_loop_pollfds)
783     {
784       run_loop_pollfds_size = RUN_LOOP_POLLFDS_INITIAL_SIZE;
785       run_loop_pollfds = g_new (GPollFD, run_loop_pollfds_size);
786     }
787
788   while ((nfds = g_main_context_query (context, max_priority, timeout,
789                                        run_loop_pollfds, 
790                                        run_loop_pollfds_size)) > run_loop_pollfds_size)
791     {
792       g_free (run_loop_pollfds);
793       run_loop_pollfds_size = nfds;
794       run_loop_pollfds = g_new (GPollFD, nfds);
795     }
796
797   return nfds;
798 }
799
800 static void
801 run_loop_entry (void)
802 {
803   if (acquired_loop_level == -1)
804     {
805       if (g_main_context_acquire (NULL))
806         {
807           GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Beginning tracking run loop activity\n"));
808           acquired_loop_level = current_loop_level;
809         }
810       else
811         {
812           /* If we fail to acquire the main context, that means someone is iterating
813            * the main context in a different thread; we simply wait until this loop
814            * exits and then try again at next entry. In general, iterating the loop
815            * from a different thread is rare: it is only possible when GDK threading
816            * is initialized and is not frequently used even then. So, we hope that
817            * having GLib main loop iteration blocked in the combination of that and
818            * a native modal operation is a minimal problem. We could imagine using a
819            * thread that does g_main_context_wait() and then wakes us back up, but
820            * the gain doesn't seem worth the complexity.
821            */
822           GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Can't acquire main loop; skipping tracking run loop activity\n"));
823         }
824     }
825 }
826
827 static void
828 run_loop_before_timers (void)
829 {
830 }
831
832 static void
833 run_loop_before_sources (void)
834 {
835   GMainContext *context = g_main_context_default ();
836   gint max_priority;
837   gint nfds;
838
839   /* Before we let the CFRunLoop process sources, we want to check if there
840    * are any pending GLib main loop sources more urgent than
841    * G_PRIORITY_DEFAULT that need to be dispatched. (We consider all activity
842    * from the CFRunLoop to have a priority of G_PRIORITY_DEFAULT.) If no
843    * sources are processed by the CFRunLoop, then processing will continue
844    * on to the BeforeWaiting stage where we check for lower priority sources.
845    */
846   
847   g_main_context_prepare (context, &max_priority); 
848   max_priority = MIN (max_priority, G_PRIORITY_DEFAULT);
849
850   /* We ignore the timeout that query_main_context () returns since we'll
851    * always query again before waiting.
852    */
853   nfds = query_main_context (context, max_priority, NULL);
854
855   if (nfds)
856     old_poll_func (run_loop_pollfds, nfds, 0);
857   
858   if (g_main_context_check (context, max_priority, run_loop_pollfds, nfds))
859     {
860       GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Dispatching high priority sources\n"));
861       g_main_context_dispatch (context);
862     }
863 }
864
865 static void
866 dummy_timer_callback (CFRunLoopTimerRef  timer,
867                       void              *info)
868 {
869   /* Nothing; won't normally even be called */
870 }
871
872 static void
873 run_loop_before_waiting (void)
874 {
875   GMainContext *context = g_main_context_default ();
876   gint timeout;
877   gint n_ready;
878
879   /* At this point, the CFRunLoop is ready to wait. We start a GMain loop
880    * iteration by calling the check() and query() stages. We start a
881    * poll, and if it doesn't complete immediately we let the run loop
882    * go ahead and sleep. Before doing that, if there was a timeout from
883    * GLib, we set up a CFRunLoopTimer to wake us up.
884    */
885   
886   g_main_context_prepare (context, &run_loop_max_priority); 
887   
888   run_loop_n_pollfds = query_main_context (context, run_loop_max_priority, &timeout);
889
890   n_ready = select_thread_start_poll (run_loop_pollfds, run_loop_n_pollfds, timeout);
891
892   if (n_ready > 0 || timeout == 0)
893     {
894       /* We have stuff to do, no sleeping allowed! */
895       CFRunLoopWakeUp (main_thread_run_loop);
896     }
897   else if (timeout > 0)
898     {
899       /* We need to get the run loop to break out of its wait when our timeout
900        * expires. We do this by adding a dummy timer that we'll remove immediately
901        * after the wait wakes up.
902        */
903       GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Adding timer to wake us up in %d milliseconds\n", timeout));
904       
905       run_loop_timer = CFRunLoopTimerCreate (NULL, /* allocator */
906                                              CFAbsoluteTimeGetCurrent () + timeout / 1000.,
907                                              0, /* interval (0=does not repeat) */
908                                              0, /* flags */
909                                              0, /* order (priority) */
910                                              dummy_timer_callback,
911                                              NULL);
912
913       CFRunLoopAddTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes);
914     }
915   
916   run_loop_polling_async = n_ready < 0;
917 }
918
919 static void
920 run_loop_after_waiting (void)
921 {
922   GMainContext *context = g_main_context_default ();
923
924   /* After sleeping, we finish of the GMain loop iteratin started in before_waiting()
925    * by doing the check() and dispatch() stages.
926    */
927
928   if (run_loop_timer)
929     {
930       CFRunLoopRemoveTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes);
931       CFRelease (run_loop_timer);
932       run_loop_timer = NULL;
933     }
934   
935   if (run_loop_polling_async)
936     {
937       select_thread_collect_poll (run_loop_pollfds, run_loop_n_pollfds);
938       run_loop_polling_async = FALSE;
939     }
940   
941   if (g_main_context_check (context, run_loop_max_priority, run_loop_pollfds, run_loop_n_pollfds))
942     {
943       GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Dispatching after waiting\n"));
944       g_main_context_dispatch (context);
945     }
946 }
947
948 static void
949 run_loop_exit (void)
950 {
951   /* + 1 because we decrement current_loop_level separately in observer_callback() */
952   if ((current_loop_level + 1) == acquired_loop_level)
953     {
954       g_main_context_release (NULL);
955       acquired_loop_level = -1;
956       GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Ended tracking run loop activity\n"));
957     }
958 }
959
960 static void
961 run_loop_observer_callback (CFRunLoopObserverRef observer,
962                             CFRunLoopActivity    activity,
963                             void                *info)
964 {
965   switch (activity)
966     {
967     case kCFRunLoopEntry:
968       current_loop_level++;
969       break;
970     case kCFRunLoopExit:
971       g_return_if_fail (current_loop_level > 0);
972       current_loop_level--;
973       break;
974     default:
975       break;
976     }
977
978   if (getting_events > 0) /* Activity we triggered */
979     return;
980
981   switch (activity)
982     {
983     case kCFRunLoopEntry:
984       run_loop_entry ();
985       break;
986     case kCFRunLoopBeforeTimers:
987       run_loop_before_timers ();
988       break;
989     case kCFRunLoopBeforeSources:
990       run_loop_before_sources ();
991       break;
992     case kCFRunLoopBeforeWaiting:
993       run_loop_before_waiting ();
994       break;
995     case kCFRunLoopAfterWaiting:
996       run_loop_after_waiting ();
997       break;
998     case kCFRunLoopExit:
999       run_loop_exit ();
1000       break;
1001     default:
1002       break;
1003     }
1004 }
1005
1006 /************************************************************/
1007
1008 void
1009 _gdk_quartz_event_loop_init (void)
1010 {
1011   GSource *source;
1012   CFRunLoopObserverRef observer;
1013
1014   /* Hook into the GLib main loop */
1015
1016   event_poll_fd.events = G_IO_IN;
1017   event_poll_fd.fd = -1;
1018
1019   source = g_source_new (&event_funcs, sizeof (GSource));
1020   g_source_set_name (source, "GDK Quartz event source"); 
1021   g_source_add_poll (source, &event_poll_fd);
1022   g_source_set_priority (source, GDK_PRIORITY_EVENTS);
1023   g_source_set_can_recurse (source, TRUE);
1024   g_source_attach (source, NULL);
1025
1026   old_poll_func = g_main_context_get_poll_func (NULL);
1027   g_main_context_set_poll_func (NULL, poll_func);
1028   
1029   /* Hook into the the CFRunLoop for the main thread */
1030
1031   main_thread_run_loop = CFRunLoopGetCurrent ();
1032
1033   observer = CFRunLoopObserverCreate (NULL, /* default allocator */
1034                                       kCFRunLoopAllActivities,
1035                                       true, /* repeats: not one-shot */
1036                                       0, /* order (priority) */
1037                                       run_loop_observer_callback,
1038                                       NULL);
1039                                      
1040   CFRunLoopAddObserver (main_thread_run_loop, observer, kCFRunLoopCommonModes);
1041   
1042   /* Initialize our autorelease pool */
1043
1044   autorelease_pool = [[NSAutoreleasePool alloc] init];
1045 }