emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r101633: Add fd handling with callbac


From: Jan D
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r101633: Add fd handling with callbacks to select, dbus needs it for async operation.
Date: Sun, 26 Sep 2010 18:20:01 +0200
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 101633
committer: Jan D <address@hidden>
branch nick: trunk
timestamp: Sun 2010-09-26 18:20:01 +0200
message:
  Add fd handling with callbacks to select, dbus needs it for async operation.
  
  * src/dbusbind.c: Include process.h.
  (dbus_fd_cb, xd_find_watch_fd, xd_toggle_watch)
  (xd_read_message_1): New functions.
  (xd_add_watch, xd_remove_watch): Call xd_find_watch_fd.  Handle
  watch for both read and write.
  (Fdbus_init_bus): Also register xd_toggle_watch.
  (Fdbus_call_method_asynchronously, Fdbus_method_return_internal)
  (Fdbus_method_error_internal, Fdbus_send_signal): Remove call
  to dbus_connection_flush.
  (xd_read_message):  Move most of the code to xd_read_message_1.
  Call xd_read_message_1 until status is COMPLETE.
  
  * src/keyboard.c (readable_events, gobble_input): Remove DBUS code.
  
  * src/process.c (gpm_wait_mask, max_gpm_desc): Remove.
  (write_mask): New variable.
  (max_input_desc): Renamed from max_keyboard_desc.
  (fd_callback_info): New variable.
  (add_read_fd, delete_read_fd, add_write_fd, delete_write_fd): New
  functions.
  (Fmake_network_process): FD_SET write_mask.
  (deactivate_process): FD_CLR write_mask.
  (wait_reading_process_output): Connecting renamed to Writeok.
  check_connect removed.  check_write is new.  Remove references to
  gpm.  Use Writeok/check_write unconditionally (i.e. no #ifdef
  NON_BLOCKING_CONNECT) instead of Connecting.
  Loop over file descriptors and call callbacks in fd_callback_info
  if file descriptor is ready for I/O.
  (add_gpm_wait_descriptor): Just call add_keyboard_wait_descriptor.
  (delete_gpm_wait_descriptor): Just call delete_keyboard_wait_descriptor.
  (keyboard_bit_set): Use max_input_desc.
  (add_keyboard_wait_descriptor, delete_keyboard_wait_descriptor): Remove
  #ifdef subprocesses. Use max_input_desc.
  (init_process): Initialize write_mask and fd_callback_info.
  
  * src/process.h (add_read_fd, delete_read_fd, add_write_fd)
  (delete_write_fd): Declare.
modified:
  src/ChangeLog
  src/dbusbind.c
  src/keyboard.c
  src/process.c
  src/process.h
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2010-09-26 15:06:21 +0000
+++ b/src/ChangeLog     2010-09-26 16:20:01 +0000
@@ -1,3 +1,43 @@
+2010-09-26  Jan Djärv  <address@hidden>
+
+       * process.h (add_read_fd, delete_read_fd, add_write_fd)
+       (delete_write_fd): Declare.
+
+       * process.c (gpm_wait_mask, max_gpm_desc): Remove.
+       (write_mask): New variable.
+       (max_input_desc): Renamed from max_keyboard_desc.
+       (fd_callback_info): New variable.
+       (add_read_fd, delete_read_fd, add_write_fd, delete_write_fd): New
+       functions.
+       (Fmake_network_process): FD_SET write_mask.
+       (deactivate_process): FD_CLR write_mask.
+       (wait_reading_process_output): Connecting renamed to Writeok.
+       check_connect removed.  check_write is new.  Remove references to
+       gpm.  Use Writeok/check_write unconditionally (i.e. no #ifdef
+       NON_BLOCKING_CONNECT) instead of Connecting.
+       Loop over file descriptors and call callbacks in fd_callback_info
+       if file descriptor is ready for I/O.
+       (add_gpm_wait_descriptor): Just call add_keyboard_wait_descriptor.
+       (delete_gpm_wait_descriptor): Just call delete_keyboard_wait_descriptor.
+       (keyboard_bit_set): Use max_input_desc.
+       (add_keyboard_wait_descriptor, delete_keyboard_wait_descriptor): Remove
+       #ifdef subprocesses. Use max_input_desc.
+       (init_process): Initialize write_mask and fd_callback_info.
+
+       * keyboard.c (readable_events, gobble_input): Remove DBUS code.
+
+       * dbusbind.c: Include process.h.
+       (dbus_fd_cb, xd_find_watch_fd, xd_toggle_watch)
+       (xd_read_message_1): New functions.
+       (xd_add_watch, xd_remove_watch): Call xd_find_watch_fd.  Handle
+       watch for both read and write.
+       (Fdbus_init_bus): Also register xd_toggle_watch.
+       (Fdbus_call_method_asynchronously, Fdbus_method_return_internal)
+       (Fdbus_method_error_internal, Fdbus_send_signal): Remove call
+       to dbus_connection_flush.
+       (xd_read_message):  Move most of the code to xd_read_message_1.
+       Call xd_read_message_1 until status is COMPLETE.
+
 2010-09-26  Dan Nicolaescu  <address@hidden>
 
        * term.c: Do not include sys/ioctl.h, not needed.

