aboutsummaryrefslogtreecommitdiffstats
path: root/src/xgselect.c
diff options
context:
space:
mode:
authorPaul Eggert2014-04-22 14:32:51 -0700
committerPaul Eggert2014-04-22 14:32:51 -0700
commit42e910349d699ee3f8024371ca1e60e015fc6aa7 (patch)
treeba589f3f7c278671f0ae9c5c8f15c241ae8dd674 /src/xgselect.c
parent4f96579371290b201a973072a1c2f237755bb954 (diff)
parent34e856d5ac828753b7be20e2471f39fb613f7f40 (diff)
downloademacs-42e910349d699ee3f8024371ca1e60e015fc6aa7.tar.gz
emacs-42e910349d699ee3f8024371ca1e60e015fc6aa7.zip
Merge from emacs-24; up to 2014-04-22T20:19:17Z!eggert@cs.ucla.edu
Diffstat (limited to 'src/xgselect.c')
-rw-r--r--src/xgselect.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/xgselect.c b/src/xgselect.c
index 5f71ff84014..bf889a90e97 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -28,6 +28,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include <stdbool.h> 28#include <stdbool.h>
29#include <timespec.h> 29#include <timespec.h>
30#include "frame.h" 30#include "frame.h"
31#include "blockinput.h"
32
33/* `xg_select' is a `pselect' replacement. Why do we need a separate function?
34 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect
35 with a greater timeout then the one scheduled by Glib, we would
36 not allow Glib to process its timer events. We want Glib to
37 work smoothly, so we need to reduce our timeout to match Glib.
38 2. Descriptors. Glib may listen to more file descriptors than we do.
39 So we add Glib descriptors to our pselect pool, but we don't change
40 the value returned by the function. The return value matches only
41 the descriptors passed as arguments, making it compatible with
42 plain pselect. */
31 43
32int 44int
33xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, 45xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
@@ -47,12 +59,6 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
47 bool need_to_dispatch; 59 bool need_to_dispatch;
48 USE_SAFE_ALLOCA; 60 USE_SAFE_ALLOCA;
49 61
50 /* Do not try to optimize with an initial check with g_main_context_pending
51 and a call to pselect if it returns false. If Gdk has a timeout for 0.01
52 second, and Emacs has a timeout for 1 second, g_main_context_pending will
53 return false, but the timeout will be 1 second, thus missing the gdk
54 timeout with a lot. */
55
56 context = g_main_context_default (); 62 context = g_main_context_default ();
57 63
58 if (rfds) all_rfds = *rfds; 64 if (rfds) all_rfds = *rfds;
@@ -136,8 +142,13 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
136 if (need_to_dispatch) 142 if (need_to_dispatch)
137 { 143 {
138 int pselect_errno = errno; 144 int pselect_errno = errno;
145 /* Prevent g_main_dispatch recursion, that would occur without
146 block_input wrapper, because event handlers call
147 unblock_input. Event loop recursion was causing Bug#15801. */
148 block_input ();
139 while (g_main_context_pending (context)) 149 while (g_main_context_pending (context))
140 g_main_context_dispatch (context); 150 g_main_context_dispatch (context);
151 unblock_input ();
141 errno = pselect_errno; 152 errno = pselect_errno;
142 } 153 }
143 154