From: Stefan Monnier Date: Sat, 8 Apr 2006 15:07:35 +0000 (+0000) Subject: * process.h (struct Lisp_Process): Replace Lisp_Objects `pid', X-Git-Tag: emacs-pretest-22.0.90~3267 X-Git-Url: https://code.delx.au/gnu-emacs/commitdiff_plain/6bfd98e75de5ae13bdceddb7effda6bb41bedf79 * 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. --- diff --git a/src/ChangeLog b/src/ChangeLog index 56957d655b..54c9b86db0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,26 @@ +2006-04-08 Stefan Monnier + + * 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 * w32fns.c (Fx_show_tip): Add 3 to the 5th arg of SetWindowPos. diff --git a/src/alloc.c b/src/alloc.c index e3b65c1a4f..5b42a0016a 100644 --- a/src/alloc.c +++ b/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]); } diff --git a/src/process.c b/src/process.c index 66cb227bb0..08c515d34e 100644 --- a/src/process.c +++ b/src/process.c @@ -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); diff --git a/src/process.h b/src/process.h index 9625556888..c4b4281fed 100644 --- a/src/process.h +++ b/src/process.h @@ -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