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
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;
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)
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;
}
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)
{
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;
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;
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)
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
#include "xgselect.h"
#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
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;
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)