=== modified file 'src/dbusbind.c'
--- a/src/dbusbind.c    2010-08-23 13:02:00 +0000
+++ b/src/dbusbind.c    2010-09-26 16:20:01 +0000
@@ -27,6 +27,7 @@
 #include "frame.h"
 #include "termhooks.h"
 #include "keyboard.h"
+#include "process.h"
 
 
 /* Subroutines.  */
@@ -799,71 +800,93 @@
   return connection;
 }
 
-
-/* Add connection file descriptor to input_wait_mask, in order to
-   let select() detect, whether a new message has been arrived.  */
-dbus_bool_t
+/* Callback called when something is read to read ow write.  */
+
+static void
+dbus_fd_cb (int fd, void *data, int for_read)
+{
+  xd_read_queued_messages ();
+}
+
+/* Return the file descriptor for WATCH, -1 if not found.  */
+
+static int
+xd_find_watch_fd (DBusWatch *watch)
+{
+#if HAVE_DBUS_WATCH_GET_UNIX_FD
+  /* TODO: Reverse these on Win32, which prefers the opposite.  */
+  int fd = dbus_watch_get_unix_fd (watch);
+  if (fd == -1)
+    fd = dbus_watch_get_socket (watch);
+#else
+  int fd = dbus_watch_get_fd (watch);
+#endif
+  return fd;
+}
+
+
+/* Start monitoring WATCH for possible I/O.  */
+
+static dbus_bool_t
 xd_add_watch (DBusWatch *watch, void *data)
 {
-  /* We check only for incoming data.  */
-  if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
+  unsigned int flags = dbus_watch_get_flags (watch);
+  int fd = xd_find_watch_fd (watch);
+
+  XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
+                    fd, flags & DBUS_WATCH_WRITABLE,
+                    dbus_watch_get_enabled (watch));
+
+  if (fd == -1)
+    return FALSE;
+
+  if (dbus_watch_get_enabled (watch))
     {
-#if HAVE_DBUS_WATCH_GET_UNIX_FD
-      /* TODO: Reverse these on Win32, which prefers the opposite.  */
-      int fd = dbus_watch_get_unix_fd(watch);
-      if (fd == -1)
-       fd = dbus_watch_get_socket(watch);
-#else
-      int fd = dbus_watch_get_fd(watch);
-#endif
-      XD_DEBUG_MESSAGE ("fd %d", fd);
-
-      if (fd == -1)
-       return FALSE;
-
-      /* Add the file descriptor to input_wait_mask.  */
-      add_keyboard_wait_descriptor (fd);
+      if (flags & DBUS_WATCH_WRITABLE)
+        add_write_fd (fd, dbus_fd_cb, NULL);
+      if (flags & DBUS_WATCH_READABLE)
+        add_read_fd (fd, dbus_fd_cb, NULL);
     }
-
-  /* Return.  */
   return TRUE;
 }
 
-/* Remove connection file descriptor from input_wait_mask.  DATA is
-   the used bus, either a string or QCdbus_system_bus or
+/* Stop monitoring WATCH for possible I/O.
+   DATA is the used bus, either a string or QCdbus_system_bus or
    QCdbus_session_bus.  */
