From: Michael Albinus Date: Fri, 17 Aug 2018 08:33:10 +0000 (+0200) Subject: Merge branch 'master' into feature/tramp-thread-safe X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2ff70179566cff8917f7cc33f360ed3b31b377ff;p=emacs.git Merge branch 'master' into feature/tramp-thread-safe --- 2ff70179566cff8917f7cc33f360ed3b31b377ff diff --cc lisp/files.el index 4054934b1db,da4f2cd78fe..d5dab88f277 --- a/lisp/files.el +++ b/lisp/files.el @@@ -1893,9 -1830,8 +1893,9 @@@ killed. ;; Don't use `find-file' because it may end up using another window ;; in some corner cases, e.g. when the selected window is ;; softly-dedicated. - (let ((newbuf (find-file-noselect filename nil nil wildcards))) + (let ((newbuf + (find-file-noselect filename nil nil wildcards async))) - (switch-to-buffer newbuf))) + (switch-to-buffer (if (consp newbuf) (car newbuf) newbuf)))) (when (eq obuf (current-buffer)) ;; This executes if find-file gets an error ;; and does not really find anything. diff --cc test/lisp/net/tramp-tests.el index 29a8df8975b,293a0054560..e1838d152ce --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@@ -5053,108 -5053,11 +5053,110 @@@ process sentinels. They shall not dist (ignore-errors (cancel-timer timer)) (ignore-errors (delete-directory tmp-name 'recursive))))))) +(ert-deftest tramp-test43-threads () + "Check that Tramp cooperates with threads." + (skip-unless (tramp--test-enabled)) + (skip-unless (featurep 'threads)) + (skip-unless (= (length (all-threads)) 1)) + (skip-unless (not (thread-last-error))) + + ;; We cannot bind the variables dynamically; they are used in the threads. + (defvar tmp-name1 (tramp--test-make-temp-name)) + (defvar tmp-name2 (tramp--test-make-temp-name)) + (defvar tmp-mutex (make-mutex "mutex")) + (defvar tmp-condvar1 (make-condition-variable tmp-mutex "condvar1")) + (defvar tmp-condvar2 (make-condition-variable tmp-mutex "condvar2")) + + ;; Rename simple file. + (unwind-protect + (let (tmp-thread1 tmp-thread2) + (write-region "foo" nil tmp-name1) + (should (file-exists-p tmp-name1)) + (should-not (file-exists-p tmp-name2)) + + (should (mutexp tmp-mutex)) + (should (condition-variable-p tmp-condvar1)) + (should (condition-variable-p tmp-condvar2)) + + ;; This thread renames `tmp-name1' to `tmp-name2' twice. + (setq + tmp-thread1 + (make-thread + (lambda () + ;; Rename first time. + (rename-file tmp-name1 tmp-name2) + ;; Notify thread2. + (with-mutex (condition-mutex tmp-condvar2) + (condition-notify tmp-condvar2 t)) + ;; Rename second time, once we've got notification from thread2. + (with-mutex (condition-mutex tmp-condvar1) + (condition-wait tmp-condvar1)) + (rename-file tmp-name1 tmp-name2)) + "thread1")) + + (should (threadp tmp-thread1)) + (should (thread-alive-p tmp-thread1)) + + ;; This thread renames `tmp-name2' to `tmp-name1' twice. + (setq + tmp-thread2 + (make-thread + (lambda () + ;; Rename first time, once we've got notification from thread1. + (with-mutex (condition-mutex tmp-condvar2) + (condition-wait tmp-condvar2)) + (rename-file tmp-name2 tmp-name1) + ;; Notify thread1. + (with-mutex (condition-mutex tmp-condvar1) + (condition-notify tmp-condvar1 t)) + ;; Rename second time, once we've got notification from + ;; the main thread. + (with-mutex (condition-mutex tmp-condvar2) + (condition-wait tmp-condvar2)) + (rename-file tmp-name2 tmp-name1)) + "thread2")) + + (should (threadp tmp-thread2)) + (should (thread-alive-p tmp-thread2)) + (should (= (length (all-threads)) 3)) + + ;; Wait for thread1. + (thread-join tmp-thread1) + ;; Checks. + (should-not (thread-alive-p tmp-thread1)) + (should (= (length (all-threads)) 2)) + (should-not (thread-last-error)) + (should (file-exists-p tmp-name2)) + (should-not (file-exists-p tmp-name1)) + + ;; Notify thread2. + (with-mutex (condition-mutex tmp-condvar2) + (condition-notify tmp-condvar2 t)) + + ;; Wait for thread2. + (thread-join tmp-thread2) + ;; Checks. + (should-not (thread-alive-p tmp-thread2)) + (should (= (length (all-threads)) 1)) + (should-not (thread-last-error)) + (should (file-exists-p tmp-name1)) + (should-not (file-exists-p tmp-name2))) + + ;; Cleanup. + (ignore-errors (delete-file tmp-name1)) + (ignore-errors (delete-file tmp-name2)) + ;; We could have spurious threads still running; wait for them to die. + (while (cdr (all-threads)) + (thread-signal (cadr (all-threads)) 'error nil) + (thread-yield)) + ;; Cleanup errors. + (thread-last-error 'cleanup))) + ;; This test is inspired by Bug#29163. -(ert-deftest tramp-test43-auto-load () +(ert-deftest tramp-test44-auto-load () "Check that Tramp autoloads properly." + (skip-unless (tramp--test-enabled)) + (let ((default-directory (expand-file-name temporary-file-directory)) (code (format