X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/0bb2392728c10748f3376f8cef6d9ca53e29f464..d5e5e7b41166815a843148f2081d19bc14b628b2:/src/xgselect.c diff --git a/src/xgselect.c b/src/xgselect.c index 9ccdd37489..c161564a32 100644 --- a/src/xgselect.c +++ b/src/xgselect.c @@ -1,6 +1,6 @@ /* Function for handling the GLib event loop. -Copyright (C) 2009-2011 Free Software Foundation, Inc. +Copyright (C) 2009-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -19,53 +19,48 @@ along with GNU Emacs. If not, see . */ #include -#include #include "xgselect.h" #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) #include #include -#include - -static GPollFD *gfds; -static int gfds_size; +#include "xterm.h" int -xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, - EMACS_TIME *timeout) +xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, + EMACS_TIME *timeout, sigset_t *sigmask) { SELECT_TYPE all_rfds, all_wfds; EMACS_TIME tmo, *tmop = timeout; - GMainContext *context = g_main_context_default (); + GMainContext *context; int have_wfds = wfds != NULL; - int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0; + GPollFD gfds_buf[128]; + GPollFD *gfds = gfds_buf; + int gfds_size = sizeof gfds_buf / sizeof *gfds_buf; + int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; int i, nfds, tmo_in_millisec; + USE_SAFE_ALLOCA; + + if (! (x_in_use + && g_main_context_pending (context = g_main_context_default ()))) + return pselect (fds_lim, rfds, wfds, efds, timeout, sigmask); - if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds)); + if (rfds) all_rfds = *rfds; else FD_ZERO (&all_rfds); - if (wfds) memcpy (&all_wfds, wfds, sizeof (all_rfds)); + if (wfds) all_wfds = *wfds; else FD_ZERO (&all_wfds); - /* Update event sources in GLib. */ - g_main_context_pending (context); - - do { - if (n_gfds > gfds_size) - { - while (n_gfds > gfds_size) - gfds_size *= 2; - xfree (gfds); - gfds = xmalloc (sizeof (*gfds) * gfds_size); - } - - n_gfds = g_main_context_query (context, - G_PRIORITY_LOW, - &tmo_in_millisec, - gfds, - gfds_size); - } while (n_gfds > gfds_size); + n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, + gfds, gfds_size); + if (gfds_size < n_gfds) + { + SAFE_NALLOCA (gfds, sizeof *gfds, n_gfds); + gfds_size = n_gfds; + n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, + gfds, gfds_size); + } for (i = 0; i < n_gfds; ++i) { @@ -82,30 +77,25 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, } } + SAFE_FREE (); + if (tmo_in_millisec >= 0) { - EMACS_SET_SECS_USECS (tmo, tmo_in_millisec/1000, - 1000 * (tmo_in_millisec % 1000)); - if (!timeout) our_tmo = 1; - else - { - EMACS_TIME difference; - - EMACS_SUB_TIME (difference, tmo, *timeout); - if (EMACS_TIME_NEG_P (difference)) our_tmo = 1; - } - - if (our_tmo) tmop = &tmo; + tmo = make_emacs_time (tmo_in_millisec / 1000, + 1000 * 1000 * (tmo_in_millisec % 1000)); + if (!timeout || EMACS_TIME_LT (tmo, *timeout)) + tmop = &tmo; } - nfds = select (max_fds+1, &all_rfds, have_wfds ? &all_wfds : NULL, - efds, tmop); + fds_lim = max_fds + 1; + nfds = pselect (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, + efds, tmop, sigmask); if (nfds < 0) retval = nfds; else if (nfds > 0) { - for (i = 0; i < max_fds+1; ++i) + for (i = 0; i < fds_lim; ++i) { if (FD_ISSET (i, &all_rfds)) { @@ -128,7 +118,7 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, } } - if (our_fds > 0 || (nfds == 0 && our_tmo)) + if (our_fds > 0 || (nfds == 0 && tmop == &tmo)) { /* If Gtk+ is in use eventually gtk_main_iteration will be called, @@ -150,12 +140,3 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, return retval; } #endif /* USE_GTK || HAVE_GCONF || HAVE_GSETTINGS */ - -void -xgselect_initialize (void) -{ -#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) - gfds_size = 128; - gfds = xmalloc (sizeof (*gfds)*gfds_size); -#endif -}