X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/9a0115abd18f219f234d6dd460cf7f5ed3c0332f..47199123698df3a14acb016c3869075b2d6012d5:/src/xgselect.c diff --git a/src/xgselect.c b/src/xgselect.c index 80dbfc32ae..4d90298a9d 100644 --- a/src/xgselect.c +++ b/src/xgselect.c @@ -1,6 +1,6 @@ /* Function for handling the GLib event loop. -Copyright (C) 2009-2012 Free Software Foundation, Inc. +Copyright (C) 2009-2013 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -15,56 +15,56 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU Emacs. If not, see . */ +along with GNU Emacs. If not, see . */ #include -#include #include "xgselect.h" -#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) +#ifdef HAVE_GLIB #include #include -#include - -static GPollFD *gfds; -static ptrdiff_t gfds_size; +#include "frame.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 (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds)); - else FD_ZERO (&all_rfds); - if (wfds) memcpy (&all_wfds, wfds, sizeof (all_rfds)); - else FD_ZERO (&all_wfds); + /* Do not try to optimize with an initial check with g_main_context_pending + and a call to pselect if it returns false. If Gdk has a timeout for 0.01 + second, and Emacs has a timeout for 1 second, g_main_context_pending will + return false, but the timeout will be 1 second, thus missing the gdk + timeout with a lot. */ - /* Update event sources in GLib. */ - g_main_context_pending (context); + context = g_main_context_default (); - do { - if (n_gfds > gfds_size) - { - xfree (gfds); - gfds = xpalloc (0, &gfds_size, n_gfds - gfds_size, INT_MAX, - sizeof *gfds); - } + if (rfds) all_rfds = *rfds; + else FD_ZERO (&all_rfds); + if (wfds) all_wfds = *wfds; + else FD_ZERO (&all_wfds); - 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) { @@ -81,30 +81,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)) { @@ -127,7 +122,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, @@ -148,13 +143,4 @@ 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 -} +#endif /* HAVE_GLIB */