-void
+
+static void
 xd_remove_watch (DBusWatch *watch, void *data)
 {
-  /* We check only for incoming data.  */
-  if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
+  unsigned int flags = dbus_watch_get_flags (watch);
+  int fd = xd_find_watch_fd (watch);
+
+  XD_DEBUG_MESSAGE ("fd %d", fd);
+
+  if (fd == -1) return;
+
+
+  /* Unset session environment.  */
+  if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
     {
-#if HAVE_DBUS_WATCH_GET_UNIX_FD
-      /* TODO: Reverse these on Win32, which prefers the opposite.  */
-      int fd = dbus_watch_get_unix_fd(watch);
-      if (fd == -1)
-       fd = dbus_watch_get_socket(watch);
-#else
-      int fd = dbus_watch_get_fd(watch);
-#endif
-      XD_DEBUG_MESSAGE ("fd %d", fd);
-
-      if (fd == -1)
-       return;
-
-      /* Unset session environment.  */
-      if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus)))
-       {
-         XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
-         unsetenv ("DBUS_SESSION_BUS_ADDRESS");
-       }
-
-      /* Remove the file descriptor from input_wait_mask.  */
-      delete_keyboard_wait_descriptor (fd);
+      XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
+      unsetenv ("DBUS_SESSION_BUS_ADDRESS");
     }
 
-  /* Return.  */
-  return;
+  if (flags & DBUS_WATCH_WRITABLE)
+    delete_write_fd (fd);
+  if (flags & DBUS_WATCH_READABLE)
+    delete_read_fd (fd);
+}
+
+/* Toggle monitoring WATCH for possible I/O.  */
+
+static void
+xd_toggle_watch (DBusWatch *watch, void *data)
+{
+  if (dbus_watch_get_enabled (watch))
+    xd_add_watch (watch, data);
+  else
+    xd_remove_watch (watch, data);
 }
 
 DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
@@ -880,7 +903,8 @@
   if (!dbus_connection_set_watch_functions (connection,
                                            xd_add_watch,
                                            xd_remove_watch,
-                                           NULL, (void*) XHASH (bus), NULL))
+                                            xd_toggle_watch,
+                                           (void*) XHASH (bus), NULL))
     XD_SIGNAL1 (build_string ("Cannot add watch functions"));
 
   /* Add bus to list of registered buses.  */
@@ -1288,9 +1312,6 @@
       result = Qnil;
     }
 
-  /* Flush connection to ensure the message is handled.  */
-  dbus_connection_flush (connection);
-
   XD_DEBUG_MESSAGE ("Message sent");
 
   /* Cleanup.  */
@@ -1379,9 +1400,6 @@
   if (!dbus_connection_send (connection, dmessage, NULL))
     XD_SIGNAL1 (build_string ("Cannot send message"));
 
-  /* Flush connection to ensure the message is handled.  */
-  dbus_connection_flush (connection);
-
   XD_DEBUG_MESSAGE ("Message sent");
 
   /* Cleanup.  */
@@ -1471,9 +1489,6 @@
   if (!dbus_connection_send (connection, dmessage, NULL))
     XD_SIGNAL1 (build_string ("Cannot send message"));
 
-  /* Flush connection to ensure the message is handled.  */
-  dbus_connection_flush (connection);
-
   XD_DEBUG_MESSAGE ("Message sent");
 
   /* Cleanup.  */
@@ -1589,9 +1604,6 @@
   if (!dbus_connection_send (connection, dmessage, NULL))
     XD_SIGNAL1 (build_string ("Cannot send message"));
 
-  /* Flush connection to ensure the message is handled.  */
-  dbus_connection_flush (connection);
-
   XD_DEBUG_MESSAGE ("Signal sent");
 
   /* Cleanup.  */
@@ -1645,32 +1657,27 @@
   return FALSE;
 }
 
