aboutsummaryrefslogtreecommitdiffstats
path: root/src/thread.c
diff options
context:
space:
mode:
authorTom Tromey2012-08-15 13:19:24 -0600
committerTom Tromey2012-08-15 13:19:24 -0600
commit6c0d5ae50789673f53c834084bbe1f62f5a62731 (patch)
tree0f976b74b292b2a4714470eebb2ce39548d47678 /src/thread.c
parentaa14ccd1e2edec2735f9200a4f2e5eee3b0abe09 (diff)
downloademacs-6c0d5ae50789673f53c834084bbe1f62f5a62731.tar.gz
emacs-6c0d5ae50789673f53c834084bbe1f62f5a62731.zip
process changes
This changes wait_reading_process_output to handle threads better. It introduces a wrapper for select that releases the global lock, and it ensures that only a single thread can select a given file descriptor at a time. This also adds the thread-locking feature to processes. By default a process can only have its output accepted by the thread that created it. This can be changed using set-process-thread. (If the thread exits, the process is again available for waiting by any thread.) Note that thread-signal will not currently interrupt a thread blocked on select. I'll fix this later.
Diffstat (limited to 'src/thread.c')
-rw-r--r--src/thread.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/thread.c b/src/thread.c
index 40c8be9f4d5..be98b4aae1d 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -22,6 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include "lisp.h" 22#include "lisp.h"
23#include "character.h" 23#include "character.h"
24#include "buffer.h" 24#include "buffer.h"
25#include "process.h"
25 26
26/* FIXME */ 27/* FIXME */
27extern void unbind_for_thread_switch (void); 28extern void unbind_for_thread_switch (void);
@@ -176,6 +177,50 @@ acquire_global_lock (struct thread_state *self)
176 177
177 178
178 179
180struct select_args
181{
182 select_func *func;
183 int max_fds;
184 SELECT_TYPE *rfds;
185 SELECT_TYPE *wfds;
186 SELECT_TYPE *efds;
187 EMACS_TIME *timeout;
188 sigset_t *sigmask;
189 int result;
190};
191
192static void
193really_call_select (void *arg)
194{
195 struct select_args *sa = arg;
196 struct thread_state *self = current_thread;
197
198 release_global_lock ();
199 sa->result = (sa->func) (sa->max_fds, sa->rfds, sa->wfds, sa->efds,
200 sa->timeout, sa->sigmask);
201 acquire_global_lock (self);
202}
203
204int
205thread_select (select_func *func, int max_fds, SELECT_TYPE *rfds,
206 SELECT_TYPE *wfds, SELECT_TYPE *efds, EMACS_TIME *timeout,
207 sigset_t *sigmask)
208{
209 struct select_args sa;
210
211 sa.func = func;
212 sa.max_fds = max_fds;
213 sa.rfds = rfds;
214 sa.wfds = wfds;
215 sa.efds = efds;
216 sa.timeout = timeout;
217 sa.sigmask = sigmask;
218 flush_stack_call_func (really_call_select, &sa);
219 return sa.result;
220}
221
222
223
179static void 224static void
180mark_one_thread (struct thread_state *thread) 225mark_one_thread (struct thread_state *thread)
181{ 226{
@@ -315,6 +360,8 @@ run_thread (void *state)
315 360
316 unbind_for_thread_switch (); 361 unbind_for_thread_switch ();
317 362
363 update_processes_for_thread_death (Fcurrent_thread ());
364
318 /* Unlink this thread from the list of all threads. */ 365 /* Unlink this thread from the list of all threads. */
319 for (iter = &all_threads; *iter != self; iter = &(*iter)->next_thread) 366 for (iter = &all_threads; *iter != self; iter = &(*iter)->next_thread)
320 ; 367 ;