aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/lispref/elisp.texi3
-rw-r--r--doc/lispref/objects.texi69
-rw-r--r--src/lisp.h2
-rw-r--r--src/regex.c1
-rw-r--r--src/thread.c71
-rw-r--r--src/xgselect.c3
6 files changed, 114 insertions, 35 deletions
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 415dbe66fac..4a53a0cd364 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -349,6 +349,9 @@ Editing Types
349* Window Configuration Type:: Recording the way a frame is subdivided. 349* Window Configuration Type:: Recording the way a frame is subdivided.
350* Frame Configuration Type:: Recording the status of all frames. 350* Frame Configuration Type:: Recording the status of all frames.
351* Process Type:: A subprocess of Emacs running on the underlying OS. 351* Process Type:: A subprocess of Emacs running on the underlying OS.
352* Thread Type:: A thread of Emacs Lisp execution.
353* Mutex Type:: An exclusive lock for thread synchronization.
354* Condition Variable Type:: Condition variable for thread synchronization.
352* Stream Type:: Receive or send characters. 355* Stream Type:: Receive or send characters.
353* Keymap Type:: What function a keystroke invokes. 356* Keymap Type:: What function a keystroke invokes.
354* Overlay Type:: How an overlay is represented. 357* Overlay Type:: How an overlay is represented.
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index a76fbb1af7f..5e608bcc093 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -1410,6 +1410,9 @@ editing.
1410* Window Configuration Type:: Recording the way a frame is subdivided. 1410* Window Configuration Type:: Recording the way a frame is subdivided.
1411* Frame Configuration Type:: Recording the status of all frames. 1411* Frame Configuration Type:: Recording the status of all frames.
1412* Process Type:: A subprocess of Emacs running on the underlying OS. 1412* Process Type:: A subprocess of Emacs running on the underlying OS.
1413* Thread Type:: A thread of Emacs Lisp execution.
1414* Mutex Type:: An exclusive lock for thread synchronization.
1415* Condition Variable Type:: Condition variable for thread synchronization.
1413* Stream Type:: Receive or send characters. 1416* Stream Type:: Receive or send characters.
1414* Keymap Type:: What function a keystroke invokes. 1417* Keymap Type:: What function a keystroke invokes.
1415* Overlay Type:: How an overlay is represented. 1418* Overlay Type:: How an overlay is represented.
@@ -1625,6 +1628,63 @@ giving the name of the process:
1625return information about, send input or signals to, and receive output 1628return information about, send input or signals to, and receive output
1626from processes. 1629from processes.
1627 1630
1631@node Thread Type
1632@subsection Thread Type
1633
1634 A @dfn{thread} in Emacs represents a separate thread of Emacs Lisp
1635execution. It runs its own Lisp program, has its own current buffer,
1636and can have subprocesses locked to it, i.e.@: subprocesses whose
1637output only this thread can accept. @xref{Threads}.
1638
1639 Thread objects have no read syntax. They print in hash notation,
1640giving the name of the thread (if it has been given a name) or its
1641address in core:
1642
1643@example
1644@group
1645(all-threads)
1646 @result{} (#<thread 0176fc40>)
1647@end group
1648@end example
1649
1650@node Mutex Type
1651@subsection Mutex Type
1652
1653 A @dfn{mutex} is an exclusive lock that threads can own and disown,
1654in order to synchronize between them. @xref{Mutexes}.
1655
1656 Mutex objects have no read syntax. They print in hash notation,
1657giving the name of the mutex (if it has been given a name) or its
1658address in core:
1659
1660@example
1661@group
1662(make-mutex "my-mutex")
1663 @result{} #<mutex my-mutex>
1664(make-mutex)
1665 @result{} #<mutex 01c7e4e0>
1666@end group
1667@end example
1668
1669@node Condition Variable Type
1670@subsection Condition Variable Type
1671
1672 A @dfn{condition variable} is a device for a more complex thread
1673synchronization than the one supported by a mutex. A thread can wait
1674on a condition variable, to be woken up when some other thread
1675notifies the condition.
1676
1677 Condition variable objects have no read syntax. They print in hash
1678notation, giving the name of the condition variable (if it has been
1679given a name) or its address in core:
1680
1681@example
1682@group
1683(make-condition-variable (make-mutex))
1684 @result{} #<condvar 01c45ae8>
1685@end group
1686@end example
1687
1628@node Stream Type 1688@node Stream Type
1629@subsection Stream Type 1689@subsection Stream Type
1630 1690
@@ -1830,6 +1890,9 @@ with references to further information.
1830@item commandp 1890@item commandp
1831@xref{Interactive Call, commandp}. 1891@xref{Interactive Call, commandp}.
1832 1892
1893@item condition-variable-p
1894@xref{Condition Variables, condition-variable-p}.
1895
1833@item consp 1896@item consp
1834@xref{List-related Predicates, consp}. 1897@xref{List-related Predicates, consp}.
1835 1898
@@ -1875,6 +1938,9 @@ with references to further information.
1875@item markerp 1938@item markerp
1876@xref{Predicates on Markers, markerp}. 1939@xref{Predicates on Markers, markerp}.
1877 1940
1941@item mutexp
1942@xref{Mutexes, mutexp}.
1943
1878@item wholenump 1944@item wholenump
1879@xref{Predicates on Numbers, wholenump}. 1945@xref{Predicates on Numbers, wholenump}.
1880 1946
@@ -1908,6 +1974,9 @@ with references to further information.
1908@item syntax-table-p 1974@item syntax-table-p
1909@xref{Syntax Tables, syntax-table-p}. 1975@xref{Syntax Tables, syntax-table-p}.
1910 1976
1977@item threadp
1978@xref{Basic Thread Functions, threadp}.
1979
1911@item vectorp 1980@item vectorp
1912@xref{Vectors, vectorp}. 1981@xref{Vectors, vectorp}.
1913 1982
diff --git a/src/lisp.h b/src/lisp.h
index 72ea50d5f27..3c7c3dde904 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -845,6 +845,7 @@ enum pvec_type
845 PVEC_THREAD, 845 PVEC_THREAD,
846 PVEC_MUTEX, 846 PVEC_MUTEX,
847 PVEC_CONDVAR, 847 PVEC_CONDVAR,
848
848 /* These should be last, check internal_equal to see why. */ 849 /* These should be last, check internal_equal to see why. */
849 PVEC_COMPILED, 850 PVEC_COMPILED,
850 PVEC_CHAR_TABLE, 851 PVEC_CHAR_TABLE,
@@ -3229,6 +3230,7 @@ union specbinding
3229 } bt; 3230 } bt;
3230 }; 3231 };
3231 3232
3233/* These 3 are defined as macros in thread.h. */
3232/* extern union specbinding *specpdl; */ 3234/* extern union specbinding *specpdl; */
3233/* extern union specbinding *specpdl_ptr; */ 3235/* extern union specbinding *specpdl_ptr; */
3234/* extern ptrdiff_t specpdl_size; */ 3236/* extern ptrdiff_t specpdl_size; */
diff --git a/src/regex.c b/src/regex.c
index e7231d3882b..f1686cf700c 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -1140,6 +1140,7 @@ print_double_string (re_char *where, re_char *string1, ssize_t size1,
1140#endif /* not DEBUG */ 1140#endif /* not DEBUG */
1141 1141
1142#ifndef emacs 1142#ifndef emacs
1143
1143/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can 1144/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
1144 also be assigned to arbitrarily: each pattern buffer stores its own 1145 also be assigned to arbitrarily: each pattern buffer stores its own
1145 syntax, so it can be changed between regex compilations. */ 1146 syntax, so it can be changed between regex compilations. */
diff --git a/src/thread.c b/src/thread.c
index dda262984c0..ae2ce3dc02b 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -144,7 +144,7 @@ static int
144lisp_mutex_unlock (lisp_mutex_t *mutex) 144lisp_mutex_unlock (lisp_mutex_t *mutex)
145{ 145{
146 if (mutex->owner != current_thread) 146 if (mutex->owner != current_thread)
147 error ("blah"); 147 error ("Cannot unlock mutex owned by another thread");
148 148
149 if (--mutex->count > 0) 149 if (--mutex->count > 0)
150 return 0; 150 return 0;
@@ -301,7 +301,7 @@ finalize_one_mutex (struct Lisp_Mutex *mutex)
301DEFUN ("make-condition-variable", 301DEFUN ("make-condition-variable",
302 Fmake_condition_variable, Smake_condition_variable, 302 Fmake_condition_variable, Smake_condition_variable,
303 1, 2, 0, 303 1, 2, 0,
304 doc: /* Make a condition variable. 304 doc: /* Make a condition variable associated with MUTEX.
305A condition variable provides a way for a thread to sleep while 305A condition variable provides a way for a thread to sleep while
306waiting for a state change. 306waiting for a state change.
307 307
@@ -355,27 +355,27 @@ condition_wait_callback (void *arg)
355} 355}
356 356
357DEFUN ("condition-wait", Fcondition_wait, Scondition_wait, 1, 1, 0, 357DEFUN ("condition-wait", Fcondition_wait, Scondition_wait, 1, 1, 0,
358 doc: /* Wait for the condition variable to be notified. 358 doc: /* Wait for the condition variable COND to be notified.
359CONDITION is the condition variable to wait on. 359COND is the condition variable to wait on.
360 360
361The mutex associated with CONDITION must be held when this is called. 361The mutex associated with COND must be held when this is called.
362It is an error if it is not held. 362It is an error if it is not held.
363 363
364This releases the mutex and waits for CONDITION to be notified or for 364This releases the mutex and waits for COND to be notified or for
365this thread to be signalled with `thread-signal'. When 365this thread to be signalled with `thread-signal'. When
366`condition-wait' returns, the mutex will again be locked by this 366`condition-wait' returns, COND's mutex will again be locked by
367thread. */) 367this thread. */)
368 (Lisp_Object condition) 368 (Lisp_Object cond)
369{ 369{
370 struct Lisp_CondVar *cvar; 370 struct Lisp_CondVar *cvar;
371 struct Lisp_Mutex *mutex; 371 struct Lisp_Mutex *mutex;
372 372
373 CHECK_CONDVAR (condition); 373 CHECK_CONDVAR (cond);
374 cvar = XCONDVAR (condition); 374 cvar = XCONDVAR (cond);
375 375
376 mutex = XMUTEX (cvar->mutex); 376 mutex = XMUTEX (cvar->mutex);
377 if (!lisp_mutex_owned_p (&mutex->mutex)) 377 if (!lisp_mutex_owned_p (&mutex->mutex))
378 error ("fixme"); 378 error ("Condition variable's mutex is not held by current thread");
379 379
380 flush_stack_call_func (condition_wait_callback, cvar); 380 flush_stack_call_func (condition_wait_callback, cvar);
381 381
@@ -409,28 +409,28 @@ condition_notify_callback (void *arg)
409} 409}
410 410
411DEFUN ("condition-notify", Fcondition_notify, Scondition_notify, 1, 2, 0, 411DEFUN ("condition-notify", Fcondition_notify, Scondition_notify, 1, 2, 0,
412 doc: /* Notify a condition variable. 412 doc: /* Notify COND, a condition variable.
413This wakes a thread waiting on CONDITION. 413This wakes a thread waiting on COND.
414If ALL is non-nil, all waiting threads are awoken. 414If ALL is non-nil, all waiting threads are awoken.
415 415
416The mutex associated with CONDITION must be held when this is called. 416The mutex associated with COND must be held when this is called.
417It is an error if it is not held. 417It is an error if it is not held.
418 418
419This releases the mutex when notifying CONDITION. When 419This releases COND's mutex when notifying COND. When
420`condition-notify' returns, the mutex will again be locked by this 420`condition-notify' returns, the mutex will again be locked by this
421thread. */) 421thread. */)
422 (Lisp_Object condition, Lisp_Object all) 422 (Lisp_Object cond, Lisp_Object all)
423{ 423{
424 struct Lisp_CondVar *cvar; 424 struct Lisp_CondVar *cvar;
425 struct Lisp_Mutex *mutex; 425 struct Lisp_Mutex *mutex;
426 struct notify_args args; 426 struct notify_args args;
427 427
428 CHECK_CONDVAR (condition); 428 CHECK_CONDVAR (cond);
429 cvar = XCONDVAR (condition); 429 cvar = XCONDVAR (cond);
430 430
431 mutex = XMUTEX (cvar->mutex); 431 mutex = XMUTEX (cvar->mutex);
432 if (!lisp_mutex_owned_p (&mutex->mutex)) 432 if (!lisp_mutex_owned_p (&mutex->mutex))
433 error ("fixme"); 433 error ("Condition variable's mutex is not held by current thread");
434 434
435 args.cvar = cvar; 435 args.cvar = cvar;
436 args.all = !NILP (all); 436 args.all = !NILP (all);
@@ -440,26 +440,26 @@ thread. */)
440} 440}
441 441
442DEFUN ("condition-mutex", Fcondition_mutex, Scondition_mutex, 1, 1, 0, 442DEFUN ("condition-mutex", Fcondition_mutex, Scondition_mutex, 1, 1, 0,
443 doc: /* Return the mutex associated with CONDITION. */) 443 doc: /* Return the mutex associated with condition variable COND. */)
444 (Lisp_Object condition) 444 (Lisp_Object cond)
445{ 445{
446 struct Lisp_CondVar *cvar; 446 struct Lisp_CondVar *cvar;
447 447
448 CHECK_CONDVAR (condition); 448 CHECK_CONDVAR (cond);
449 cvar = XCONDVAR (condition); 449 cvar = XCONDVAR (cond);
450 450
451 return cvar->mutex; 451 return cvar->mutex;
452} 452}
453 453
454DEFUN ("condition-name", Fcondition_name, Scondition_name, 1, 1, 0, 454DEFUN ("condition-name", Fcondition_name, Scondition_name, 1, 1, 0,
455 doc: /* Return the name of CONDITION. 455 doc: /* Return the name of condition variable COND.
456If no name was given when CONDITION was created, return nil. */) 456If no name was given when COND was created, return nil. */)
457 (Lisp_Object condition) 457 (Lisp_Object cond)
458{ 458{
459 struct Lisp_CondVar *cvar; 459 struct Lisp_CondVar *cvar;
460 460
461 CHECK_CONDVAR (condition); 461 CHECK_CONDVAR (cond);
462 cvar = XCONDVAR (condition); 462 cvar = XCONDVAR (cond);
463 463
464 return cvar->name; 464 return cvar->name;
465} 465}
@@ -540,7 +540,7 @@ mark_one_thread (struct thread_state *thread)
540 540
541 mark_object (thread->m_last_thing_searched); 541 mark_object (thread->m_last_thing_searched);
542 542
543 if (thread->m_saved_last_thing_searched) 543 if (!NILP (thread->m_saved_last_thing_searched))
544 mark_object (thread->m_saved_last_thing_searched); 544 mark_object (thread->m_saved_last_thing_searched);
545} 545}
546 546
@@ -678,7 +678,7 @@ finalize_one_thread (struct thread_state *state)
678DEFUN ("make-thread", Fmake_thread, Smake_thread, 1, 2, 0, 678DEFUN ("make-thread", Fmake_thread, Smake_thread, 1, 2, 0,
679 doc: /* Start a new thread and run FUNCTION in it. 679 doc: /* Start a new thread and run FUNCTION in it.
680When the function exits, the thread dies. 680When the function exits, the thread dies.
681If NAME is given, it names the new thread. */) 681If NAME is given, it must be a string; it names the new thread. */)
682 (Lisp_Object function, Lisp_Object name) 682 (Lisp_Object function, Lisp_Object name)
683{ 683{
684 sys_thread_t thr; 684 sys_thread_t thr;
@@ -843,8 +843,9 @@ thread_join_callback (void *arg)
843} 843}
844 844
845DEFUN ("thread-join", Fthread_join, Sthread_join, 1, 1, 0, 845DEFUN ("thread-join", Fthread_join, Sthread_join, 1, 1, 0,
846 doc: /* Wait for a thread to exit. 846 doc: /* Wait for THREAD to exit.
847This blocks the current thread until THREAD exits. 847This blocks the current thread until THREAD exits or until
848the current thread is signaled.
848It is an error for a thread to try to join itself. */) 849It is an error for a thread to try to join itself. */)
849 (Lisp_Object thread) 850 (Lisp_Object thread)
850{ 851{
@@ -854,7 +855,7 @@ It is an error for a thread to try to join itself. */)
854 tstate = XTHREAD (thread); 855 tstate = XTHREAD (thread);
855 856
856 if (tstate == current_thread) 857 if (tstate == current_thread)
857 error ("cannot join current thread"); 858 error ("Cannot join current thread");
858 859
859 if (thread_alive_p (tstate)) 860 if (thread_alive_p (tstate))
860 flush_stack_call_func (thread_join_callback, tstate); 861 flush_stack_call_func (thread_join_callback, tstate);
@@ -863,7 +864,7 @@ It is an error for a thread to try to join itself. */)
863} 864}
864 865
865DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0, 866DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0,
866 doc: /* Return a list of all threads. */) 867 doc: /* Return a list of all the live threads. */)
867 (void) 868 (void)
868{ 869{
869 Lisp_Object result = Qnil; 870 Lisp_Object result = Qnil;
diff --git a/src/xgselect.c b/src/xgselect.c
index e418e1a3c4e..2f23764ae41 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -76,6 +76,9 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
76 76
77 if (gfds_size < n_gfds) 77 if (gfds_size < n_gfds)
78 { 78 {
79 /* Avoid using SAFE_NALLOCA, as that implicitly refers to the
80 current thread. Using xnmalloc avoids thread-switching
81 problems here. */
79 gfds = xnmalloc (n_gfds, sizeof *gfds); 82 gfds = xnmalloc (n_gfds, sizeof *gfds);
80 must_free = 1; 83 must_free = 1;
81 gfds_size = n_gfds; 84 gfds_size = n_gfds;