diff options
| author | Karoly Lorentey | 2004-01-02 04:37:46 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-01-02 04:37:46 +0000 |
| commit | eb9332fa2e41dbe54f5427b9383cb4028a6f926f (patch) | |
| tree | 4f05548846c10ed0642893c1495882d670e90e4c /src | |
| parent | fa971ac34de80905a91d2af15dd8712329dad273 (diff) | |
| parent | 31e0fbdd4308bde64849bbfa0327a2a77797b3e9 (diff) | |
| download | emacs-eb9332fa2e41dbe54f5427b9383cb4028a6f926f.tar.gz emacs-eb9332fa2e41dbe54f5427b9383cb4028a6f926f.zip | |
Merged in changes from CVS HEAD
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-10
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-11
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-12
Add section on button package to lisp reference manual
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-13
Minor tweaks to Buttons section in lispref/display.texi
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-14
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-33
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 37 | ||||
| -rw-r--r-- | src/eval.c | 2 | ||||
| -rw-r--r-- | src/print.c | 4 | ||||
| -rw-r--r-- | src/process.c | 199 | ||||
| -rw-r--r-- | src/process.h | 12 | ||||
| -rw-r--r-- | src/w32term.c | 6 |
6 files changed, 221 insertions, 39 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 121142703c9..d5bf5ba7aa9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,40 @@ | |||
| 1 | 2004-01-02 Kim F. Storm <storm@cua.dk> | ||
| 2 | |||
| 3 | * process.h (struct Lisp_Process): New members for adaptive read | ||
| 4 | buffering: adaptive_read_buffering, read_output_delay, and | ||
| 5 | read_output_skip. | ||
| 6 | |||
| 7 | * process.c (ADAPTIVE_READ_BUFFERING): New conditional. | ||
| 8 | (READ_OUTPUT_DELAY_INCREMENT, READ_OUTPUT_DELAY_MAX) | ||
| 9 | (READ_OUTPUT_DELAY_MAX_MAX): New constants. | ||
| 10 | (process_output_delay_count, process_output_skip): New vars. | ||
| 11 | (Vprocess_adaptive_read_buffering): New variable. | ||
| 12 | (make_process): Initialize adaptive read buffering members. | ||
| 13 | (Fstart_process): Set adaptive_read_buffering member. | ||
| 14 | (deactivate_process): Cleanup adaptive read buffering. | ||
| 15 | (wait_reading_process_input): Temporarily omit delayed | ||
| 16 | subprocesses from the set of file descriptors to read from; | ||
| 17 | adjust the select timeout if we skipped any subprocesses. | ||
| 18 | (read_process_output): Increase adaptive read buffering delay if | ||
| 19 | we read less than a full buffer; reduce delay when we read a | ||
| 20 | full buffer. | ||
| 21 | (send_process): Simplify using local Lisp_Process var. | ||
| 22 | Reset adaptive read buffering delay after write. | ||
| 23 | (init_process): Initialize process_output_delay_count and | ||
| 24 | process_output_skip. | ||
| 25 | (syms_of_process): DEFVAR_LISP Vprocess_adaptive_read_buffering. | ||
| 26 | |||
| 27 | 2004-01-01 Jason Rumney <jasonr@gnu.org> | ||
| 28 | |||
| 29 | * w32term.c (w32_text_out): Use s->font, for consistency with | ||
| 30 | callers. | ||
| 31 | |||
| 32 | 2003-12-30 Luc Teirlinck <teirllm@auburn.edu> | ||
| 33 | |||
| 34 | * print.c (Ferror_message_string): Add hyperlink in the docstring | ||
| 35 | to the definition of `signal' in the Elisp manual. | ||
| 36 | * eval.c (Fsignal): Ditto. | ||
| 37 | |||
| 1 | 2003-12-29 James Clark <jjc@jclark.com> (tiny change) | 38 | 2003-12-29 James Clark <jjc@jclark.com> (tiny change) |
| 2 | 39 | ||
| 3 | * fns.c (internal_equal): Return t for two NaN arguments. | 40 | * fns.c (internal_equal): Return t for two NaN arguments. |
diff --git a/src/eval.c b/src/eval.c index 8a6d0d3ff54..a5f66b295a6 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1436,6 +1436,8 @@ A handler for any of those names will get to handle this signal. | |||
| 1436 | The symbol `error' should normally be one of them. | 1436 | The symbol `error' should normally be one of them. |
| 1437 | 1437 | ||
| 1438 | DATA should be a list. Its elements are printed as part of the error message. | 1438 | DATA should be a list. Its elements are printed as part of the error message. |
| 1439 | See Info anchor `(elisp)Definition of signal' for some details on how this | ||
| 1440 | error message is constructed. | ||
| 1439 | If the signal is handled, DATA is made available to the handler. | 1441 | If the signal is handled, DATA is made available to the handler. |
| 1440 | See also the function `condition-case'. */) | 1442 | See also the function `condition-case'. */) |
| 1441 | (error_symbol, data) | 1443 | (error_symbol, data) |
diff --git a/src/print.c b/src/print.c index af76616e42b..2560f5f3e26 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -967,7 +967,9 @@ debug_print (arg) | |||
| 967 | 967 | ||
| 968 | DEFUN ("error-message-string", Ferror_message_string, Serror_message_string, | 968 | DEFUN ("error-message-string", Ferror_message_string, Serror_message_string, |
| 969 | 1, 1, 0, | 969 | 1, 1, 0, |
| 970 | doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error message. */) | 970 | doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error message. |
| 971 | See Info anchor `(elisp)Definition of signal' for some details on how this | ||
| 972 | error message is constructed. */) | ||
| 971 | (obj) | 973 | (obj) |
| 972 | Lisp_Object obj; | 974 | Lisp_Object obj; |
| 973 | { | 975 | { |
diff --git a/src/process.c b/src/process.c index 3334f3258ae..906497f14ed 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 | ||
| @@ -6493,6 +6603,11 @@ init_process () | |||
| 6493 | FD_ZERO (&non_process_wait_mask); | 6603 | FD_ZERO (&non_process_wait_mask); |
| 6494 | max_process_desc = 0; | 6604 | max_process_desc = 0; |
| 6495 | 6605 | ||
| 6606 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 6607 | process_output_delay_count = 0; | ||
| 6608 | process_output_skip = 0; | ||
| 6609 | #endif | ||
| 6610 | |||
| 6496 | FD_SET (0, &input_wait_mask); | 6611 | FD_SET (0, &input_wait_mask); |
| 6497 | 6612 | ||
| 6498 | Vprocess_alist = Qnil; | 6613 | Vprocess_alist = Qnil; |
| @@ -6626,6 +6741,20 @@ then a pipe is used in any case. | |||
| 6626 | The value takes effect when `start-process' is called. */); | 6741 | The value takes effect when `start-process' is called. */); |
| 6627 | Vprocess_connection_type = Qt; | 6742 | Vprocess_connection_type = Qt; |
| 6628 | 6743 | ||
| 6744 | #ifdef ADAPTIVE_READ_BUFFERING | ||
| 6745 | DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering, | ||
| 6746 | doc: /* If non-nil, improve receive buffering by delaying after short reads. | ||
| 6747 | On some systems, when emacs reads the output from a subprocess, the output data | ||
| 6748 | is read in very small blocks, potentially resulting in very poor performance. | ||
| 6749 | This behaviour can be remedied to some extent by setting this variable to a | ||
| 6750 | non-nil value, as it will automatically delay reading from such processes, to | ||
| 6751 | allowing them to produce more output before emacs tries to read it. | ||
| 6752 | If the value is t, the delay is reset after each write to the process; any other | ||
| 6753 | non-nil value means that the delay is not reset on write. | ||
| 6754 | The variable takes effect when `start-process' is called. */); | ||
| 6755 | Vprocess_adaptive_read_buffering = Qt; | ||
| 6756 | #endif | ||
| 6757 | |||
| 6629 | defsubr (&Sprocessp); | 6758 | defsubr (&Sprocessp); |
| 6630 | defsubr (&Sget_process); | 6759 | defsubr (&Sget_process); |
| 6631 | defsubr (&Sget_buffer_process); | 6760 | defsubr (&Sget_buffer_process); |
diff --git a/src/process.h b/src/process.h index 63680a0ed8e..2f46e74d4d0 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -101,6 +101,18 @@ struct Lisp_Process | |||
| 101 | generated, and can be changed by the function | 101 | generated, and can be changed by the function |
| 102 | `set-process-fileter-multibyte'. */ | 102 | `set-process-fileter-multibyte'. */ |
| 103 | Lisp_Object filter_multibyte; | 103 | Lisp_Object filter_multibyte; |
| 104 | /* Should we delay reading output from this process. | ||
| 105 | Initialized from `Vprocess_adaptive_read_buffering'. */ | ||
| 106 | Lisp_Object adaptive_read_buffering; | ||
| 107 | /* Hysteresis to try to read process output in larger blocks. | ||
| 108 | On some systems, e.g. the Linux kernel, emacs is seen as | ||
| 109 | an interactive app also when reading process output, meaning | ||
| 110 | that process output can be read in as little as 1 byte at a | ||
| 111 | time. Value is micro-seconds to delay reading output from | ||
| 112 | this process. Range is 0 .. 50000. */ | ||
| 113 | Lisp_Object read_output_delay; | ||
| 114 | /* Skip reading this process on next read. */ | ||
| 115 | Lisp_Object read_output_skip; | ||
| 104 | }; | 116 | }; |
| 105 | 117 | ||
| 106 | /* Every field in the preceding structure except for the first two | 118 | /* Every field in the preceding structure except for the first two |
diff --git a/src/w32term.c b/src/w32term.c index 6da7f612ec9..bee1a1913ff 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -1121,9 +1121,9 @@ w32_text_out (s, x, y,chars,nchars) | |||
| 1121 | wchar_t * chars; | 1121 | wchar_t * chars; |
| 1122 | int nchars; | 1122 | int nchars; |
| 1123 | { | 1123 | { |
| 1124 | int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1; | 1124 | int charset_dim = w32_font_is_double_byte (s->font) ? 2 : 1; |
| 1125 | if (s->gc->font->bdf) | 1125 | if (s->font->bdf) |
| 1126 | w32_BDF_TextOut (s->gc->font->bdf, s->hdc, | 1126 | w32_BDF_TextOut (s->font->bdf, s->hdc, |
| 1127 | x, y, (char *) chars, charset_dim, | 1127 | x, y, (char *) chars, charset_dim, |
| 1128 | nchars * charset_dim, 0); | 1128 | nchars * charset_dim, 0); |
| 1129 | else if (s->first_glyph->font_type == UNICODE_FONT) | 1129 | else if (s->first_glyph->font_type == UNICODE_FONT) |