-/* Read queued incoming message of the D-Bus BUS.  BUS is either a
-   Lisp symbol, :system or :session, or a string denoting the bus
-   address.  */
-static Lisp_Object
-xd_read_message (Lisp_Object bus)
+/* Read one queued incoming message of the D-Bus BUS.
+   BUS is either a Lisp symbol, :system or :session, or a string denoting
+   the bus address.  */
+
+static void
+xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
 {
   Lisp_Object args, key, value;
   struct gcpro gcpro1;
   struct input_event event;
-  DBusConnection *connection;
   DBusMessage *dmessage;
   DBusMessageIter iter;
   unsigned int dtype;
   int mtype, serial;
   const char *uname, *path, *interface, *member;
 
-  /* Open a connection to the bus.  */
-  connection = xd_initialize (bus, TRUE);
-
-  /* Non blocking read of the next available message.  */
-  dbus_connection_read_write (connection, 0);
   dmessage = dbus_connection_pop_message (connection);
 
   /* Return if there is no queued message.  */
   if (dmessage == NULL)
-    return Qnil;
+    return;
 
   /* Collect the parameters.  */
   args = Qnil;
@@ -1801,7 +1808,26 @@
  cleanup:
   dbus_message_unref (dmessage);
 
-  RETURN_UNGCPRO (Qnil);
+  UNGCPRO;
+}
+
+/* Read queued incoming messages of the D-Bus BUS.
+   BUS is either a Lisp symbol, :system or :session, or a string denoting
+   the bus address.  */
+
+static Lisp_Object
+xd_read_message (Lisp_Object bus)
+{
+  /* Open a connection to the bus.  */
+  DBusConnection *connection = xd_initialize (bus, TRUE);
+
+  /* Non blocking read of the next available message.  */
+  dbus_connection_read_write (connection, 0);
+
+  while (dbus_connection_get_dispatch_status (connection)
+         != DBUS_DISPATCH_COMPLETE)
+    xd_read_message_1 (connection, bus);
+  return Qnil;
 }
 
 /* Read queued incoming messages from all buses.  */

