mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-18 08:51:45 -08:00
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.
This commit is contained in:
parent
6303aba122
commit
3fad2ad22e
5 changed files with 281 additions and 160 deletions
|
|
@ -1,3 +1,43 @@
|
|||
2010-09-26 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* 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 <dann@ics.uci.edu>
|
||||
|
||||
* term.c: Do not include sys/ioctl.h, not needed.
|
||||
|
|
|
|||
180
src/dbusbind.c
180
src/dbusbind.c
|
|
@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "frame.h"
|
||||
#include "termhooks.h"
|
||||
#include "keyboard.h"
|
||||
#include "process.h"
|
||||
|
||||
|
||||
/* Subroutines. */
|
||||
|
|
@ -799,71 +800,93 @@ xd_initialize (Lisp_Object bus, int raise_error)
|
|||
return connection;
|
||||
}
|
||||
|
||||
/* Callback called when something is read to read ow write. */
|
||||
|
||||
/* Add connection file descriptor to input_wait_mask, in order to
|
||||
let select() detect, whether a new message has been arrived. */
|
||||
dbus_bool_t
|
||||
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 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
|
|||
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 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
|
|||
result = Qnil;
|
||||
}
|
||||
|
||||
/* Flush connection to ensure the message is handled. */
|
||||
dbus_connection_flush (connection);
|
||||
|
||||
XD_DEBUG_MESSAGE ("Message sent");
|
||||
|
||||
/* Cleanup. */
|
||||
|
|
@ -1379,9 +1400,6 @@ usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
|
|||
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 @@ usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
|
|||
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 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
|
|||
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 @@ xd_pending_messages (void)
|
|||
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 @@ xd_read_message (Lisp_Object bus)
|
|||
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. */
|
||||
|
|
|
|||
|
|
@ -3522,12 +3522,6 @@ restore_getcjmp (jmp_buf temp)
|
|||
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 @@ get_input_pending (int *addr, int flags)
|
|||
void
|
||||
gobble_input (int expected)
|
||||
{
|
||||
#ifdef HAVE_DBUS
|
||||
/* Read D-Bus messages. */
|
||||
xd_read_queued_messages ();
|
||||
#endif /* HAVE_DBUS */
|
||||
|
||||
#ifdef SIGIO
|
||||
if (interrupt_input)
|
||||
{
|
||||
|
|
|
|||
203
src/process.c
203
src/process.c
|
|
@ -294,9 +294,9 @@ static SELECT_TYPE non_keyboard_wait_mask;
|
|||
|
||||
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 @@ static int num_pending_connects;
|
|||
/* 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];
|
||||
|
|
@ -365,6 +362,90 @@ static int pty_max_bytes;
|
|||
|
||||
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 @@ usage: (make-network-process &rest ARGS) */)
|
|||
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 @@ deactivate_process (Lisp_Object proc)
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
{
|
||||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
}
|
||||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
#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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
}
|
||||
}
|
||||
#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 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p,
|
|||
|
||||
|
||||
|
||||
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 @@ keyboard_bit_set (fd_set *mask)
|
|||
{
|
||||
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 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
|
|||
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 @@ add_keyboard_wait_descriptor (int desc)
|
|||
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 @@ init_process (void)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -192,5 +192,12 @@ extern void hold_keyboard_input (void);
|
|||
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) */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue