aboutsummaryrefslogtreecommitdiffstats
path: root/test/src/thread-tests.el
diff options
context:
space:
mode:
authorEli Zaretskii2017-01-13 11:48:51 +0200
committerEli Zaretskii2017-01-13 11:48:51 +0200
commit03e4ab0d586069be65e4a17fbf4cd965a9984726 (patch)
tree729d86e3282165ca0d58bec8bde33661c9b60ed9 /test/src/thread-tests.el
parent62e27ebd54336d30a90ae71e5bdcb910e954c061 (diff)
downloademacs-03e4ab0d586069be65e4a17fbf4cd965a9984726.tar.gz
emacs-03e4ab0d586069be65e4a17fbf4cd965a9984726.zip
Fix a bug in waiting for condition variable
* src/thread.c (lisp_mutex_lock, lisp_mutex_unlock) (lisp_mutex_unlock_for_wait, condition_wait_callback) (condition_notify_callback): Improve commentary. (condition_wait_callback): Call post_acquire_global_lock before attempting to lock the mutex, to make sure the lock's owner is recorded correctly. * test/src/thread-tests.el (threads-condvar-wait): New test.
Diffstat (limited to 'test/src/thread-tests.el')
-rw-r--r--test/src/thread-tests.el41
1 files changed, 41 insertions, 0 deletions
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el
index 2e5a3bcc1fa..71b20185d76 100644
--- a/test/src/thread-tests.el
+++ b/test/src/thread-tests.el
@@ -244,4 +244,45 @@
244 (sit-for 1) 244 (sit-for 1)
245 (should-not (thread-alive-p thread)))) 245 (should-not (thread-alive-p thread))))
246 246
247(defvar threads-condvar nil)
248(defun threads-test-condvar-wait ()
249 ;; Wait for condvar to be notified
250 (mutex-lock (condition-mutex threads-condvar))
251 (condition-wait threads-condvar)
252 (mutex-unlock (condition-mutex threads-condvar))
253 ;; Wait again, it will be signaled.
254 (with-mutex (condition-mutex threads-condvar)
255 (condition-wait threads-condvar)))
256
257(ert-deftest threads-condvar-wait ()
258 "test waiting on conditional variable"
259 (let* ((cv-mutex (make-mutex))
260 (nthreads (length (all-threads)))
261 new-thread)
262 (setq threads-condvar (make-condition-variable cv-mutex))
263 (setq new-thread (make-thread #'threads-test-condvar-wait))
264 (while (not (eq (thread--blocker new-thread) threads-condvar))
265 (thread-yield))
266 (should (thread-alive-p new-thread))
267 (should (= (length (all-threads)) (1+ nthreads)))
268 ;; Notify the waiting thread.
269 (with-mutex cv-mutex
270 (condition-notify threads-condvar t))
271
272 ;; Allow new-thread to process the notification.
273 (sleep-for 0.1)
274 ;; Make sure the thread is still there. This used to fail due to
275 ;; a bug in condition_wait_callback.
276 (should (thread-alive-p new-thread))
277 (should (= (length (all-threads)) (1+ nthreads)))
278 (should (memq new-thread (all-threads)))
279 ;; Make sure the other thread waits at the condition variable again.
280 (should (eq (thread--blocker new-thread) threads-condvar))
281
282 ;; Signal the thread.
283 (thread-signal new-thread 'error '("Die, die, die!"))
284 (sleep-for 0.1)
285 ;; Make sure the thread died.
286 (should (= (length (all-threads)) nthreads))))
287
247;;; threads.el ends here 288;;; threads.el ends here