=== modified file 'src/keyboard.c'
--- a/src/keyboard.c    2010-09-25 12:04:35 +0000
+++ b/src/keyboard.c    2010-09-26 16:20:01 +0000
@@ -3522,12 +3522,6 @@
 static int
 readable_events (int flags)
 {
-#ifdef HAVE_DBUS
-  /* Check whether a D-Bus message has arrived.  */
-  if (xd_pending_messages () > 0)
-    return 1;
-#endif /* HAVE_DBUS */
-
   if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
     timer_check (1);
 
@@ -6877,11 +6871,6 @@
 void
 gobble_input (int expected)
 {
-#ifdef HAVE_DBUS
-  /* Read D-Bus messages.  */
-  xd_read_queued_messages ();
-#endif /* HAVE_DBUS */
-
 #ifdef SIGIO
   if (interrupt_input)
     {

=== modified file 'src/process.c'
--- a/src/process.c     2010-09-26 06:06:28 +0000
+++ b/src/process.c     2010-09-26 16:20:01 +0000
@@ -294,9 +294,9 @@
 
 static SELECT_TYPE non_process_wait_mask;
 
-/* Mask for the gpm mouse input descriptor.  */
+/* Mask for selecting for write.  */
 
-static SELECT_TYPE gpm_wait_mask;
+static SELECT_TYPE write_mask;
 
 #ifdef NON_BLOCKING_CONNECT
 /* Mask of bits indicating the descriptors that we wait for connect to
@@ -316,11 +316,8 @@
 /* The largest descriptor currently in use for a process object.  */
 static int max_process_desc;
 
-/* The largest descriptor currently in use for keyboard input.  */
-static int max_keyboard_desc;
-
-/* The largest descriptor currently in use for gpm mouse input.  */
-static int max_gpm_desc;
+/* The largest descriptor currently in use for input.  */
+static int max_input_desc;
 
 /* Indexed by descriptor, gives the process (if any) for that descriptor */
 Lisp_Object chan_process[MAXDESC];
@@ -366,6 +363,90 @@
 static char pty_name[24];
 #endif
 
+
+struct fd_callback_data
+{
+  fd_callback func;
+  void *data;
+#define FOR_READ  1
+#define FOR_WRITE 2
+  int condition; /* mask of the defines above.  */
+} fd_callback_info[MAXDESC];
+
+
+/* Add a file descriptor FD to be monitored for when read is possible.
+   When read is possible, call FUNC with argument DATA.  */
+
+void
+add_read_fd (int fd, fd_callback func, void *data)
+{
+  xassert (fd < MAXDESC);
+  add_keyboard_wait_descriptor (fd);
+
+  fd_callback_info[fd].func = func;
+  fd_callback_info[fd].data = data;
+  fd_callback_info[fd].condition |= FOR_READ;
+}
+
+/* Stop monitoring file descriptor FD for when read is possible.  */
+
+void
+delete_read_fd (int fd)
+{
+  xassert (fd < MAXDESC);
+  delete_keyboard_wait_descriptor (fd);
+
+  fd_callback_info[fd].condition &= ~FOR_READ;
+  if (fd_callback_info[fd].condition == 0)
+    {
+      fd_callback_info[fd].func = 0;
+      fd_callback_info[fd].data = 0;
+    }
+}
+
+/* Add a file descriptor FD to be monitored for when write is possible.
+   When write is possible, call FUNC with argument DATA.  */
+
+void
+add_write_fd (int fd, fd_callback func, void *data)
+{
+  xassert (fd < MAXDESC);
+  FD_SET (fd, &write_mask);
+  if (fd > max_input_desc)
+    max_input_desc = fd;
+
+  fd_callback_info[fd].func = func;
+  fd_callback_info[fd].data = data;
+  fd_callback_info[fd].condition |= FOR_WRITE;
+}
+
+/* Stop monitoring file descriptor FD for when write is possible.  */
+
+void
+delete_write_fd (int fd)
+{
+  int lim = max_input_desc;
+
+  xassert (fd < MAXDESC);
+  FD_CLR (fd, &write_mask);
+  fd_callback_info[fd].condition &= ~FOR_WRITE;
+  if (fd_callback_info[fd].condition == 0)
+    {
+      fd_callback_info[fd].func = 0;
+      fd_callback_info[fd].data = 0;
+
+      if (fd == max_input_desc)
+        for (fd = lim; fd >= 0; fd--)
+          if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
+            {
+              max_input_desc = fd;
+              break;
+            }
+      
+    }
+}
+
+
 /* Compute the Lisp form of the process status, p->status, from
    the numeric status that was returned by `wait'.  */
 
@@ -3620,6 +3701,7 @@
       if (!FD_ISSET (inch, &connect_wait_mask))
        {
          FD_SET (inch, &connect_wait_mask);
+         FD_SET (inch, &write_mask);
          num_pending_connects++;
        }
     }
@@ -4023,6 +4105,7 @@
       if (FD_ISSET (inchannel, &connect_wait_mask))
        {
          FD_CLR (inchannel, &connect_wait_mask);
+         FD_CLR (inchannel, &write_mask);
          if (--num_pending_connects < 0)
            abort ();
        }
@@ -4401,10 +4484,8 @@
 {
   register int channel, nfds;
   SELECT_TYPE Available;
-#ifdef NON_BLOCKING_CONNECT
-  SELECT_TYPE Connecting;
-  int check_connect;
-#endif
+  SELECT_TYPE Writeok;
+  int check_write;
   int check_delay, no_avail;
   int xerrno;
   Lisp_Object proc;
@@ -4414,9 +4495,7 @@
   int count = SPECPDL_INDEX ();
 
   FD_ZERO (&Available);
-#ifdef NON_BLOCKING_CONNECT
-  FD_ZERO (&Connecting);
-#endif
+  FD_ZERO (&Writeok);
 
   if (time_limit == 0 && microsecs == 0 && wait_proc && !NILP (Vinhibit_quit)
       && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit)))
@@ -4552,19 +4631,16 @@
       if (update_tick != process_tick)
        {
          SELECT_TYPE Atemp;
-#ifdef NON_BLOCKING_CONNECT
          SELECT_TYPE Ctemp;
-#endif
 
           if (kbd_on_hold_p ())
             FD_ZERO (&Atemp);
           else
             Atemp = input_wait_mask;
-         IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
+         Ctemp = write_mask;
 
          EMACS_SET_SECS_USECS (timeout, 0, 0);
-         if ((select (max (max (max_process_desc, max_keyboard_desc),
-                             max_gpm_desc) + 1,
+         if ((select (max (max_process_desc, max_input_desc) + 1,
                       &Atemp,
 #ifdef NON_BLOCKING_CONNECT
                       (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
@@ -4635,13 +4711,13 @@
            break;
          FD_SET (wait_proc->infd, &Available);
          check_delay = 0;
-         IF_NON_BLOCKING_CONNECT (check_connect = 0);
+          check_write = 0;
        }
       else if (!NILP (wait_for_cell))
        {
          Available = non_process_wait_mask;
          check_delay = 0;
-         IF_NON_BLOCKING_CONNECT (check_connect = 0);
+         check_write = 0;
        }
       else
        {
@@ -4649,7 +4725,8 @@
            Available = non_keyboard_wait_mask;
          else
            Available = input_wait_mask;
-         IF_NON_BLOCKING_CONNECT (check_connect = (num_pending_connects > 0));
+          Writeok = write_mask;
+          check_write = 1;
          check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
        }
 
@@ -4674,10 +4751,6 @@
        }
       else
        {
-#ifdef NON_BLOCKING_CONNECT
-         if (check_connect)
-           Connecting = connect_wait_mask;
-#endif
 
 #ifdef ADAPTIVE_READ_BUFFERING
          /* Set the timeout for adaptive read buffering if any
@@ -4719,15 +4792,10 @@
 #else
          nfds = select
 #endif
-                       (max (max (max_process_desc, max_keyboard_desc),
-                             max_gpm_desc) + 1,
-                        &Available,
-#ifdef NON_BLOCKING_CONNECT
-                        (check_connect ? &Connecting : (SELECT_TYPE *)0),
-#else
-                        (SELECT_TYPE *)0,
-#endif
-                        (SELECT_TYPE *)0, &timeout);
+            (max (max_process_desc, max_input_desc) + 1,
+             &Available,
+             (check_write ? &Writeok : (SELECT_TYPE *)0),
+             (SELECT_TYPE *)0, &timeout);
        }
 
       xerrno = errno;
@@ -4767,7 +4835,7 @@
       if (no_avail)
        {
          FD_ZERO (&Available);
-         IF_NON_BLOCKING_CONNECT (check_connect = 0);
+         check_write = 0;
        }
 
 #if 0 /* When polling is used, interrupt_input is 0,
@@ -4863,12 +4931,26 @@
       if (no_avail || nfds == 0)
        continue;
 
+      for (channel = 0; channel <= max_input_desc; ++channel)
+        {
+          struct fd_callback_data *d = &fd_callback_info[channel];
+          if (FD_ISSET (channel, &Available)
+              && d->func != 0
+              && (d->condition & FOR_READ) != 0)
+            d->func (channel, d->data, 1);
+          if (FD_ISSET (channel, &write_mask)
+              && d->func != 0
+              && (d->condition & FOR_WRITE) != 0)
+            d->func (channel, d->data, 0);
+          }
+
       /* Really FIRST_PROC_DESC should be 0 on Unix,
         but this is safer in the short run.  */
       for (channel = 0; channel <= max_process_desc; channel++)
        {
          if (FD_ISSET (channel, &Available)
-             && FD_ISSET (channel, &non_keyboard_wait_mask))
+             && FD_ISSET (channel, &non_keyboard_wait_mask)
+              && !FD_ISSET (channel, &non_process_wait_mask))
            {
              int nread;
 
@@ -4973,7 +5055,7 @@
                }
            }
 #ifdef NON_BLOCKING_CONNECT
-         if (check_connect && FD_ISSET (channel, &Connecting)
+         if (FD_ISSET (channel, &Writeok)
              && FD_ISSET (channel, &connect_wait_mask))
            {
              struct Lisp_Process *p;
@@ -6745,35 +6827,16 @@
 
 
 
-static int add_gpm_wait_descriptor_called_flag;
-
 void
 add_gpm_wait_descriptor (int desc)
 {
-  if (! add_gpm_wait_descriptor_called_flag)
-    FD_CLR (0, &input_wait_mask);
-  add_gpm_wait_descriptor_called_flag = 1;
-  FD_SET (desc, &input_wait_mask);
-  FD_SET (desc, &gpm_wait_mask);
-  if (desc > max_gpm_desc)
-    max_gpm_desc = desc;
+  add_keyboard_wait_descriptor (desc);
 }
 
 void
 delete_gpm_wait_descriptor (int desc)
 {
-  int fd;
-  int lim = max_gpm_desc;
-
-  FD_CLR (desc, &input_wait_mask);
-  FD_CLR (desc, &non_process_wait_mask);
-
-  if (desc == max_gpm_desc)
-    for (fd = 0; fd < lim; fd++)
-      if (FD_ISSET (fd, &input_wait_mask)
-         && !FD_ISSET (fd, &non_keyboard_wait_mask)
-         && !FD_ISSET (fd, &non_process_wait_mask))
-       max_gpm_desc = fd;
+  delete_keyboard_wait_descriptor (desc);
 }
 
 /* Return nonzero if *MASK has a bit set
@@ -6784,7 +6847,7 @@
 {
   int fd;
 
-  for (fd = 0; fd <= max_keyboard_desc; fd++)
+  for (fd = 0; fd <= max_input_desc; fd++)
     if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask)
        && !FD_ISSET (fd, &non_keyboard_wait_mask))
       return 1;
@@ -7023,12 +7086,10 @@
 void
 add_keyboard_wait_descriptor (int desc)
 {
-#ifdef subprocesses
   FD_SET (desc, &input_wait_mask);
   FD_SET (desc, &non_process_wait_mask);
-  if (desc > max_keyboard_desc)
-    max_keyboard_desc = desc;
-#endif
+  if (desc > max_input_desc)
+    max_input_desc = desc;
 }
 
 /* From now on, do not expect DESC to give keyboard input.  */
@@ -7036,20 +7097,16 @@
 void
 delete_keyboard_wait_descriptor (int desc)
 {
-#ifdef subprocesses
   int fd;
-  int lim = max_keyboard_desc;
+  int lim = max_input_desc;
 
   FD_CLR (desc, &input_wait_mask);
   FD_CLR (desc, &non_process_wait_mask);
 
-  if (desc == max_keyboard_desc)
+  if (desc == max_input_desc)
     for (fd = 0; fd < lim; fd++)
-      if (FD_ISSET (fd, &input_wait_mask)
-         && !FD_ISSET (fd, &non_keyboard_wait_mask)
-         && !FD_ISSET (fd, &gpm_wait_mask))
-       max_keyboard_desc = fd;
-#endif /* subprocesses */
+      if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
+        max_input_desc = fd;
 }
 
 /* Setup coding systems of PROCESS.  */
@@ -7306,7 +7363,9 @@
   FD_ZERO (&input_wait_mask);
   FD_ZERO (&non_keyboard_wait_mask);
   FD_ZERO (&non_process_wait_mask);
+  FD_ZERO (&write_mask);
   max_process_desc = 0;
+  memset (fd_callback_info, 0, sizeof (fd_callback_info));
 
 #ifdef NON_BLOCKING_CONNECT
   FD_ZERO (&connect_wait_mask);

=== modified file 'src/process.h'
--- a/src/process.h     2010-09-26 06:06:28 +0000
+++ b/src/process.h     2010-09-26 16:20:01 +0000
@@ -192,5 +192,12 @@
 extern void unhold_keyboard_input (void);
 extern int kbd_on_hold_p (void);
 
+typedef void (*fd_callback)(int fd, void *data, int for_read);
+
+extern void add_read_fd (int fd, fd_callback func, void *data);
+extern void delete_read_fd (int fd);
+extern void add_write_fd (int fd, fd_callback func, void *data);
+extern void delete_write_fd (int fd);
+
 /* arch-tag: dffedfc4-d7bc-4b58-a26f-c16155449c72
    (do not change this comment) */


reply via email to

[Prev in Thread] Current Thread [Next in Thread]