From: Gemini Lasswell Date: Sat, 3 Nov 2018 20:57:55 +0000 (-0700) Subject: Instrument file descriptor mask code (bug#33198) X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=40f179e2257c34ad7f424ef0912dd2c460e6d492;p=emacs.git Instrument file descriptor mask code (bug#33198) --- diff --git a/src/process.c b/src/process.c index 7e78e172d36..c273a4dfeaf 100644 --- a/src/process.c +++ b/src/process.c @@ -280,7 +280,7 @@ static void exec_sentinel (Lisp_Object, Lisp_Object); static int num_pending_connects; /* The largest descriptor currently in use; -1 if none. */ -static int max_desc; +int max_desc; /* Set the external socket descriptor for Emacs to use when `make-network-process' is called with a non-nil @@ -459,6 +459,8 @@ static struct fd_callback_data void add_read_fd (int fd, fd_callback func, void *data) { + fprintf(stderr, "add_read_fd %d (%p)\n", fd, current_thread); + add_keyboard_wait_descriptor (fd); fd_callback_info[fd].func = func; @@ -471,6 +473,8 @@ add_non_keyboard_read_fd (int fd) eassert (fd >= 0 && fd < FD_SETSIZE); eassert (fd_callback_info[fd].func == NULL); + fprintf(stderr, "add_non_keyboard_read_fd %d (%p)\n", fd, current_thread); + fd_callback_info[fd].flags &= ~KEYBOARD_FD; fd_callback_info[fd].flags |= FOR_READ; if (fd > max_desc) @@ -480,6 +484,8 @@ add_non_keyboard_read_fd (int fd) static void add_process_read_fd (int fd) { + fprintf(stderr, "add_process_read_fd %d (%p)\n", fd, current_thread); + add_non_keyboard_read_fd (fd); fd_callback_info[fd].flags |= PROCESS_FD; } @@ -489,6 +495,8 @@ add_process_read_fd (int fd) void delete_read_fd (int fd) { + fprintf(stderr, "delete_read_fd %d (%p)\n", fd, current_thread); + delete_keyboard_wait_descriptor (fd); if (fd_callback_info[fd].flags == 0) @@ -506,6 +514,8 @@ add_write_fd (int fd, fd_callback func, void *data) { eassert (fd >= 0 && fd < FD_SETSIZE); + fprintf(stderr, "add_write_fd %d (%p)\n", fd, current_thread); + fd_callback_info[fd].func = func; fd_callback_info[fd].data = data; fd_callback_info[fd].flags |= FOR_WRITE; @@ -519,6 +529,8 @@ add_non_blocking_write_fd (int fd) eassert (fd >= 0 && fd < FD_SETSIZE); eassert (fd_callback_info[fd].func == NULL); + fprintf(stderr, "add_non_blocking_write_fd %d (%p)\n", fd, current_thread); + fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD; if (fd > max_desc) max_desc = fd; @@ -545,6 +557,8 @@ recompute_max_desc (void) void delete_write_fd (int fd) { + fprintf(stderr, "delete_write_fd %d (%p)\n", fd, current_thread); + if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0) { if (--num_pending_connects < 0) diff --git a/src/xgselect.c b/src/xgselect.c index fedd3127ef3..cd7eadeadc2 100644 --- a/src/xgselect.c +++ b/src/xgselect.c @@ -18,6 +18,9 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ #include +#include +#include +#include #include "xgselect.h" @@ -29,6 +32,9 @@ along with GNU Emacs. If not, see . */ #include "blockinput.h" #include "systime.h" +extern void safe_debug_print (Lisp_Object); +extern int max_desc; + /* `xg_select' is a `pselect' replacement. Why do we need a separate function? 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect with a greater timeout then the one scheduled by Glib, we would @@ -45,6 +51,7 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timespec *timeout, sigset_t *sigmask) { fd_set all_rfds, all_wfds; + fd_set save_all_rfds, save_all_wfds; struct timespec tmo; struct timespec *tmop = timeout; @@ -113,12 +120,36 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, tmop = &tmo; } + save_all_rfds = all_rfds; + save_all_wfds = all_wfds; + fds_lim = max_fds + 1; nfds = thread_select (pselect, fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop, sigmask); if (nfds < 0) - retval = nfds; + { + retval = nfds; + if (errno == EBADF) + { + int fd; + fprintf (stderr, "EBADF in xg_select, thread = %p\n", + current_thread); + + for (fd = 0; fd <= max_desc; ++fd) + { + if (FD_ISSET (fd, &save_all_rfds) && + fcntl(fd, F_GETFL) < 0 && + errno == EBADF) + fprintf (stderr, "fd %d in save_all_rfds\n", fd); + if (FD_ISSET (fd, &save_all_wfds) && + fcntl(fd, F_GETFL) < 0 && + errno == EBADF) + fprintf (stderr, "fd %d in save_all_wfds\n", fd); + } + errno = EBADF; + } + } else if (nfds > 0) { for (i = 0; i < fds_lim; ++i)