diff options
| author | Kim F. Storm | 2004-01-01 23:34:14 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2004-01-01 23:34:14 +0000 |
| commit | 2d942bfadfd794e71202b92dd6e6928c70bbfcb0 (patch) | |
| tree | 16467bcced3fbbf3685b00b4618c44df8ccc3d6c /src/process.c | |
| parent | 2ba4be11b79b7cc0a7485240cabd7d91f209fb94 (diff) | |
| download | emacs-2d942bfadfd794e71202b92dd6e6928c70bbfcb0.tar.gz emacs-2d942bfadfd794e71202b92dd6e6928c70bbfcb0.zip | |
(ADAPTIVE_READ_BUFFERING): New conditional.
(READ_OUTPUT_DELAY_INCREMENT, READ_OUTPUT_DELAY_MAX)
(READ_OUTPUT_DELAY_MAX_MAX): New constants.
(process_output_delay_count, process_output_skip): New vars.
(Vprocess_adaptive_read_buffering): New variable.
(make_process): Initialize adaptive read buffering members.
(Fstart_process): Set adaptive_read_buffering member.
(deactivate_process): Cleanup adaptive read buffering.
(wait_reading_process_input): Temporarily omit delayed
subprocesses from the set of file descriptors to read from;
adjust the select timeout if we skipped any subprocesses.
(read_process_output): Increase adaptive read buffering delay if
we read less than a full buffer; reduce delay when we read a
full buffer.
(send_process): Simplify using local Lisp_Process var.
Reset adaptive read buffering delay after write.
(init_process): Initialize process_output_delay_count and
process_output_skip.
(syms_of_process): DEFVAR_LISP Vprocess_adaptive_read_buffering.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 199 |
1 files changed, 164 insertions, 35 deletions
diff --git a/src/process.c b/src/process.c index ed0d5fe765b..3cb63de1584 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -260,6 +260,33 @@ int update_tick; | |||
| 260 | #undef DATAGRAM_SOCKETS | 260 | #undef DATAGRAM_SOCKETS |
| 261 | #endif | 261 | #endif |
| 262 | 262 | ||
| 263 | #if !defined (ADAPTIVE_READ_BUFFERING) && !defined (NO_ADAPTIVE_READ_BUFFERING) | ||
| 264 | #ifdef EMACS_HAS_USECS | ||
| 265 | #define ADAPTIVE_READ_BUFFERING | ||
| 266 | #endif | ||
| 267 | #endif | ||
| 268 | |||
| 269 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 270 | #define READ_OUTPUT_DELAY_INCREMENT 10000 | ||
| 271 | #define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5) | ||
| 272 | #define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7) | ||
| 273 | |||
| 274 | /* Number of processes which might be delayed. */ | ||
| 275 | |||
| 276 | static int process_output_delay_count; | ||
| 277 | |||
| 278 | /* Non-zero if any process has non-nil process_output_skip. */ | ||
| 279 | |||
| 280 | static int process_output_skip; | ||
| 281 | |||
| 282 | /* Non-nil means to delay reading process output to improve buffering. | ||
| 283 | A value of t means that delay is reset after each send, any other | ||
| 284 | non-nil value does not reset the delay. */ | ||
| 285 | static Lisp_Object Vprocess_adaptive_read_buffering; | ||
| 286 | #else | ||
| 287 | #define process_output_delay_count 0 | ||
| 288 | #endif | ||
| 289 | |||
| 263 | 290 | ||
| 264 | #include "sysselect.h" | 291 | #include "sysselect.h" |
| 265 | 292 | ||
| @@ -573,6 +600,12 @@ make_process (name) | |||
| 573 | p->status = Qrun; | 600 | p->status = Qrun; |
| 574 | p->mark = Fmake_marker (); | 601 | p->mark = Fmake_marker (); |
| 575 | 602 | ||
| 603 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 604 | p->adaptive_read_buffering = Qnil; | ||
| 605 | XSETFASTINT (p->read_output_delay, 0); | ||
| 606 | p->read_output_skip = Qnil; | ||
| 607 | #endif | ||
| 608 | |||
| 576 | /* If name is already in use, modify it until it is unused. */ | 609 | /* If name is already in use, modify it until it is unused. */ |
| 577 | 610 | ||
| 578 | name1 = name; | 611 | name1 = name; |
| @@ -1501,6 +1534,10 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1501 | = buffer_defaults.enable_multibyte_characters; | 1534 | = buffer_defaults.enable_multibyte_characters; |
| 1502 | XPROCESS (proc)->command = Flist (nargs - 2, args + 2); | 1535 | XPROCESS (proc)->command = Flist (nargs - 2, args + 2); |
| 1503 | 1536 | ||
| 1537 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 1538 | XPROCESS (proc)->adaptive_read_buffering = Vprocess_adaptive_read_buffering; | ||
| 1539 | #endif | ||
| 1540 | |||
| 1504 | /* Make the process marker point into the process buffer (if any). */ | 1541 | /* Make the process marker point into the process buffer (if any). */ |
| 1505 | if (!NILP (buffer)) | 1542 | if (!NILP (buffer)) |
| 1506 | set_marker_both (XPROCESS (proc)->mark, buffer, | 1543 | set_marker_both (XPROCESS (proc)->mark, buffer, |
| @@ -3588,6 +3625,16 @@ deactivate_process (proc) | |||
| 3588 | inchannel = XINT (p->infd); | 3625 | inchannel = XINT (p->infd); |
| 3589 | outchannel = XINT (p->outfd); | 3626 | outchannel = XINT (p->outfd); |
| 3590 | 3627 | ||
| 3628 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 3629 | if (XINT (p->read_output_delay) > 0) | ||
| 3630 | { | ||
| 3631 | if (--process_output_delay_count < 0) | ||
| 3632 | process_output_delay_count = 0; | ||
| 3633 | XSETINT (p->read_output_delay, 0); | ||
| 3634 | p->read_output_skip = Qnil; | ||
| 3635 | } | ||
| 3636 | #endif | ||
| 3637 | |||
| 3591 | if (inchannel >= 0) | 3638 | if (inchannel >= 0) |
| 3592 | { | 3639 | { |
| 3593 | /* Beware SIGCHLD hereabouts. */ | 3640 | /* Beware SIGCHLD hereabouts. */ |
| @@ -3973,7 +4020,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) | |||
| 3973 | register int channel, nfds; | 4020 | register int channel, nfds; |
| 3974 | static SELECT_TYPE Available; | 4021 | static SELECT_TYPE Available; |
| 3975 | static SELECT_TYPE Connecting; | 4022 | static SELECT_TYPE Connecting; |
| 3976 | int check_connect, no_avail; | 4023 | int check_connect, check_delay, no_avail; |
| 3977 | int xerrno; | 4024 | int xerrno; |
| 3978 | Lisp_Object proc; | 4025 | Lisp_Object proc; |
| 3979 | EMACS_TIME timeout, end_time; | 4026 | EMACS_TIME timeout, end_time; |
| @@ -4202,7 +4249,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) | |||
| 4202 | if (!NILP (wait_for_cell)) | 4249 | if (!NILP (wait_for_cell)) |
| 4203 | { | 4250 | { |
| 4204 | Available = non_process_wait_mask; | 4251 | Available = non_process_wait_mask; |
| 4205 | check_connect = 0; | 4252 | check_connect = check_delay = 0; |
| 4206 | } | 4253 | } |
| 4207 | else | 4254 | else |
| 4208 | { | 4255 | { |
| @@ -4211,6 +4258,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) | |||
| 4211 | else | 4258 | else |
| 4212 | Available = input_wait_mask; | 4259 | Available = input_wait_mask; |
| 4213 | check_connect = (num_pending_connects > 0); | 4260 | check_connect = (num_pending_connects > 0); |
| 4261 | check_delay = process_output_delay_count; | ||
| 4214 | } | 4262 | } |
| 4215 | 4263 | ||
| 4216 | /* If frame size has changed or the window is newly mapped, | 4264 | /* If frame size has changed or the window is newly mapped, |
| @@ -4236,6 +4284,34 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) | |||
| 4236 | { | 4284 | { |
| 4237 | if (check_connect) | 4285 | if (check_connect) |
| 4238 | Connecting = connect_wait_mask; | 4286 | Connecting = connect_wait_mask; |
| 4287 | |||
| 4288 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 4289 | if (process_output_skip && check_delay > 0) | ||
| 4290 | { | ||
| 4291 | int usecs = EMACS_USECS (timeout); | ||
| 4292 | if (EMACS_SECS (timeout) > 0 || usecs > READ_OUTPUT_DELAY_MAX) | ||
| 4293 | usecs = READ_OUTPUT_DELAY_MAX; | ||
| 4294 | for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) | ||
| 4295 | { | ||
| 4296 | proc = chan_process[channel]; | ||
| 4297 | if (NILP (proc)) | ||
| 4298 | continue; | ||
| 4299 | if (XPROCESS (proc)->read_output_delay > 0) | ||
| 4300 | { | ||
| 4301 | check_delay--; | ||
| 4302 | if (NILP (XPROCESS (proc)->read_output_skip)) | ||
| 4303 | continue; | ||
| 4304 | FD_CLR (channel, &Available); | ||
| 4305 | XPROCESS (proc)->read_output_skip = Qnil; | ||
| 4306 | if (XINT (XPROCESS (proc)->read_output_delay) < usecs) | ||
| 4307 | usecs = XINT (XPROCESS (proc)->read_output_delay); | ||
| 4308 | } | ||
| 4309 | } | ||
| 4310 | EMACS_SET_SECS_USECS (timeout, 0, usecs); | ||
| 4311 | process_output_skip = 0; | ||
| 4312 | } | ||
| 4313 | #endif | ||
| 4314 | |||
| 4239 | nfds = select (max (max_process_desc, max_keyboard_desc) + 1, | 4315 | nfds = select (max (max_process_desc, max_keyboard_desc) + 1, |
| 4240 | &Available, | 4316 | &Available, |
| 4241 | (check_connect ? &Connecting : (SELECT_TYPE *)0), | 4317 | (check_connect ? &Connecting : (SELECT_TYPE *)0), |
| @@ -4689,7 +4765,36 @@ read_process_output (proc, channel) | |||
| 4689 | else | 4765 | else |
| 4690 | #endif | 4766 | #endif |
| 4691 | if (proc_buffered_char[channel] < 0) | 4767 | if (proc_buffered_char[channel] < 0) |
| 4692 | nbytes = emacs_read (channel, chars + carryover, readmax - carryover); | 4768 | { |
| 4769 | nbytes = emacs_read (channel, chars + carryover, readmax - carryover); | ||
| 4770 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 4771 | if (!NILP (p->adaptive_read_buffering)) | ||
| 4772 | { | ||
| 4773 | int delay = XINT (p->read_output_delay); | ||
| 4774 | if (nbytes < readmax - carryover) | ||
| 4775 | { | ||
| 4776 | if (delay < READ_OUTPUT_DELAY_MAX_MAX) | ||
| 4777 | { | ||
| 4778 | if (delay == 0) | ||
| 4779 | process_output_delay_count++; | ||
| 4780 | delay += READ_OUTPUT_DELAY_INCREMENT * 2; | ||
| 4781 | } | ||
| 4782 | } | ||
| 4783 | else if (delay > 0) | ||
| 4784 | { | ||
| 4785 | delay -= READ_OUTPUT_DELAY_INCREMENT; | ||
| 4786 | if (delay == 0) | ||
| 4787 | process_output_delay_count--; | ||
| 4788 | } | ||
| 4789 | XSETINT (p->read_output_delay, delay); | ||
| 4790 | if (delay) | ||
| 4791 | { | ||
| 4792 | p->read_output_skip = Qt; | ||
| 4793 | process_output_skip = 1; | ||
| 4794 | } | ||
| 4795 | } | ||
| 4796 | #endif | ||
| 4797 | } | ||
| 4693 | else | 4798 | else |
| 4694 | { | 4799 | { |
| 4695 | chars[carryover] = proc_buffered_char[channel]; | 4800 | chars[carryover] = proc_buffered_char[channel]; |
| @@ -4991,6 +5096,7 @@ send_process (proc, buf, len, object) | |||
| 4991 | volatile Lisp_Object object; | 5096 | volatile Lisp_Object object; |
| 4992 | { | 5097 | { |
| 4993 | /* Use volatile to protect variables from being clobbered by longjmp. */ | 5098 | /* Use volatile to protect variables from being clobbered by longjmp. */ |
| 5099 | struct Lisp_Process *p = XPROCESS (proc); | ||
| 4994 | int rv; | 5100 | int rv; |
| 4995 | struct coding_system *coding; | 5101 | struct coding_system *coding; |
| 4996 | struct gcpro gcpro1; | 5102 | struct gcpro gcpro1; |
| @@ -4998,20 +5104,17 @@ send_process (proc, buf, len, object) | |||
| 4998 | GCPRO1 (object); | 5104 | GCPRO1 (object); |
| 4999 | 5105 | ||
| 5000 | #ifdef VMS | 5106 | #ifdef VMS |
| 5001 | struct Lisp_Process *p = XPROCESS (proc); | ||
| 5002 | VMS_PROC_STUFF *vs, *get_vms_process_pointer(); | 5107 | VMS_PROC_STUFF *vs, *get_vms_process_pointer(); |
| 5003 | #endif /* VMS */ | 5108 | #endif /* VMS */ |
| 5004 | 5109 | ||
| 5005 | if (! NILP (XPROCESS (proc)->raw_status_low)) | 5110 | if (! NILP (p->raw_status_low)) |
| 5006 | update_status (XPROCESS (proc)); | 5111 | update_status (p); |
| 5007 | if (! EQ (XPROCESS (proc)->status, Qrun)) | 5112 | if (! EQ (p->status, Qrun)) |
| 5008 | error ("Process %s not running", | 5113 | error ("Process %s not running", SDATA (p->name)); |
| 5009 | SDATA (XPROCESS (proc)->name)); | 5114 | if (XINT (p->outfd) < 0) |
| 5010 | if (XINT (XPROCESS (proc)->outfd) < 0) | 5115 | error ("Output file descriptor of %s is closed", SDATA (p->name)); |
| 5011 | error ("Output file descriptor of %s is closed", | ||
| 5012 | SDATA (XPROCESS (proc)->name)); | ||
| 5013 | 5116 | ||
| 5014 | coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; | 5117 | coding = proc_encode_coding_system[XINT (p->outfd)]; |
| 5015 | Vlast_coding_system_used = coding->symbol; | 5118 | Vlast_coding_system_used = coding->symbol; |
| 5016 | 5119 | ||
| 5017 | if ((STRINGP (object) && STRING_MULTIBYTE (object)) | 5120 | if ((STRINGP (object) && STRING_MULTIBYTE (object)) |
| @@ -5019,13 +5122,12 @@ send_process (proc, buf, len, object) | |||
| 5019 | && !NILP (XBUFFER (object)->enable_multibyte_characters)) | 5122 | && !NILP (XBUFFER (object)->enable_multibyte_characters)) |
| 5020 | || EQ (object, Qt)) | 5123 | || EQ (object, Qt)) |
| 5021 | { | 5124 | { |
| 5022 | if (!EQ (coding->symbol, XPROCESS (proc)->encode_coding_system)) | 5125 | if (!EQ (coding->symbol, p->encode_coding_system)) |
| 5023 | /* The coding system for encoding was changed to raw-text | 5126 | /* The coding system for encoding was changed to raw-text |
| 5024 | because we sent a unibyte text previously. Now we are | 5127 | because we sent a unibyte text previously. Now we are |
| 5025 | sending a multibyte text, thus we must encode it by the | 5128 | sending a multibyte text, thus we must encode it by the |
| 5026 | original coding system specified for the current | 5129 | original coding system specified for the current process. */ |
| 5027 | process. */ | 5130 | setup_coding_system (p->encode_coding_system, coding); |
| 5028 | setup_coding_system (XPROCESS (proc)->encode_coding_system, coding); | ||
| 5029 | /* src_multibyte should be set to 1 _after_ a call to | 5131 | /* src_multibyte should be set to 1 _after_ a call to |
| 5030 | setup_coding_system, since it resets src_multibyte to | 5132 | setup_coding_system, since it resets src_multibyte to |
| 5031 | zero. */ | 5133 | zero. */ |
| @@ -5076,15 +5178,15 @@ send_process (proc, buf, len, object) | |||
| 5076 | coding->composing = COMPOSITION_DISABLED; | 5178 | coding->composing = COMPOSITION_DISABLED; |
| 5077 | } | 5179 | } |
| 5078 | 5180 | ||
| 5079 | if (SBYTES (XPROCESS (proc)->encoding_buf) < require) | 5181 | if (SBYTES (p->encoding_buf) < require) |
| 5080 | XPROCESS (proc)->encoding_buf = make_uninit_string (require); | 5182 | p->encoding_buf = make_uninit_string (require); |
| 5081 | 5183 | ||
| 5082 | if (from_byte >= 0) | 5184 | if (from_byte >= 0) |
| 5083 | buf = (BUFFERP (object) | 5185 | buf = (BUFFERP (object) |
| 5084 | ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) | 5186 | ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) |
| 5085 | : SDATA (object) + from_byte); | 5187 | : SDATA (object) + from_byte); |
| 5086 | 5188 | ||
| 5087 | object = XPROCESS (proc)->encoding_buf; | 5189 | object = p->encoding_buf; |
| 5088 | encode_coding (coding, (char *) buf, SDATA (object), | 5190 | encode_coding (coding, (char *) buf, SDATA (object), |
| 5089 | len, SBYTES (object)); | 5191 | len, SBYTES (object)); |
| 5090 | len = coding->produced; | 5192 | len = coding->produced; |
| @@ -5102,8 +5204,7 @@ send_process (proc, buf, len, object) | |||
| 5102 | if (pty_max_bytes == 0) | 5204 | if (pty_max_bytes == 0) |
| 5103 | { | 5205 | { |
| 5104 | #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) | 5206 | #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) |
| 5105 | pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), | 5207 | pty_max_bytes = fpathconf (XFASTINT (p->outfd), _PC_MAX_CANON); |
| 5106 | _PC_MAX_CANON); | ||
| 5107 | if (pty_max_bytes < 0) | 5208 | if (pty_max_bytes < 0) |
| 5108 | pty_max_bytes = 250; | 5209 | pty_max_bytes = 250; |
| 5109 | #else | 5210 | #else |
| @@ -5126,7 +5227,7 @@ send_process (proc, buf, len, object) | |||
| 5126 | 5227 | ||
| 5127 | /* Decide how much data we can send in one batch. | 5228 | /* Decide how much data we can send in one batch. |
| 5128 | Long lines need to be split into multiple batches. */ | 5229 | Long lines need to be split into multiple batches. */ |
| 5129 | if (!NILP (XPROCESS (proc)->pty_flag)) | 5230 | if (!NILP (p->pty_flag)) |
| 5130 | { | 5231 | { |
| 5131 | /* Starting this at zero is always correct when not the first | 5232 | /* Starting this at zero is always correct when not the first |
| 5132 | iteration because the previous iteration ended by sending C-d. | 5233 | iteration because the previous iteration ended by sending C-d. |
| @@ -5155,7 +5256,7 @@ send_process (proc, buf, len, object) | |||
| 5155 | /* Send this batch, using one or more write calls. */ | 5256 | /* Send this batch, using one or more write calls. */ |
| 5156 | while (this > 0) | 5257 | while (this > 0) |
| 5157 | { | 5258 | { |
| 5158 | int outfd = XINT (XPROCESS (proc)->outfd); | 5259 | int outfd = XINT (p->outfd); |
| 5159 | old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); | 5260 | old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); |
| 5160 | #ifdef DATAGRAM_SOCKETS | 5261 | #ifdef DATAGRAM_SOCKETS |
| 5161 | if (DATAGRAM_CHAN_P (outfd)) | 5262 | if (DATAGRAM_CHAN_P (outfd)) |
| @@ -5168,7 +5269,18 @@ send_process (proc, buf, len, object) | |||
| 5168 | } | 5269 | } |
| 5169 | else | 5270 | else |
| 5170 | #endif | 5271 | #endif |
| 5171 | rv = emacs_write (outfd, (char *) buf, this); | 5272 | { |
| 5273 | rv = emacs_write (outfd, (char *) buf, this); | ||
| 5274 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 5275 | if (XINT (p->read_output_delay) > 0 | ||
| 5276 | && EQ (p->adaptive_read_buffering, Qt)) | ||
| 5277 | { | ||
| 5278 | XSETFASTINT (p->read_output_delay, 0); | ||
| 5279 | process_output_delay_count--; | ||
| 5280 | p->read_output_skip = Qnil; | ||
| 5281 | } | ||
| 5282 | #endif | ||
| 5283 | } | ||
| 5172 | signal (SIGPIPE, old_sigpipe); | 5284 | signal (SIGPIPE, old_sigpipe); |
| 5173 | 5285 | ||
| 5174 | if (rv < 0) | 5286 | if (rv < 0) |
| @@ -5209,8 +5321,7 @@ send_process (proc, buf, len, object) | |||
| 5209 | if (errno == EAGAIN) | 5321 | if (errno == EAGAIN) |
| 5210 | { | 5322 | { |
| 5211 | int flags = FWRITE; | 5323 | int flags = FWRITE; |
| 5212 | ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH, | 5324 | ioctl (XINT (p->outfd), TIOCFLUSH, &flags); |
| 5213 | &flags); | ||
| 5214 | } | 5325 | } |
| 5215 | #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ | 5326 | #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ |
| 5216 | 5327 | ||
| @@ -5255,18 +5366,17 @@ send_process (proc, buf, len, object) | |||
| 5255 | { | 5366 | { |
| 5256 | #ifndef VMS | 5367 | #ifndef VMS |
| 5257 | proc = process_sent_to; | 5368 | proc = process_sent_to; |
| 5369 | p = XPROCESS (proc); | ||
| 5258 | #endif | 5370 | #endif |
| 5259 | XPROCESS (proc)->raw_status_low = Qnil; | 5371 | p->raw_status_low = Qnil; |
| 5260 | XPROCESS (proc)->raw_status_high = Qnil; | 5372 | p->raw_status_high = Qnil; |
| 5261 | XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); | 5373 | p->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); |
| 5262 | XSETINT (XPROCESS (proc)->tick, ++process_tick); | 5374 | XSETINT (p->tick, ++process_tick); |
| 5263 | deactivate_process (proc); | 5375 | deactivate_process (proc); |
| 5264 | #ifdef VMS | 5376 | #ifdef VMS |
| 5265 | error ("Error writing to process %s; closed it", | 5377 | error ("Error writing to process %s; closed it", SDATA (p->name)); |
| 5266 | SDATA (XPROCESS (proc)->name)); | ||
| 5267 | #else | 5378 | #else |
| 5268 | error ("SIGPIPE raised on process %s; closed it", | 5379 | error ("SIGPIPE raised on process %s; closed it", SDATA (p->name)); |
| 5269 | SDATA (XPROCESS (proc)->name)); | ||
| 5270 | #endif | 5380 | #endif |
| 5271 | } | 5381 | } |
| 5272 | 5382 | ||
| @@ -6503,6 +6613,11 @@ init_process () | |||
| 6503 | FD_ZERO (&non_process_wait_mask); | 6613 | FD_ZERO (&non_process_wait_mask); |
| 6504 | max_process_desc = 0; | 6614 | max_process_desc = 0; |
| 6505 | 6615 | ||
| 6616 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 6617 | process_output_delay_count = 0; | ||
| 6618 | process_output_skip = 0; | ||
| 6619 | #endif | ||
| 6620 | |||
| 6506 | FD_SET (0, &input_wait_mask); | 6621 | FD_SET (0, &input_wait_mask); |
| 6507 | 6622 | ||
| 6508 | Vprocess_alist = Qnil; | 6623 | Vprocess_alist = Qnil; |
| @@ -6636,6 +6751,20 @@ then a pipe is used in any case. | |||
| 6636 | The value takes effect when `start-process' is called. */); | 6751 | The value takes effect when `start-process' is called. */); |
| 6637 | Vprocess_connection_type = Qt; | 6752 | Vprocess_connection_type = Qt; |
| 6638 | 6753 | ||
| 6754 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 6755 | DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering, | ||
| 6756 | doc: /* If non-nil, improve receive buffering by delaying after short reads. | ||
| 6757 | On some systems, when emacs reads the output from a subprocess, the output data | ||
| 6758 | is read in very small blocks, potentially resulting in very poor performance. | ||
| 6759 | This behaviour can be remedied to some extent by setting this variable to a | ||
| 6760 | non-nil value, as it will automatically delay reading from such processes, to | ||
| 6761 | allowing them to produce more output before emacs tries to read it. | ||
| 6762 | If the value is t, the delay is reset after each write to the process; any other | ||
| 6763 | non-nil value means that the delay is not reset on write. | ||
| 6764 | The variable takes effect when `start-process' is called. */); | ||
| 6765 | Vprocess_adaptive_read_buffering = Qt; | ||
| 6766 | #endif | ||
| 6767 | |||
| 6639 | defsubr (&Sprocessp); | 6768 | defsubr (&Sprocessp); |
| 6640 | defsubr (&Sget_process); | 6769 | defsubr (&Sget_process); |
| 6641 | defsubr (&Sget_buffer_process); | 6770 | defsubr (&Sget_buffer_process); |