mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-25 15:00:45 -08:00
* process.h (struct Lisp_Process): Replace Lisp_Objects `pid',
`raw_status_high', and `raw_status_low' with plain integers, and move them to the end of the structure. * alloc.c (allocate_process): Use PSEUDOVECSIZE to initialize the pseudovector's size field so only the Lisp_Object fields get GC'd. * process.c (update_status, make_process, Fdelete_process) (Fprocess_status, list_processes_1, start_process_unwind) (create_process, Fmake_network_process, server_accept_connection) (wait_reading_process_output, send_process, Fprocess_running_child_p) (process_send_signal, proc_encode_coding_system, Fprocess_send_eof) (sigchld_handler, status_notify): Adjust to new non-Lisp fields for `pid' and `raw_status'. (Fprocess_id, Fsignal_process): Same, and additionally use floats when representing PIDs that are larger than most-positive-fixnum.
This commit is contained in:
parent
67438f773f
commit
6bfd98e75d
4 changed files with 98 additions and 56 deletions
|
|
@ -1,3 +1,26 @@
|
|||
2006-04-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* process.h (struct Lisp_Process): Replace Lisp_Objects `pid',
|
||||
`raw_status_high', and `raw_status_low' with plain integers, and move
|
||||
them to the end of the structure.
|
||||
|
||||
* alloc.c (allocate_process): Use PSEUDOVECSIZE to initialize the
|
||||
pseudovector's size field so only the Lisp_Object fields get GC'd.
|
||||
|
||||
* process.c (update_status, make_process, Fdelete_process)
|
||||
(Fprocess_status, list_processes_1, start_process_unwind)
|
||||
(create_process, Fmake_network_process, server_accept_connection)
|
||||
(wait_reading_process_output, send_process, Fprocess_running_child_p)
|
||||
(process_send_signal, proc_encode_coding_system, Fprocess_send_eof)
|
||||
(sigchld_handler, status_notify): Adjust to new non-Lisp fields for
|
||||
`pid' and `raw_status'.
|
||||
(Fprocess_id, Fsignal_process): Same, and additionally use floats when
|
||||
representing PIDs that are larger than most-positive-fixnum.
|
||||
|
||||
* keymap.c (describe_map): Only use XINT if we checked INTEGERP.
|
||||
|
||||
* lisp.h (OFFSETOF, PSEUDOVECSIZE): New macros.
|
||||
|
||||
2006-04-08 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32fns.c (Fx_show_tip): Add 3 to the 5th arg of SetWindowPos.
|
||||
|
|
|
|||
16
src/alloc.c
16
src/alloc.c
|
|
@ -3003,13 +3003,17 @@ allocate_frame ()
|
|||
struct Lisp_Process *
|
||||
allocate_process ()
|
||||
{
|
||||
EMACS_INT len = VECSIZE (struct Lisp_Process);
|
||||
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_PROCESS);
|
||||
/* Memory-footprint of the object in nb of Lisp_Object fields. */
|
||||
EMACS_INT memlen = VECSIZE (struct Lisp_Process);
|
||||
/* Size if we only count the actual Lisp_Object fields (which need to be
|
||||
traced by the GC). */
|
||||
EMACS_INT lisplen = PSEUDOVECSIZE (struct Lisp_Process, pid);
|
||||
struct Lisp_Vector *v = allocate_vectorlike (memlen, MEM_TYPE_PROCESS);
|
||||
EMACS_INT i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
for (i = 0; i < lisplen; ++i)
|
||||
v->contents[i] = Qnil;
|
||||
v->size = len;
|
||||
v->size = lisplen;
|
||||
|
||||
return (struct Lisp_Process *) v;
|
||||
}
|
||||
|
|
@ -5558,6 +5562,10 @@ mark_object (arg)
|
|||
if (size & PSEUDOVECTOR_FLAG)
|
||||
size &= PSEUDOVECTOR_SIZE_MASK;
|
||||
|
||||
/* Note that this size is not the memory-footprint size, but only
|
||||
the number of Lisp_Object fields that we should trace.
|
||||
The distinction is used e.g. by Lisp_Process which places extra
|
||||
non-Lisp_Object fields at the end of the structure. */
|
||||
for (i = 0; i < size; i++) /* and then mark its elements */
|
||||
mark_object (ptr->contents[i]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -414,10 +414,10 @@ update_status (p)
|
|||
struct Lisp_Process *p;
|
||||
{
|
||||
union { int i; WAITTYPE wt; } u;
|
||||
u.i = XFASTINT (p->raw_status_low) + (XFASTINT (p->raw_status_high) << 16);
|
||||
eassert (p->raw_status_new);
|
||||
u.i = p->raw_status;
|
||||
p->status = status_convert (u.wt);
|
||||
p->raw_status_low = Qnil;
|
||||
p->raw_status_high = Qnil;
|
||||
p->raw_status_new = 0;
|
||||
}
|
||||
|
||||
/* Convert a process status word in Unix format to
|
||||
|
|
@ -619,11 +619,10 @@ make_process (name)
|
|||
|
||||
XSETINT (p->infd, -1);
|
||||
XSETINT (p->outfd, -1);
|
||||
XSETFASTINT (p->pid, 0);
|
||||
XSETFASTINT (p->tick, 0);
|
||||
XSETFASTINT (p->update_tick, 0);
|
||||
p->raw_status_low = Qnil;
|
||||
p->raw_status_high = Qnil;
|
||||
p->pid = 0;
|
||||
p->raw_status_new = 0;
|
||||
p->status = Qrun;
|
||||
p->mark = Fmake_marker ();
|
||||
|
||||
|
|
@ -789,8 +788,7 @@ nil, indicating the current buffer's process. */)
|
|||
process = get_process (process);
|
||||
p = XPROCESS (process);
|
||||
|
||||
p->raw_status_low = Qnil;
|
||||
p->raw_status_high = Qnil;
|
||||
p->raw_status_new = 0;
|
||||
if (NETCONN1_P (p))
|
||||
{
|
||||
p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
|
||||
|
|
@ -840,7 +838,7 @@ nil, indicating the current buffer's process. */)
|
|||
return process;
|
||||
|
||||
p = XPROCESS (process);
|
||||
if (!NILP (p->raw_status_low))
|
||||
if (p->raw_status_new)
|
||||
update_status (p);
|
||||
status = p->status;
|
||||
if (CONSP (status))
|
||||
|
|
@ -865,7 +863,7 @@ If PROCESS has not yet exited or died, return 0. */)
|
|||
register Lisp_Object process;
|
||||
{
|
||||
CHECK_PROCESS (process);
|
||||
if (!NILP (XPROCESS (process)->raw_status_low))
|
||||
if (XPROCESS (process)->raw_status_new)
|
||||
update_status (XPROCESS (process));
|
||||
if (CONSP (XPROCESS (process)->status))
|
||||
return XCAR (XCDR (XPROCESS (process)->status));
|
||||
|
|
@ -880,7 +878,9 @@ For a network connection, this value is nil. */)
|
|||
register Lisp_Object process;
|
||||
{
|
||||
CHECK_PROCESS (process);
|
||||
return XPROCESS (process)->pid;
|
||||
return (XPROCESS (process)->pid
|
||||
? make_fixnum_or_float (XPROCESS (process)->pid)
|
||||
: Qnil);
|
||||
}
|
||||
|
||||
DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
|
||||
|
|
@ -1362,7 +1362,7 @@ list_processes_1 (query_only)
|
|||
Finsert (1, &p->name);
|
||||
Findent_to (i_status, minspace);
|
||||
|
||||
if (!NILP (p->raw_status_low))
|
||||
if (p->raw_status_new)
|
||||
update_status (p);
|
||||
symbol = p->status;
|
||||
if (CONSP (p->status))
|
||||
|
|
@ -1734,7 +1734,7 @@ start_process_unwind (proc)
|
|||
abort ();
|
||||
|
||||
/* Was PROC started successfully? */
|
||||
if (XINT (XPROCESS (proc)->pid) <= 0)
|
||||
if (XPROCESS (proc)->pid <= 0)
|
||||
remove_process (proc);
|
||||
|
||||
return Qnil;
|
||||
|
|
@ -1945,7 +1945,7 @@ create_process (process, new_argv, current_dir)
|
|||
in the table after this function has returned; if it does
|
||||
it might cause call-process to hang and subsequent asynchronous
|
||||
processes to get their return values scrambled. */
|
||||
XSETINT (XPROCESS (process)->pid, -1);
|
||||
XPROCESS (process)->pid = -1;
|
||||
|
||||
BLOCK_INPUT;
|
||||
|
||||
|
|
@ -2136,7 +2136,7 @@ create_process (process, new_argv, current_dir)
|
|||
else
|
||||
{
|
||||
/* vfork succeeded. */
|
||||
XSETFASTINT (XPROCESS (process)->pid, pid);
|
||||
XPROCESS (process)->pid = pid;
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
register_child (pid, inchannel);
|
||||
|
|
@ -3349,7 +3349,7 @@ usage: (make-network-process &rest ARGS) */)
|
|||
p->kill_without_query = Qt;
|
||||
if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
|
||||
p->command = Qt;
|
||||
p->pid = Qnil;
|
||||
p->pid = 0;
|
||||
XSETINT (p->infd, inch);
|
||||
XSETINT (p->outfd, outch);
|
||||
if (is_server && socktype == SOCK_STREAM)
|
||||
|
|
@ -4065,7 +4065,7 @@ server_accept_connection (server, channel)
|
|||
p->sentinel = ps->sentinel;
|
||||
p->filter = ps->filter;
|
||||
p->command = Qnil;
|
||||
p->pid = Qnil;
|
||||
p->pid = 0;
|
||||
XSETINT (p->infd, s);
|
||||
XSETINT (p->outfd, s);
|
||||
p->status = Qrun;
|
||||
|
|
@ -4365,9 +4365,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
|
|||
|
||||
/* Don't wait for output from a non-running process. Just
|
||||
read whatever data has already been received. */
|
||||
if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
|
||||
if (wait_proc && wait_proc->raw_status_new)
|
||||
update_status (wait_proc);
|
||||
if (wait_proc != 0
|
||||
if (wait_proc
|
||||
&& ! EQ (wait_proc->status, Qrun)
|
||||
&& ! EQ (wait_proc->status, Qconnect))
|
||||
{
|
||||
|
|
@ -4751,7 +4751,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
|
|||
/* Preserve status of processes already terminated. */
|
||||
XSETINT (XPROCESS (proc)->tick, ++process_tick);
|
||||
deactivate_process (proc);
|
||||
if (!NILP (XPROCESS (proc)->raw_status_low))
|
||||
if (XPROCESS (proc)->raw_status_new)
|
||||
update_status (XPROCESS (proc));
|
||||
if (EQ (XPROCESS (proc)->status, Qrun))
|
||||
XPROCESS (proc)->status
|
||||
|
|
@ -5288,7 +5288,7 @@ send_process (proc, buf, len, object)
|
|||
VMS_PROC_STUFF *vs, *get_vms_process_pointer();
|
||||
#endif /* VMS */
|
||||
|
||||
if (! NILP (p->raw_status_low))
|
||||
if (p->raw_status_new)
|
||||
update_status (p);
|
||||
if (! EQ (p->status, Qrun))
|
||||
error ("Process %s not running", SDATA (p->name));
|
||||
|
|
@ -5552,8 +5552,7 @@ send_process (proc, buf, len, object)
|
|||
proc = process_sent_to;
|
||||
p = XPROCESS (proc);
|
||||
#endif
|
||||
p->raw_status_low = Qnil;
|
||||
p->raw_status_high = Qnil;
|
||||
p->raw_status_new = 0;
|
||||
p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
|
||||
XSETINT (p->tick, ++process_tick);
|
||||
deactivate_process (proc);
|
||||
|
|
@ -5668,7 +5667,7 @@ return t unconditionally. */)
|
|||
|
||||
gid = emacs_get_tty_pgrp (p);
|
||||
|
||||
if (gid == XFASTINT (p->pid))
|
||||
if (gid == p->pid)
|
||||
return Qnil;
|
||||
return Qt;
|
||||
}
|
||||
|
|
@ -5715,7 +5714,7 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
/* If we are using pgrps, get a pgrp number and make it negative. */
|
||||
if (NILP (current_group))
|
||||
/* Send the signal to the shell's process group. */
|
||||
gid = XFASTINT (p->pid);
|
||||
gid = p->pid;
|
||||
else
|
||||
{
|
||||
#ifdef SIGNALS_VIA_CHARACTERS
|
||||
|
|
@ -5834,7 +5833,7 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
if (gid == -1)
|
||||
/* If we can't get the information, assume
|
||||
the shell owns the tty. */
|
||||
gid = XFASTINT (p->pid);
|
||||
gid = p->pid;
|
||||
|
||||
/* It is not clear whether anything really can set GID to -1.
|
||||
Perhaps on some system one of those ioctls can or could do so.
|
||||
|
|
@ -5844,12 +5843,12 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
#else /* ! defined (TIOCGPGRP ) */
|
||||
/* Can't select pgrps on this system, so we know that
|
||||
the child itself heads the pgrp. */
|
||||
gid = XFASTINT (p->pid);
|
||||
gid = p->pid;
|
||||
#endif /* ! defined (TIOCGPGRP ) */
|
||||
|
||||
/* If current_group is lambda, and the shell owns the terminal,
|
||||
don't send any signal. */
|
||||
if (EQ (current_group, Qlambda) && gid == XFASTINT (p->pid))
|
||||
if (EQ (current_group, Qlambda) && gid == p->pid)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5857,8 +5856,7 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
{
|
||||
#ifdef SIGCONT
|
||||
case SIGCONT:
|
||||
p->raw_status_low = Qnil;
|
||||
p->raw_status_high = Qnil;
|
||||
p->raw_status_new = 0;
|
||||
p->status = Qrun;
|
||||
XSETINT (p->tick, ++process_tick);
|
||||
if (!nomsg)
|
||||
|
|
@ -5877,7 +5875,7 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
#endif
|
||||
case SIGKILL:
|
||||
#ifdef VMS
|
||||
sys$forcex (&(XFASTINT (p->pid)), 0, 1);
|
||||
sys$forcex (&(p->pid), 0, 1);
|
||||
whoosh:
|
||||
#endif
|
||||
flush_pending_output (XINT (p->infd));
|
||||
|
|
@ -5889,7 +5887,7 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
obvious alternative. */
|
||||
if (no_pgrp)
|
||||
{
|
||||
kill (XFASTINT (p->pid), signo);
|
||||
kill (p->pid, signo);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5902,7 +5900,7 @@ process_send_signal (process, signo, current_group, nomsg)
|
|||
}
|
||||
else
|
||||
{
|
||||
gid = - XFASTINT (p->pid);
|
||||
gid = - p->pid;
|
||||
kill (gid, signo);
|
||||
}
|
||||
#else /* ! defined (TIOCSIGSEND) */
|
||||
|
|
@ -6022,11 +6020,17 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
|
|||
(process, sigcode)
|
||||
Lisp_Object process, sigcode;
|
||||
{
|
||||
Lisp_Object pid;
|
||||
pid_t pid;
|
||||
|
||||
if (INTEGERP (process))
|
||||
{
|
||||
pid = process;
|
||||
pid = XINT (process);
|
||||
goto got_it;
|
||||
}
|
||||
|
||||
if (FLOATP (process))
|
||||
{
|
||||
pid = (pid_t) XFLOAT (process);
|
||||
goto got_it;
|
||||
}
|
||||
|
||||
|
|
@ -6035,8 +6039,8 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
|
|||
Lisp_Object tem;
|
||||
if (tem = Fget_process (process), NILP (tem))
|
||||
{
|
||||
pid = Fstring_to_number (process, make_number (10));
|
||||
if (XINT (pid) != 0)
|
||||
pid = XINT (Fstring_to_number (process, make_number (10)));
|
||||
if (pid > 0)
|
||||
goto got_it;
|
||||
}
|
||||
process = tem;
|
||||
|
|
@ -6049,7 +6053,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
|
|||
|
||||
CHECK_PROCESS (process);
|
||||
pid = XPROCESS (process)->pid;
|
||||
if (!INTEGERP (pid) || XINT (pid) <= 0)
|
||||
if (pid <= 0)
|
||||
error ("Cannot signal process %s", SDATA (XPROCESS (process)->name));
|
||||
|
||||
got_it:
|
||||
|
|
@ -6168,7 +6172,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
|
|||
|
||||
#undef handle_signal
|
||||
|
||||
return make_number (kill (XINT (pid), XINT (sigcode)));
|
||||
return make_number (kill (pid, XINT (sigcode)));
|
||||
}
|
||||
|
||||
DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
|
||||
|
|
@ -6192,7 +6196,7 @@ text to PROCESS after you call this function. */)
|
|||
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
|
||||
|
||||
/* Make sure the process is really alive. */
|
||||
if (! NILP (XPROCESS (proc)->raw_status_low))
|
||||
if (XPROCESS (proc)->raw_status_new)
|
||||
update_status (XPROCESS (proc));
|
||||
if (! EQ (XPROCESS (proc)->status, Qrun))
|
||||
error ("Process %s not running", SDATA (XPROCESS (proc)->name));
|
||||
|
|
@ -6217,7 +6221,7 @@ text to PROCESS after you call this function. */)
|
|||
for communication with the subprocess, call shutdown to cause EOF.
|
||||
(In some old system, shutdown to socketpair doesn't work.
|
||||
Then we just can't win.) */
|
||||
if (NILP (XPROCESS (proc)->pid)
|
||||
if (XPROCESS (proc)->pid == 0
|
||||
|| XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd))
|
||||
shutdown (XINT (XPROCESS (proc)->outfd), 1);
|
||||
/* In case of socketpair, outfd == infd, so don't close it. */
|
||||
|
|
@ -6354,7 +6358,7 @@ sigchld_handler (signo)
|
|||
{
|
||||
proc = XCDR (XCAR (tail));
|
||||
p = XPROCESS (proc);
|
||||
if (GC_EQ (p->childp, Qt) && XINT (p->pid) == pid)
|
||||
if (GC_EQ (p->childp, Qt) && p->pid == pid)
|
||||
break;
|
||||
p = 0;
|
||||
}
|
||||
|
|
@ -6366,7 +6370,7 @@ sigchld_handler (signo)
|
|||
{
|
||||
proc = XCDR (XCAR (tail));
|
||||
p = XPROCESS (proc);
|
||||
if (GC_INTEGERP (p->pid) && XINT (p->pid) == -1)
|
||||
if (p->pid == -1)
|
||||
break;
|
||||
p = 0;
|
||||
}
|
||||
|
|
@ -6379,8 +6383,8 @@ sigchld_handler (signo)
|
|||
|
||||
XSETINT (p->tick, ++process_tick);
|
||||
u.wt = w;
|
||||
XSETINT (p->raw_status_low, u.i & 0xffff);
|
||||
XSETINT (p->raw_status_high, u.i >> 16);
|
||||
p->raw_status = u.i;
|
||||
p->raw_status_new = 1;
|
||||
|
||||
/* If process has terminated, stop waiting for its output. */
|
||||
if ((WIFSIGNALED (w) || WIFEXITED (w))
|
||||
|
|
@ -6577,7 +6581,7 @@ status_notify (deleting_process)
|
|||
buffer = p->buffer;
|
||||
|
||||
/* Get the text to use for the message. */
|
||||
if (!NILP (p->raw_status_low))
|
||||
if (p->raw_status_new)
|
||||
update_status (p);
|
||||
msg = status_message (p);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,6 @@ struct Lisp_Process
|
|||
Lisp_Object log;
|
||||
/* Buffer that output is going to */
|
||||
Lisp_Object buffer;
|
||||
/* Number of this process */
|
||||
Lisp_Object pid;
|
||||
/* t if this is a real child process.
|
||||
For a net connection, it is a plist based on the arguments to make-network-process. */
|
||||
Lisp_Object childp;
|
||||
|
|
@ -63,10 +61,6 @@ struct Lisp_Process
|
|||
/* Non-nil means kill silently if Emacs is exited.
|
||||
This is the inverse of the `query-on-exit' flag. */
|
||||
Lisp_Object kill_without_query;
|
||||
/* Record the process status in the raw form in which it comes from `wait'.
|
||||
This is to avoid consing in a signal handler. */
|
||||
Lisp_Object raw_status_low;
|
||||
Lisp_Object raw_status_high;
|
||||
/* Symbol indicating status of process.
|
||||
This may be a symbol: run, open, or closed.
|
||||
Or it may be a list, whose car is stop, exit or signal
|
||||
|
|
@ -112,6 +106,19 @@ struct Lisp_Process
|
|||
Lisp_Object read_output_delay;
|
||||
/* Skip reading this process on next read. */
|
||||
Lisp_Object read_output_skip;
|
||||
|
||||
/* After this point, there are no Lisp_Objects any more. */
|
||||
|
||||
/* Number of this process.
|
||||
allocate_process assumes this is the first non-Lisp_Object field.
|
||||
A value 0 is used for pseudo-processes such as network connections. */
|
||||
pid_t pid;
|
||||
/* Record the process status in the raw form in which it comes from `wait'.
|
||||
This is to avoid consing in a signal handler. The `raw_status_new'
|
||||
flag indicates that `raw_status' contains a new status that still
|
||||
needs to be synced to `status'. */
|
||||
int raw_status_new : 1;
|
||||
int raw_status;
|
||||
};
|
||||
|
||||
/* Every field in the preceding structure except for the first two
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue