diff options
| author | Eli Zaretskii | 2017-01-13 11:48:51 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2017-01-13 11:48:51 +0200 |
| commit | 03e4ab0d586069be65e4a17fbf4cd965a9984726 (patch) | |
| tree | 729d86e3282165ca0d58bec8bde33661c9b60ed9 /test/src/thread-tests.el | |
| parent | 62e27ebd54336d30a90ae71e5bdcb910e954c061 (diff) | |
| download | emacs-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.el | 41 |
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 |