From: Tom Tromey Date: Tue, 20 Aug 2013 03:53:07 +0000 (-0600) Subject: merge from trunk X-Git-Tag: emacs-26.0.90~1144^2~17^2~22 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6d75555c5cc3d2a629646cee7629e67530fa7a36;p=emacs.git merge from trunk --- 6d75555c5cc3d2a629646cee7629e67530fa7a36 diff --cc src/Makefile.in index ce709a6bc44,f0ed770ac8f..5b1a7b525d0 --- a/src/Makefile.in +++ b/src/Makefile.in @@@ -374,8 -376,7 +376,8 @@@ base_obj = dispnew.o frame.o scroll.o x process.o gnutls.o callproc.o \ region-cache.o sound.o atimer.o \ doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \ - profiler.o \ + profiler.o decompress.o \ + thread.o systhread.o \ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) obj = $(base_obj) $(NS_OBJC_OBJ) diff --cc src/emacs.c index 6d406407a9d,05384145330..e6d612b8417 --- a/src/emacs.c +++ b/src/emacs.c @@@ -685,11 -691,13 +684,12 @@@ main (int argc, char **argv #endif char *ch_to_dir; -#if GC_MARK_STACK - stack_base = &dummy; -#endif + /* Record (approximately) where the stack begins. */ + stack_bottom = &stack_bottom_variable; #ifdef G_SLICE_ALWAYS_MALLOC - /* This is used by the Cygwin build. */ + /* This is used by the Cygwin build. It's not needed starting with + cygwin-1.7.24, but it doesn't do any harm. */ xputenv ("G_SLICE=always-malloc"); #endif diff --cc src/eval.c index e93c3473ae8,566be0c2a83..d36defc8fe4 --- a/src/eval.c +++ b/src/eval.c @@@ -3301,83 -3273,7 +3338,80 @@@ record_unwind_protect_void (void (*func grow_specpdl (); } +void +rebind_for_thread_switch (void) +{ + union specbinding *bind; + + for (bind = specpdl; bind != specpdl_ptr; ++bind) + { + if (bind->kind >= SPECPDL_LET) + { + Lisp_Object value = specpdl_saved_value (bind); + + bind->let.saved_value = Qnil; + do_specbind (XSYMBOL (binding_symbol (bind)), bind, value); + } + } +} + static void +do_one_unbind (union specbinding *this_binding, int unwinding) +{ + eassert (unwinding || this_binding->kind >= SPECPDL_LET); + switch (this_binding->kind) + { + case SPECPDL_UNWIND: - specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg); ++ this_binding->unwind.func (this_binding->unwind.arg); + break; + case SPECPDL_UNWIND_PTR: - specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg); ++ this_binding->unwind_ptr.func (this_binding->unwind_ptr.arg); + break; + case SPECPDL_UNWIND_INT: - specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg); ++ this_binding->unwind_int.func (this_binding->unwind_int.arg); + break; + case SPECPDL_UNWIND_VOID: - specpdl_ptr->unwind_void.func (); ++ this_binding->unwind_void.func (); + break; + case SPECPDL_BACKTRACE: + break; + case SPECPDL_LET: - /* If variable has a trivial value (no forwarding), we can - just set it. No need to check for constant symbols here, - since that was already done by specbind. */ - if (XSYMBOL (specpdl_symbol (this_binding))->redirect - == SYMBOL_PLAINVAL) - SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (this_binding)), - specpdl_old_value (this_binding)); - else - /* NOTE: we only ever come here if make_local_foo was used for - the first time on this var within this let. */ - Fset_default (specpdl_symbol (this_binding), - specpdl_old_value (this_binding)); ++ { /* If variable has a trivial value (no forwarding), we can ++ just set it. No need to check for constant symbols here, ++ since that was already done by specbind. */ ++ struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (this_binding)); ++ if (sym->redirect == SYMBOL_PLAINVAL) ++ { ++ SET_SYMBOL_VAL (sym, specpdl_old_value (this_binding)); ++ break; ++ } ++ else ++ { /* FALLTHROUGH!! ++ NOTE: we only ever come here if make_local_foo was used for ++ the first time on this var within this let. */ ++ } ++ } ++ case SPECPDL_LET_DEFAULT: ++ Fset_default (specpdl_symbol (this_binding), ++ specpdl_old_value (this_binding)); + break; + case SPECPDL_LET_LOCAL: - case SPECPDL_LET_DEFAULT: - { /* If the symbol is a list, it is really (SYMBOL WHERE - . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a - frame. If WHERE is a buffer or frame, this indicates we - bound a variable that had a buffer-local or frame-local - binding. WHERE nil means that the variable had the default - value when it was bound. CURRENT-BUFFER is the buffer that - was current when the variable was bound. */ ++ { + Lisp_Object symbol = specpdl_symbol (this_binding); + Lisp_Object where = specpdl_where (this_binding); ++ Lisp_Object old_value = specpdl_old_value (this_binding); + eassert (BUFFERP (where)); + - if (this_binding->kind == SPECPDL_LET_DEFAULT) - Fset_default (symbol, specpdl_old_value (this_binding)); + /* If this was a local binding, reset the value in the appropriate + buffer, but only if that buffer's binding still exists. */ - else if (!NILP (Flocal_variable_p (symbol, where))) - set_internal (symbol, specpdl_old_value (this_binding), - where, 1); ++ if (!NILP (Flocal_variable_p (symbol, where))) ++ set_internal (symbol, old_value, where, 1); + } + break; + } +} + +void do_nothing (void) {} diff --cc src/lisp.h index 952991a32d9,e6e90e1e968..60a553cc7d1 --- a/src/lisp.h +++ b/src/lisp.h @@@ -3821,10 -3751,9 +3824,11 @@@ extern void record_unwind_protect_int ( extern void record_unwind_protect_void (void (*) (void)); extern void record_unwind_protect_nothing (void); extern void clear_unwind_protect (ptrdiff_t); + extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object); extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *); extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); +extern void rebind_for_thread_switch (void); +extern void unbind_for_thread_switch (void); extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); extern _Noreturn void verror (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0); diff --cc src/process.c index 33d8ccbbc35,c4dd87a6b48..91483e5839f --- a/src/process.c +++ b/src/process.c @@@ -301,8 -324,11 +302,8 @@@ static void exec_sentinel (Lisp_Object static int num_pending_connects; #endif /* NON_BLOCKING_CONNECT */ - /* The largest descriptor currently in use for input. */ -/* The largest descriptor currently in use for a process object; -1 if none. */ -static int max_process_desc; - -/* The largest descriptor currently in use for input; -1 if none. */ -static int max_input_desc; ++/* The largest descriptor currently in use; -1 if none. */ +static int max_desc; /* Indexed by descriptor, gives the process (if any) for that descriptor */ static Lisp_Object chan_process[MAXDESC]; @@@ -513,36 -504,25 +520,52 @@@ add_write_fd (int fd, fd_callback func fd_callback_info[fd].func = func; fd_callback_info[fd].data = data; - fd_callback_info[fd].condition |= FOR_WRITE; + fd_callback_info[fd].flags |= FOR_WRITE; +} + +static void +add_non_blocking_write_fd (int fd) +{ + eassert (fd >= 0 && fd < MAXDESC); + eassert (fd_callback_info[fd].func == NULL); + + fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD; + if (fd > max_desc) + max_desc = fd; + ++num_pending_connects; +} + +static void +recompute_max_desc (void) +{ + int fd; + + for (fd = max_desc; fd >= 0; --fd) + { + if (fd_callback_info[fd].flags != 0) + { + max_desc = fd; + break; + } + } } + /* FD is no longer an input descriptor; update max_input_desc accordingly. */ + + static void + delete_input_desc (int fd) + { + if (fd == max_input_desc) + { + do + fd--; + while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask) + || FD_ISSET (fd, &write_mask))); + + max_input_desc = fd; + } + } + /* Stop monitoring file descriptor FD for when write is possible. */ void @@@ -1869,10 -1715,13 +1922,10 @@@ create_process (Lisp_Object process, ch we just reopen the device (see emacs_get_tty_pgrp) as this is more portable (see USG_SUBTTY_WORKS above). */ - XPROCESS (process)->pty_flag = pty_flag; - pset_status (XPROCESS (process), Qrun); + p->pty_flag = pty_flag; + pset_status (p, Qrun); - FD_SET (inchannel, &input_wait_mask); - FD_SET (inchannel, &non_keyboard_wait_mask); - if (inchannel > max_process_desc) - max_process_desc = inchannel; + add_process_read_fd (inchannel); /* This may signal an error. */ setup_process_coding_systems (process); @@@ -2105,14 -1947,19 +2151,16 @@@ create_pty (Lisp_Object process we just reopen the device (see emacs_get_tty_pgrp) as this is more portable (see USG_SUBTTY_WORKS above). */ - XPROCESS (process)->pty_flag = 1; - pset_status (XPROCESS (process), Qrun); + p->pty_flag = 1; + pset_status (p, Qrun); setup_process_coding_systems (process); - pset_tty_name (XPROCESS (process), build_string (pty_name)); - FD_SET (pty_fd, &input_wait_mask); - FD_SET (pty_fd, &non_keyboard_wait_mask); - if (pty_fd > max_process_desc) - max_process_desc = pty_fd; ++ fixme; + + pset_tty_name (p, build_string (pty_name)); } - XPROCESS (process)->pid = -2; + p->pid = -2; } @@@ -2718,10 -2565,11 +2766,11 @@@ usage: (make-serial-process &rest ARGS p = XPROCESS (proc); fd = serial_open (port); + p->open_fd[SUBPROCESS_STDIN] = fd; p->infd = fd; p->outfd = fd; - if (fd > max_process_desc) - max_process_desc = fd; + if (fd > max_desc) + max_desc = fd; chan_process[fd] = proc; buffer = Fplist_get (contact, QCbuffer); @@@ -4672,18 -4552,18 +4726,18 @@@ wait_reading_process_output (intmax_t t process_output_skip = 0; } #endif - + nfds = thread_select ( #if defined (HAVE_NS) - nfds = ns_select + ns_select #elif defined (HAVE_GLIB) - nfds = xg_select + xg_select #else - nfds = pselect + pselect #endif - (max (max_process_desc, max_input_desc) + 1, - &Available, - (check_write ? &Writeok : 0), - NULL, &timeout, NULL); + , max_desc + 1, + &Available, - (check_write ? &Writeok : (SELECT_TYPE *)0), ++ (check_write ? &Writeok : 0), + NULL, &timeout, NULL); #ifdef HAVE_GNUTLS /* GnuTLS buffers data internally. In lowat mode it leaves @@@ -7183,7 -7062,11 +7230,7 @@@ init_process_emacs (void catch_child_signal (); } - max_desc = 0; - FD_ZERO (&input_wait_mask); - FD_ZERO (&non_keyboard_wait_mask); - FD_ZERO (&non_process_wait_mask); - FD_ZERO (&write_mask); - max_process_desc = max_input_desc = -1; ++ max_desc = -1; memset (fd_callback_info, 0, sizeof (fd_callback_info)); #ifdef NON_BLOCKING_CONNECT