diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 40 | ||||
| -rw-r--r-- | src/dbusbind.c | 170 | ||||
| -rw-r--r-- | src/keyboard.c | 11 | ||||
| -rw-r--r-- | src/process.c | 203 | ||||
| -rw-r--r-- | src/process.h | 7 |
5 files changed, 276 insertions, 155 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3b80698932c..9474066af76 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,43 @@ | |||
| 1 | 2010-09-26 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * process.h (add_read_fd, delete_read_fd, add_write_fd) | ||
| 4 | (delete_write_fd): Declare. | ||
| 5 | |||
| 6 | * process.c (gpm_wait_mask, max_gpm_desc): Remove. | ||
| 7 | (write_mask): New variable. | ||
| 8 | (max_input_desc): Renamed from max_keyboard_desc. | ||
| 9 | (fd_callback_info): New variable. | ||
| 10 | (add_read_fd, delete_read_fd, add_write_fd, delete_write_fd): New | ||
| 11 | functions. | ||
| 12 | (Fmake_network_process): FD_SET write_mask. | ||
| 13 | (deactivate_process): FD_CLR write_mask. | ||
| 14 | (wait_reading_process_output): Connecting renamed to Writeok. | ||
| 15 | check_connect removed. check_write is new. Remove references to | ||
| 16 | gpm. Use Writeok/check_write unconditionally (i.e. no #ifdef | ||
| 17 | NON_BLOCKING_CONNECT) instead of Connecting. | ||
| 18 | Loop over file descriptors and call callbacks in fd_callback_info | ||
| 19 | if file descriptor is ready for I/O. | ||
| 20 | (add_gpm_wait_descriptor): Just call add_keyboard_wait_descriptor. | ||
| 21 | (delete_gpm_wait_descriptor): Just call delete_keyboard_wait_descriptor. | ||
| 22 | (keyboard_bit_set): Use max_input_desc. | ||
| 23 | (add_keyboard_wait_descriptor, delete_keyboard_wait_descriptor): Remove | ||
| 24 | #ifdef subprocesses. Use max_input_desc. | ||
| 25 | (init_process): Initialize write_mask and fd_callback_info. | ||
| 26 | |||
| 27 | * keyboard.c (readable_events, gobble_input): Remove DBUS code. | ||
| 28 | |||
| 29 | * dbusbind.c: Include process.h. | ||
| 30 | (dbus_fd_cb, xd_find_watch_fd, xd_toggle_watch) | ||
| 31 | (xd_read_message_1): New functions. | ||
| 32 | (xd_add_watch, xd_remove_watch): Call xd_find_watch_fd. Handle | ||
| 33 | watch for both read and write. | ||
| 34 | (Fdbus_init_bus): Also register xd_toggle_watch. | ||
| 35 | (Fdbus_call_method_asynchronously, Fdbus_method_return_internal) | ||
| 36 | (Fdbus_method_error_internal, Fdbus_send_signal): Remove call | ||
| 37 | to dbus_connection_flush. | ||
| 38 | (xd_read_message): Move most of the code to xd_read_message_1. | ||
| 39 | Call xd_read_message_1 until status is COMPLETE. | ||
| 40 | |||
| 1 | 2010-09-26 Dan Nicolaescu <dann@ics.uci.edu> | 41 | 2010-09-26 Dan Nicolaescu <dann@ics.uci.edu> |
| 2 | 42 | ||
| 3 | * term.c: Do not include sys/ioctl.h, not needed. | 43 | * term.c: Do not include sys/ioctl.h, not needed. |
diff --git a/src/dbusbind.c b/src/dbusbind.c index 3b6f0e543bb..a8db1c510c7 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 27 | #include "frame.h" | 27 | #include "frame.h" |
| 28 | #include "termhooks.h" | 28 | #include "termhooks.h" |
| 29 | #include "keyboard.h" | 29 | #include "keyboard.h" |
| 30 | #include "process.h" | ||
| 30 | 31 | ||
| 31 | 32 | ||
| 32 | /* Subroutines. */ | 33 | /* Subroutines. */ |
| @@ -799,71 +800,93 @@ xd_initialize (Lisp_Object bus, int raise_error) | |||
| 799 | return connection; | 800 | return connection; |
| 800 | } | 801 | } |
| 801 | 802 | ||
| 803 | /* Callback called when something is read to read ow write. */ | ||
| 802 | 804 | ||
| 803 | /* Add connection file descriptor to input_wait_mask, in order to | 805 | static void |
| 804 | let select() detect, whether a new message has been arrived. */ | 806 | dbus_fd_cb (int fd, void *data, int for_read) |
| 805 | dbus_bool_t | 807 | { |
| 806 | xd_add_watch (DBusWatch *watch, void *data) | 808 | xd_read_queued_messages (); |
| 809 | } | ||
| 810 | |||
| 811 | /* Return the file descriptor for WATCH, -1 if not found. */ | ||
| 812 | |||
| 813 | static int | ||
| 814 | xd_find_watch_fd (DBusWatch *watch) | ||
| 807 | { | 815 | { |
| 808 | /* We check only for incoming data. */ | ||
| 809 | if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE) | ||
| 810 | { | ||
| 811 | #if HAVE_DBUS_WATCH_GET_UNIX_FD | 816 | #if HAVE_DBUS_WATCH_GET_UNIX_FD |
| 812 | /* TODO: Reverse these on Win32, which prefers the opposite. */ | 817 | /* TODO: Reverse these on Win32, which prefers the opposite. */ |
| 813 | int fd = dbus_watch_get_unix_fd(watch); | 818 | int fd = dbus_watch_get_unix_fd (watch); |
| 814 | if (fd == -1) | 819 | if (fd == -1) |
| 815 | fd = dbus_watch_get_socket(watch); | 820 | fd = dbus_watch_get_socket (watch); |
| 816 | #else | 821 | #else |
| 817 | int fd = dbus_watch_get_fd(watch); | 822 | int fd = dbus_watch_get_fd (watch); |
| 818 | #endif | 823 | #endif |
| 819 | XD_DEBUG_MESSAGE ("fd %d", fd); | 824 | return fd; |
| 825 | } | ||
| 820 | 826 | ||
| 821 | if (fd == -1) | ||
| 822 | return FALSE; | ||
| 823 | 827 | ||
| 824 | /* Add the file descriptor to input_wait_mask. */ | 828 | /* Start monitoring WATCH for possible I/O. */ |
| 825 | add_keyboard_wait_descriptor (fd); | ||
| 826 | } | ||
| 827 | 829 | ||
| 828 | /* Return. */ | 830 | static dbus_bool_t |
| 831 | xd_add_watch (DBusWatch *watch, void *data) | ||
| 832 | { | ||
| 833 | unsigned int flags = dbus_watch_get_flags (watch); | ||
| 834 | int fd = xd_find_watch_fd (watch); | ||
| 835 | |||
| 836 | XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d", | ||
| 837 | fd, flags & DBUS_WATCH_WRITABLE, | ||
| 838 | dbus_watch_get_enabled (watch)); | ||
| 839 | |||
| 840 | if (fd == -1) | ||
| 841 | return FALSE; | ||
| 842 | |||
| 843 | if (dbus_watch_get_enabled (watch)) | ||
| 844 | { | ||
| 845 | if (flags & DBUS_WATCH_WRITABLE) | ||
| 846 | add_write_fd (fd, dbus_fd_cb, NULL); | ||
| 847 | if (flags & DBUS_WATCH_READABLE) | ||
| 848 | add_read_fd (fd, dbus_fd_cb, NULL); | ||
| 849 | } | ||
| 829 | return TRUE; | 850 | return TRUE; |
| 830 | } | 851 | } |
| 831 | 852 | ||
| 832 | /* Remove connection file descriptor from input_wait_mask. DATA is | 853 | /* Stop monitoring WATCH for possible I/O. |
| 833 | the used bus, either a string or QCdbus_system_bus or | 854 | DATA is the used bus, either a string or QCdbus_system_bus or |
| 834 | QCdbus_session_bus. */ | 855 | QCdbus_session_bus. */ |
| 835 | void | 856 | |
| 857 | static void | ||
| 836 | xd_remove_watch (DBusWatch *watch, void *data) | 858 | xd_remove_watch (DBusWatch *watch, void *data) |
| 837 | { | 859 | { |
| 838 | /* We check only for incoming data. */ | 860 | unsigned int flags = dbus_watch_get_flags (watch); |
| 839 | if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE) | 861 | int fd = xd_find_watch_fd (watch); |
| 840 | { | ||
| 841 | #if HAVE_DBUS_WATCH_GET_UNIX_FD | ||
| 842 | /* TODO: Reverse these on Win32, which prefers the opposite. */ | ||
| 843 | int fd = dbus_watch_get_unix_fd(watch); | ||
| 844 | if (fd == -1) | ||
| 845 | fd = dbus_watch_get_socket(watch); | ||
| 846 | #else | ||
| 847 | int fd = dbus_watch_get_fd(watch); | ||
| 848 | #endif | ||
| 849 | XD_DEBUG_MESSAGE ("fd %d", fd); | ||
| 850 | 862 | ||
| 851 | if (fd == -1) | 863 | XD_DEBUG_MESSAGE ("fd %d", fd); |
| 852 | return; | 864 | |
| 865 | if (fd == -1) return; | ||
| 853 | 866 | ||
| 854 | /* Unset session environment. */ | ||
| 855 | if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus))) | ||
| 856 | { | ||
| 857 | XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); | ||
| 858 | unsetenv ("DBUS_SESSION_BUS_ADDRESS"); | ||
| 859 | } | ||
| 860 | 867 | ||
| 861 | /* Remove the file descriptor from input_wait_mask. */ | 868 | /* Unset session environment. */ |
| 862 | delete_keyboard_wait_descriptor (fd); | 869 | if (data != NULL && data == (void*) XHASH (QCdbus_session_bus)) |
| 870 | { | ||
| 871 | XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); | ||
| 872 | unsetenv ("DBUS_SESSION_BUS_ADDRESS"); | ||
| 863 | } | 873 | } |
| 864 | 874 | ||
| 865 | /* Return. */ | 875 | if (flags & DBUS_WATCH_WRITABLE) |
| 866 | return; | 876 | delete_write_fd (fd); |
| 877 | if (flags & DBUS_WATCH_READABLE) | ||
| 878 | delete_read_fd (fd); | ||
| 879 | } | ||
| 880 | |||
| 881 | /* Toggle monitoring WATCH for possible I/O. */ | ||
| 882 | |||
| 883 | static void | ||
| 884 | xd_toggle_watch (DBusWatch *watch, void *data) | ||
| 885 | { | ||
| 886 | if (dbus_watch_get_enabled (watch)) | ||
| 887 | xd_add_watch (watch, data); | ||
| 888 | else | ||
| 889 | xd_remove_watch (watch, data); | ||
| 867 | } | 890 | } |
| 868 | 891 | ||
| 869 | DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, | 892 | DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, |
| @@ -880,7 +903,8 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, | |||
| 880 | if (!dbus_connection_set_watch_functions (connection, | 903 | if (!dbus_connection_set_watch_functions (connection, |
| 881 | xd_add_watch, | 904 | xd_add_watch, |
| 882 | xd_remove_watch, | 905 | xd_remove_watch, |
| 883 | NULL, (void*) XHASH (bus), NULL)) | 906 | xd_toggle_watch, |
| 907 | (void*) XHASH (bus), NULL)) | ||
| 884 | XD_SIGNAL1 (build_string ("Cannot add watch functions")); | 908 | XD_SIGNAL1 (build_string ("Cannot add watch functions")); |
| 885 | 909 | ||
| 886 | /* Add bus to list of registered buses. */ | 910 | /* Add bus to list of registered buses. */ |
| @@ -1288,9 +1312,6 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE | |||
| 1288 | result = Qnil; | 1312 | result = Qnil; |
| 1289 | } | 1313 | } |
| 1290 | 1314 | ||
| 1291 | /* Flush connection to ensure the message is handled. */ | ||
| 1292 | dbus_connection_flush (connection); | ||
| 1293 | |||
| 1294 | XD_DEBUG_MESSAGE ("Message sent"); | 1315 | XD_DEBUG_MESSAGE ("Message sent"); |
| 1295 | 1316 | ||
| 1296 | /* Cleanup. */ | 1317 | /* Cleanup. */ |
| @@ -1379,9 +1400,6 @@ usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */) | |||
| 1379 | if (!dbus_connection_send (connection, dmessage, NULL)) | 1400 | if (!dbus_connection_send (connection, dmessage, NULL)) |
| 1380 | XD_SIGNAL1 (build_string ("Cannot send message")); | 1401 | XD_SIGNAL1 (build_string ("Cannot send message")); |
| 1381 | 1402 | ||
| 1382 | /* Flush connection to ensure the message is handled. */ | ||
| 1383 | dbus_connection_flush (connection); | ||
| 1384 | |||
| 1385 | XD_DEBUG_MESSAGE ("Message sent"); | 1403 | XD_DEBUG_MESSAGE ("Message sent"); |
| 1386 | 1404 | ||
| 1387 | /* Cleanup. */ | 1405 | /* Cleanup. */ |
| @@ -1471,9 +1489,6 @@ usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */) | |||
| 1471 | if (!dbus_connection_send (connection, dmessage, NULL)) | 1489 | if (!dbus_connection_send (connection, dmessage, NULL)) |
| 1472 | XD_SIGNAL1 (build_string ("Cannot send message")); | 1490 | XD_SIGNAL1 (build_string ("Cannot send message")); |
| 1473 | 1491 | ||
| 1474 | /* Flush connection to ensure the message is handled. */ | ||
| 1475 | dbus_connection_flush (connection); | ||
| 1476 | |||
| 1477 | XD_DEBUG_MESSAGE ("Message sent"); | 1492 | XD_DEBUG_MESSAGE ("Message sent"); |
| 1478 | 1493 | ||
| 1479 | /* Cleanup. */ | 1494 | /* Cleanup. */ |
| @@ -1589,9 +1604,6 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */) | |||
| 1589 | if (!dbus_connection_send (connection, dmessage, NULL)) | 1604 | if (!dbus_connection_send (connection, dmessage, NULL)) |
| 1590 | XD_SIGNAL1 (build_string ("Cannot send message")); | 1605 | XD_SIGNAL1 (build_string ("Cannot send message")); |
| 1591 | 1606 | ||
| 1592 | /* Flush connection to ensure the message is handled. */ | ||
| 1593 | dbus_connection_flush (connection); | ||
| 1594 | |||
| 1595 | XD_DEBUG_MESSAGE ("Signal sent"); | 1607 | XD_DEBUG_MESSAGE ("Signal sent"); |
| 1596 | 1608 | ||
| 1597 | /* Cleanup. */ | 1609 | /* Cleanup. */ |
| @@ -1645,32 +1657,27 @@ xd_pending_messages (void) | |||
| 1645 | return FALSE; | 1657 | return FALSE; |
| 1646 | } | 1658 | } |
| 1647 | 1659 | ||
| 1648 | /* Read queued incoming message of the D-Bus BUS. BUS is either a | 1660 | /* Read one queued incoming message of the D-Bus BUS. |
| 1649 | Lisp symbol, :system or :session, or a string denoting the bus | 1661 | BUS is either a Lisp symbol, :system or :session, or a string denoting |
| 1650 | address. */ | 1662 | the bus address. */ |
| 1651 | static Lisp_Object | 1663 | |
| 1652 | xd_read_message (Lisp_Object bus) | 1664 | static void |
| 1665 | xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | ||
| 1653 | { | 1666 | { |
| 1654 | Lisp_Object args, key, value; | 1667 | Lisp_Object args, key, value; |
| 1655 | struct gcpro gcpro1; | 1668 | struct gcpro gcpro1; |
| 1656 | struct input_event event; | 1669 | struct input_event event; |
| 1657 | DBusConnection *connection; | ||
| 1658 | DBusMessage *dmessage; | 1670 | DBusMessage *dmessage; |
| 1659 | DBusMessageIter iter; | 1671 | DBusMessageIter iter; |
| 1660 | unsigned int dtype; | 1672 | unsigned int dtype; |
| 1661 | int mtype, serial; | 1673 | int mtype, serial; |
| 1662 | const char *uname, *path, *interface, *member; | 1674 | const char *uname, *path, *interface, *member; |
| 1663 | 1675 | ||
| 1664 | /* Open a connection to the bus. */ | ||
| 1665 | connection = xd_initialize (bus, TRUE); | ||
| 1666 | |||
| 1667 | /* Non blocking read of the next available message. */ | ||
| 1668 | dbus_connection_read_write (connection, 0); | ||
| 1669 | dmessage = dbus_connection_pop_message (connection); | 1676 | dmessage = dbus_connection_pop_message (connection); |
| 1670 | 1677 | ||
| 1671 | /* Return if there is no queued message. */ | 1678 | /* Return if there is no queued message. */ |
| 1672 | if (dmessage == NULL) | 1679 | if (dmessage == NULL) |
| 1673 | return Qnil; | 1680 | return; |
| 1674 | 1681 | ||
| 1675 | /* Collect the parameters. */ | 1682 | /* Collect the parameters. */ |
| 1676 | args = Qnil; | 1683 | args = Qnil; |
| @@ -1801,7 +1808,26 @@ xd_read_message (Lisp_Object bus) | |||
| 1801 | cleanup: | 1808 | cleanup: |
| 1802 | dbus_message_unref (dmessage); | 1809 | dbus_message_unref (dmessage); |
| 1803 | 1810 | ||
| 1804 | RETURN_UNGCPRO (Qnil); | 1811 | UNGCPRO; |
| 1812 | } | ||
| 1813 | |||
| 1814 | /* Read queued incoming messages of the D-Bus BUS. | ||
| 1815 | BUS is either a Lisp symbol, :system or :session, or a string denoting | ||
| 1816 | the bus address. */ | ||
| 1817 | |||
| 1818 | static Lisp_Object | ||
| 1819 | xd_read_message (Lisp_Object bus) | ||
| 1820 | { | ||
| 1821 | /* Open a connection to the bus. */ | ||
| 1822 | DBusConnection *connection = xd_initialize (bus, TRUE); | ||
| 1823 | |||
| 1824 | /* Non blocking read of the next available message. */ | ||
| 1825 | dbus_connection_read_write (connection, 0); | ||
| 1826 | |||
| 1827 | while (dbus_connection_get_dispatch_status (connection) | ||
| 1828 | != DBUS_DISPATCH_COMPLETE) | ||
| 1829 | xd_read_message_1 (connection, bus); | ||
| 1830 | return Qnil; | ||
| 1805 | } | 1831 | } |
| 1806 | 1832 | ||
| 1807 | /* Read queued incoming messages from all buses. */ | 1833 | /* Read queued incoming messages from all buses. */ |
diff --git a/src/keyboard.c b/src/keyboard.c index 50cd49e54cd..1be6c2aad9d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -3522,12 +3522,6 @@ restore_getcjmp (jmp_buf temp) | |||
| 3522 | static int | 3522 | static int |
| 3523 | readable_events (int flags) | 3523 | readable_events (int flags) |
| 3524 | { | 3524 | { |
| 3525 | #ifdef HAVE_DBUS | ||
| 3526 | /* Check whether a D-Bus message has arrived. */ | ||
| 3527 | if (xd_pending_messages () > 0) | ||
| 3528 | return 1; | ||
| 3529 | #endif /* HAVE_DBUS */ | ||
| 3530 | |||
| 3531 | if (flags & READABLE_EVENTS_DO_TIMERS_NOW) | 3525 | if (flags & READABLE_EVENTS_DO_TIMERS_NOW) |
| 3532 | timer_check (1); | 3526 | timer_check (1); |
| 3533 | 3527 | ||
| @@ -6877,11 +6871,6 @@ get_input_pending (int *addr, int flags) | |||
| 6877 | void | 6871 | void |
| 6878 | gobble_input (int expected) | 6872 | gobble_input (int expected) |
| 6879 | { | 6873 | { |
| 6880 | #ifdef HAVE_DBUS | ||
| 6881 | /* Read D-Bus messages. */ | ||
| 6882 | xd_read_queued_messages (); | ||
| 6883 | #endif /* HAVE_DBUS */ | ||
| 6884 | |||
| 6885 | #ifdef SIGIO | 6874 | #ifdef SIGIO |
| 6886 | if (interrupt_input) | 6875 | if (interrupt_input) |
| 6887 | { | 6876 | { |
diff --git a/src/process.c b/src/process.c index ef086914704..6ff8f472c26 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -294,9 +294,9 @@ static SELECT_TYPE non_keyboard_wait_mask; | |||
| 294 | 294 | ||
| 295 | static SELECT_TYPE non_process_wait_mask; | 295 | static SELECT_TYPE non_process_wait_mask; |
| 296 | 296 | ||
| 297 | /* Mask for the gpm mouse input descriptor. */ | 297 | /* Mask for selecting for write. */ |
| 298 | 298 | ||
| 299 | static SELECT_TYPE gpm_wait_mask; | 299 | static SELECT_TYPE write_mask; |
| 300 | 300 | ||
| 301 | #ifdef NON_BLOCKING_CONNECT | 301 | #ifdef NON_BLOCKING_CONNECT |
| 302 | /* Mask of bits indicating the descriptors that we wait for connect to | 302 | /* Mask of bits indicating the descriptors that we wait for connect to |
| @@ -316,11 +316,8 @@ static int num_pending_connects; | |||
| 316 | /* The largest descriptor currently in use for a process object. */ | 316 | /* The largest descriptor currently in use for a process object. */ |
| 317 | static int max_process_desc; | 317 | static int max_process_desc; |
| 318 | 318 | ||
| 319 | /* The largest descriptor currently in use for keyboard input. */ | 319 | /* The largest descriptor currently in use for input. */ |
| 320 | static int max_keyboard_desc; | 320 | static int max_input_desc; |
| 321 | |||
| 322 | /* The largest descriptor currently in use for gpm mouse input. */ | ||
| 323 | static int max_gpm_desc; | ||
| 324 | 321 | ||
| 325 | /* Indexed by descriptor, gives the process (if any) for that descriptor */ | 322 | /* Indexed by descriptor, gives the process (if any) for that descriptor */ |
| 326 | Lisp_Object chan_process[MAXDESC]; | 323 | Lisp_Object chan_process[MAXDESC]; |
| @@ -366,6 +363,90 @@ static int pty_max_bytes; | |||
| 366 | static char pty_name[24]; | 363 | static char pty_name[24]; |
| 367 | #endif | 364 | #endif |
| 368 | 365 | ||
| 366 | |||
| 367 | struct fd_callback_data | ||
| 368 | { | ||
| 369 | fd_callback func; | ||
| 370 | void *data; | ||
| 371 | #define FOR_READ 1 | ||
| 372 | #define FOR_WRITE 2 | ||
| 373 | int condition; /* mask of the defines above. */ | ||
| 374 | } fd_callback_info[MAXDESC]; | ||
| 375 | |||
| 376 | |||
| 377 | /* Add a file descriptor FD to be monitored for when read is possible. | ||
| 378 | When read is possible, call FUNC with argument DATA. */ | ||
| 379 | |||
| 380 | void | ||
| 381 | add_read_fd (int fd, fd_callback func, void *data) | ||
| 382 | { | ||
| 383 | xassert (fd < MAXDESC); | ||
| 384 | add_keyboard_wait_descriptor (fd); | ||
| 385 | |||
| 386 | fd_callback_info[fd].func = func; | ||
| 387 | fd_callback_info[fd].data = data; | ||
| 388 | fd_callback_info[fd].condition |= FOR_READ; | ||
| 389 | } | ||
| 390 | |||
| 391 | /* Stop monitoring file descriptor FD for when read is possible. */ | ||
| 392 | |||
| 393 | void | ||
| 394 | delete_read_fd (int fd) | ||
| 395 | { | ||
| 396 | xassert (fd < MAXDESC); | ||
| 397 | delete_keyboard_wait_descriptor (fd); | ||
| 398 | |||
| 399 | fd_callback_info[fd].condition &= ~FOR_READ; | ||
| 400 | if (fd_callback_info[fd].condition == 0) | ||
| 401 | { | ||
| 402 | fd_callback_info[fd].func = 0; | ||
| 403 | fd_callback_info[fd].data = 0; | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | /* Add a file descriptor FD to be monitored for when write is possible. | ||
| 408 | When write is possible, call FUNC with argument DATA. */ | ||
| 409 | |||
| 410 | void | ||
| 411 | add_write_fd (int fd, fd_callback func, void *data) | ||
| 412 | { | ||
| 413 | xassert (fd < MAXDESC); | ||
| 414 | FD_SET (fd, &write_mask); | ||
| 415 | if (fd > max_input_desc) | ||
| 416 | max_input_desc = fd; | ||
| 417 | |||
| 418 | fd_callback_info[fd].func = func; | ||
| 419 | fd_callback_info[fd].data = data; | ||
| 420 | fd_callback_info[fd].condition |= FOR_WRITE; | ||
| 421 | } | ||
| 422 | |||
| 423 | /* Stop monitoring file descriptor FD for when write is possible. */ | ||
| 424 | |||
| 425 | void | ||
| 426 | delete_write_fd (int fd) | ||
| 427 | { | ||
| 428 | int lim = max_input_desc; | ||
| 429 | |||
| 430 | xassert (fd < MAXDESC); | ||
| 431 | FD_CLR (fd, &write_mask); | ||
| 432 | fd_callback_info[fd].condition &= ~FOR_WRITE; | ||
| 433 | if (fd_callback_info[fd].condition == 0) | ||
| 434 | { | ||
| 435 | fd_callback_info[fd].func = 0; | ||
| 436 | fd_callback_info[fd].data = 0; | ||
| 437 | |||
| 438 | if (fd == max_input_desc) | ||
| 439 | for (fd = lim; fd >= 0; fd--) | ||
| 440 | if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) | ||
| 441 | { | ||
| 442 | max_input_desc = fd; | ||
| 443 | break; | ||
| 444 | } | ||
| 445 | |||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 449 | |||
| 369 | /* Compute the Lisp form of the process status, p->status, from | 450 | /* Compute the Lisp form of the process status, p->status, from |
| 370 | the numeric status that was returned by `wait'. */ | 451 | the numeric status that was returned by `wait'. */ |
| 371 | 452 | ||
| @@ -3620,6 +3701,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3620 | if (!FD_ISSET (inch, &connect_wait_mask)) | 3701 | if (!FD_ISSET (inch, &connect_wait_mask)) |
| 3621 | { | 3702 | { |
| 3622 | FD_SET (inch, &connect_wait_mask); | 3703 | FD_SET (inch, &connect_wait_mask); |
| 3704 | FD_SET (inch, &write_mask); | ||
| 3623 | num_pending_connects++; | 3705 | num_pending_connects++; |
| 3624 | } | 3706 | } |
| 3625 | } | 3707 | } |
| @@ -4023,6 +4105,7 @@ deactivate_process (Lisp_Object proc) | |||
| 4023 | if (FD_ISSET (inchannel, &connect_wait_mask)) | 4105 | if (FD_ISSET (inchannel, &connect_wait_mask)) |
| 4024 | { | 4106 | { |
| 4025 | FD_CLR (inchannel, &connect_wait_mask); | 4107 | FD_CLR (inchannel, &connect_wait_mask); |
| 4108 | FD_CLR (inchannel, &write_mask); | ||
| 4026 | if (--num_pending_connects < 0) | 4109 | if (--num_pending_connects < 0) |
| 4027 | abort (); | 4110 | abort (); |
| 4028 | } | 4111 | } |
| @@ -4401,10 +4484,8 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4401 | { | 4484 | { |
| 4402 | register int channel, nfds; | 4485 | register int channel, nfds; |
| 4403 | SELECT_TYPE Available; | 4486 | SELECT_TYPE Available; |
| 4404 | #ifdef NON_BLOCKING_CONNECT | 4487 | SELECT_TYPE Writeok; |
| 4405 | SELECT_TYPE Connecting; | 4488 | int check_write; |
| 4406 | int check_connect; | ||
| 4407 | #endif | ||
| 4408 | int check_delay, no_avail; | 4489 | int check_delay, no_avail; |
| 4409 | int xerrno; | 4490 | int xerrno; |
| 4410 | Lisp_Object proc; | 4491 | Lisp_Object proc; |
| @@ -4414,9 +4495,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4414 | int count = SPECPDL_INDEX (); | 4495 | int count = SPECPDL_INDEX (); |
| 4415 | 4496 | ||
| 4416 | FD_ZERO (&Available); | 4497 | FD_ZERO (&Available); |
| 4417 | #ifdef NON_BLOCKING_CONNECT | 4498 | FD_ZERO (&Writeok); |
| 4418 | FD_ZERO (&Connecting); | ||
| 4419 | #endif | ||
| 4420 | 4499 | ||
| 4421 | if (time_limit == 0 && microsecs == 0 && wait_proc && !NILP (Vinhibit_quit) | 4500 | if (time_limit == 0 && microsecs == 0 && wait_proc && !NILP (Vinhibit_quit) |
| 4422 | && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit))) | 4501 | && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit))) |
| @@ -4552,19 +4631,16 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4552 | if (update_tick != process_tick) | 4631 | if (update_tick != process_tick) |
| 4553 | { | 4632 | { |
| 4554 | SELECT_TYPE Atemp; | 4633 | SELECT_TYPE Atemp; |
| 4555 | #ifdef NON_BLOCKING_CONNECT | ||
| 4556 | SELECT_TYPE Ctemp; | 4634 | SELECT_TYPE Ctemp; |
| 4557 | #endif | ||
| 4558 | 4635 | ||
| 4559 | if (kbd_on_hold_p ()) | 4636 | if (kbd_on_hold_p ()) |
| 4560 | FD_ZERO (&Atemp); | 4637 | FD_ZERO (&Atemp); |
| 4561 | else | 4638 | else |
| 4562 | Atemp = input_wait_mask; | 4639 | Atemp = input_wait_mask; |
| 4563 | IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask); | 4640 | Ctemp = write_mask; |
| 4564 | 4641 | ||
| 4565 | EMACS_SET_SECS_USECS (timeout, 0, 0); | 4642 | EMACS_SET_SECS_USECS (timeout, 0, 0); |
| 4566 | if ((select (max (max (max_process_desc, max_keyboard_desc), | 4643 | if ((select (max (max_process_desc, max_input_desc) + 1, |
| 4567 | max_gpm_desc) + 1, | ||
| 4568 | &Atemp, | 4644 | &Atemp, |
| 4569 | #ifdef NON_BLOCKING_CONNECT | 4645 | #ifdef NON_BLOCKING_CONNECT |
| 4570 | (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), | 4646 | (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), |
| @@ -4635,13 +4711,13 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4635 | break; | 4711 | break; |
| 4636 | FD_SET (wait_proc->infd, &Available); | 4712 | FD_SET (wait_proc->infd, &Available); |
| 4637 | check_delay = 0; | 4713 | check_delay = 0; |
| 4638 | IF_NON_BLOCKING_CONNECT (check_connect = 0); | 4714 | check_write = 0; |
| 4639 | } | 4715 | } |
| 4640 | else if (!NILP (wait_for_cell)) | 4716 | else if (!NILP (wait_for_cell)) |
| 4641 | { | 4717 | { |
| 4642 | Available = non_process_wait_mask; | 4718 | Available = non_process_wait_mask; |
| 4643 | check_delay = 0; | 4719 | check_delay = 0; |
| 4644 | IF_NON_BLOCKING_CONNECT (check_connect = 0); | 4720 | check_write = 0; |
| 4645 | } | 4721 | } |
| 4646 | else | 4722 | else |
| 4647 | { | 4723 | { |
| @@ -4649,7 +4725,8 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4649 | Available = non_keyboard_wait_mask; | 4725 | Available = non_keyboard_wait_mask; |
| 4650 | else | 4726 | else |
| 4651 | Available = input_wait_mask; | 4727 | Available = input_wait_mask; |
| 4652 | IF_NON_BLOCKING_CONNECT (check_connect = (num_pending_connects > 0)); | 4728 | Writeok = write_mask; |
| 4729 | check_write = 1; | ||
| 4653 | check_delay = wait_channel >= 0 ? 0 : process_output_delay_count; | 4730 | check_delay = wait_channel >= 0 ? 0 : process_output_delay_count; |
| 4654 | } | 4731 | } |
| 4655 | 4732 | ||
| @@ -4674,10 +4751,6 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4674 | } | 4751 | } |
| 4675 | else | 4752 | else |
| 4676 | { | 4753 | { |
| 4677 | #ifdef NON_BLOCKING_CONNECT | ||
| 4678 | if (check_connect) | ||
| 4679 | Connecting = connect_wait_mask; | ||
| 4680 | #endif | ||
| 4681 | 4754 | ||
| 4682 | #ifdef ADAPTIVE_READ_BUFFERING | 4755 | #ifdef ADAPTIVE_READ_BUFFERING |
| 4683 | /* Set the timeout for adaptive read buffering if any | 4756 | /* Set the timeout for adaptive read buffering if any |
| @@ -4719,15 +4792,10 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4719 | #else | 4792 | #else |
| 4720 | nfds = select | 4793 | nfds = select |
| 4721 | #endif | 4794 | #endif |
| 4722 | (max (max (max_process_desc, max_keyboard_desc), | 4795 | (max (max_process_desc, max_input_desc) + 1, |
| 4723 | max_gpm_desc) + 1, | 4796 | &Available, |
| 4724 | &Available, | 4797 | (check_write ? &Writeok : (SELECT_TYPE *)0), |
| 4725 | #ifdef NON_BLOCKING_CONNECT | 4798 | (SELECT_TYPE *)0, &timeout); |
| 4726 | (check_connect ? &Connecting : (SELECT_TYPE *)0), | ||
| 4727 | #else | ||
| 4728 | (SELECT_TYPE *)0, | ||
| 4729 | #endif | ||
| 4730 | (SELECT_TYPE *)0, &timeout); | ||
| 4731 | } | 4799 | } |
| 4732 | 4800 | ||
| 4733 | xerrno = errno; | 4801 | xerrno = errno; |
| @@ -4767,7 +4835,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4767 | if (no_avail) | 4835 | if (no_avail) |
| 4768 | { | 4836 | { |
| 4769 | FD_ZERO (&Available); | 4837 | FD_ZERO (&Available); |
| 4770 | IF_NON_BLOCKING_CONNECT (check_connect = 0); | 4838 | check_write = 0; |
| 4771 | } | 4839 | } |
| 4772 | 4840 | ||
| 4773 | #if 0 /* When polling is used, interrupt_input is 0, | 4841 | #if 0 /* When polling is used, interrupt_input is 0, |
| @@ -4863,12 +4931,26 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4863 | if (no_avail || nfds == 0) | 4931 | if (no_avail || nfds == 0) |
| 4864 | continue; | 4932 | continue; |
| 4865 | 4933 | ||
| 4934 | for (channel = 0; channel <= max_input_desc; ++channel) | ||
| 4935 | { | ||
| 4936 | struct fd_callback_data *d = &fd_callback_info[channel]; | ||
| 4937 | if (FD_ISSET (channel, &Available) | ||
| 4938 | && d->func != 0 | ||
| 4939 | && (d->condition & FOR_READ) != 0) | ||
| 4940 | d->func (channel, d->data, 1); | ||
| 4941 | if (FD_ISSET (channel, &write_mask) | ||
| 4942 | && d->func != 0 | ||
| 4943 | && (d->condition & FOR_WRITE) != 0) | ||
| 4944 | d->func (channel, d->data, 0); | ||
| 4945 | } | ||
| 4946 | |||
| 4866 | /* Really FIRST_PROC_DESC should be 0 on Unix, | 4947 | /* Really FIRST_PROC_DESC should be 0 on Unix, |
| 4867 | but this is safer in the short run. */ | 4948 | but this is safer in the short run. */ |
| 4868 | for (channel = 0; channel <= max_process_desc; channel++) | 4949 | for (channel = 0; channel <= max_process_desc; channel++) |
| 4869 | { | 4950 | { |
| 4870 | if (FD_ISSET (channel, &Available) | 4951 | if (FD_ISSET (channel, &Available) |
| 4871 | && FD_ISSET (channel, &non_keyboard_wait_mask)) | 4952 | && FD_ISSET (channel, &non_keyboard_wait_mask) |
| 4953 | && !FD_ISSET (channel, &non_process_wait_mask)) | ||
| 4872 | { | 4954 | { |
| 4873 | int nread; | 4955 | int nread; |
| 4874 | 4956 | ||
| @@ -4973,7 +5055,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4973 | } | 5055 | } |
| 4974 | } | 5056 | } |
| 4975 | #ifdef NON_BLOCKING_CONNECT | 5057 | #ifdef NON_BLOCKING_CONNECT |
| 4976 | if (check_connect && FD_ISSET (channel, &Connecting) | 5058 | if (FD_ISSET (channel, &Writeok) |
| 4977 | && FD_ISSET (channel, &connect_wait_mask)) | 5059 | && FD_ISSET (channel, &connect_wait_mask)) |
| 4978 | { | 5060 | { |
| 4979 | struct Lisp_Process *p; | 5061 | struct Lisp_Process *p; |
| @@ -6745,35 +6827,16 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p, | |||
| 6745 | 6827 | ||
| 6746 | 6828 | ||
| 6747 | 6829 | ||
| 6748 | static int add_gpm_wait_descriptor_called_flag; | ||
| 6749 | |||
| 6750 | void | 6830 | void |
| 6751 | add_gpm_wait_descriptor (int desc) | 6831 | add_gpm_wait_descriptor (int desc) |
| 6752 | { | 6832 | { |
| 6753 | if (! add_gpm_wait_descriptor_called_flag) | 6833 | add_keyboard_wait_descriptor (desc); |
| 6754 | FD_CLR (0, &input_wait_mask); | ||
| 6755 | add_gpm_wait_descriptor_called_flag = 1; | ||
| 6756 | FD_SET (desc, &input_wait_mask); | ||
| 6757 | FD_SET (desc, &gpm_wait_mask); | ||
| 6758 | if (desc > max_gpm_desc) | ||
| 6759 | max_gpm_desc = desc; | ||
| 6760 | } | 6834 | } |
| 6761 | 6835 | ||
| 6762 | void | 6836 | void |
| 6763 | delete_gpm_wait_descriptor (int desc) | 6837 | delete_gpm_wait_descriptor (int desc) |
| 6764 | { | 6838 | { |
| 6765 | int fd; | 6839 | delete_keyboard_wait_descriptor (desc); |
| 6766 | int lim = max_gpm_desc; | ||
| 6767 | |||
| 6768 | FD_CLR (desc, &input_wait_mask); | ||
| 6769 | FD_CLR (desc, &non_process_wait_mask); | ||
| 6770 | |||
| 6771 | if (desc == max_gpm_desc) | ||
| 6772 | for (fd = 0; fd < lim; fd++) | ||
| 6773 | if (FD_ISSET (fd, &input_wait_mask) | ||
| 6774 | && !FD_ISSET (fd, &non_keyboard_wait_mask) | ||
| 6775 | && !FD_ISSET (fd, &non_process_wait_mask)) | ||
| 6776 | max_gpm_desc = fd; | ||
| 6777 | } | 6840 | } |
| 6778 | 6841 | ||
| 6779 | /* Return nonzero if *MASK has a bit set | 6842 | /* Return nonzero if *MASK has a bit set |
| @@ -6784,7 +6847,7 @@ keyboard_bit_set (fd_set *mask) | |||
| 6784 | { | 6847 | { |
| 6785 | int fd; | 6848 | int fd; |
| 6786 | 6849 | ||
| 6787 | for (fd = 0; fd <= max_keyboard_desc; fd++) | 6850 | for (fd = 0; fd <= max_input_desc; fd++) |
| 6788 | if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask) | 6851 | if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask) |
| 6789 | && !FD_ISSET (fd, &non_keyboard_wait_mask)) | 6852 | && !FD_ISSET (fd, &non_keyboard_wait_mask)) |
| 6790 | return 1; | 6853 | return 1; |
| @@ -7023,12 +7086,10 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 7023 | void | 7086 | void |
| 7024 | add_keyboard_wait_descriptor (int desc) | 7087 | add_keyboard_wait_descriptor (int desc) |
| 7025 | { | 7088 | { |
| 7026 | #ifdef subprocesses | ||
| 7027 | FD_SET (desc, &input_wait_mask); | 7089 | FD_SET (desc, &input_wait_mask); |
| 7028 | FD_SET (desc, &non_process_wait_mask); | 7090 | FD_SET (desc, &non_process_wait_mask); |
| 7029 | if (desc > max_keyboard_desc) | 7091 | if (desc > max_input_desc) |
| 7030 | max_keyboard_desc = desc; | 7092 | max_input_desc = desc; |
| 7031 | #endif | ||
| 7032 | } | 7093 | } |
| 7033 | 7094 | ||
| 7034 | /* From now on, do not expect DESC to give keyboard input. */ | 7095 | /* From now on, do not expect DESC to give keyboard input. */ |
| @@ -7036,20 +7097,16 @@ add_keyboard_wait_descriptor (int desc) | |||
| 7036 | void | 7097 | void |
| 7037 | delete_keyboard_wait_descriptor (int desc) | 7098 | delete_keyboard_wait_descriptor (int desc) |
| 7038 | { | 7099 | { |
| 7039 | #ifdef subprocesses | ||
| 7040 | int fd; | 7100 | int fd; |
| 7041 | int lim = max_keyboard_desc; | 7101 | int lim = max_input_desc; |
| 7042 | 7102 | ||
| 7043 | FD_CLR (desc, &input_wait_mask); | 7103 | FD_CLR (desc, &input_wait_mask); |
| 7044 | FD_CLR (desc, &non_process_wait_mask); | 7104 | FD_CLR (desc, &non_process_wait_mask); |
| 7045 | 7105 | ||
| 7046 | if (desc == max_keyboard_desc) | 7106 | if (desc == max_input_desc) |
| 7047 | for (fd = 0; fd < lim; fd++) | 7107 | for (fd = 0; fd < lim; fd++) |
| 7048 | if (FD_ISSET (fd, &input_wait_mask) | 7108 | if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) |
| 7049 | && !FD_ISSET (fd, &non_keyboard_wait_mask) | 7109 | max_input_desc = fd; |
| 7050 | && !FD_ISSET (fd, &gpm_wait_mask)) | ||
| 7051 | max_keyboard_desc = fd; | ||
| 7052 | #endif /* subprocesses */ | ||
| 7053 | } | 7110 | } |
| 7054 | 7111 | ||
| 7055 | /* Setup coding systems of PROCESS. */ | 7112 | /* Setup coding systems of PROCESS. */ |
| @@ -7306,7 +7363,9 @@ init_process (void) | |||
| 7306 | FD_ZERO (&input_wait_mask); | 7363 | FD_ZERO (&input_wait_mask); |
| 7307 | FD_ZERO (&non_keyboard_wait_mask); | 7364 | FD_ZERO (&non_keyboard_wait_mask); |
| 7308 | FD_ZERO (&non_process_wait_mask); | 7365 | FD_ZERO (&non_process_wait_mask); |
| 7366 | FD_ZERO (&write_mask); | ||
| 7309 | max_process_desc = 0; | 7367 | max_process_desc = 0; |
| 7368 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); | ||
| 7310 | 7369 | ||
| 7311 | #ifdef NON_BLOCKING_CONNECT | 7370 | #ifdef NON_BLOCKING_CONNECT |
| 7312 | FD_ZERO (&connect_wait_mask); | 7371 | FD_ZERO (&connect_wait_mask); |
diff --git a/src/process.h b/src/process.h index 562d888f93f..d6e842cfbbc 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -192,5 +192,12 @@ extern void hold_keyboard_input (void); | |||
| 192 | extern void unhold_keyboard_input (void); | 192 | extern void unhold_keyboard_input (void); |
| 193 | extern int kbd_on_hold_p (void); | 193 | extern int kbd_on_hold_p (void); |
| 194 | 194 | ||
| 195 | typedef void (*fd_callback)(int fd, void *data, int for_read); | ||
| 196 | |||
| 197 | extern void add_read_fd (int fd, fd_callback func, void *data); | ||
| 198 | extern void delete_read_fd (int fd); | ||
| 199 | extern void add_write_fd (int fd, fd_callback func, void *data); | ||
| 200 | extern void delete_write_fd (int fd); | ||
| 201 | |||
| 195 | /* arch-tag: dffedfc4-d7bc-4b58-a26f-c16155449c72 | 202 | /* arch-tag: dffedfc4-d7bc-4b58-a26f-c16155449c72 |
| 196 | (do not change this comment) */ | 203 | (do not change this comment) */ |