emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/slime 4767d6dc33 1/3: Avoid using CLOS in the auto-flush t


From: ELPA Syncer
Subject: [nongnu] elpa/slime 4767d6dc33 1/3: Avoid using CLOS in the auto-flush thread.
Date: Thu, 2 May 2024 18:59:12 -0400 (EDT)

branch: elpa/slime
commit 4767d6dc3361dc98f8b256a2018d3fe3930f66c7
Author: Stas Boukarev <stassats@gmail.com>
Commit: Stas Boukarev <stassats@gmail.com>

    Avoid using CLOS in the auto-flush thread.
    
    Possible deadlocks.
---
 swank/backend.lisp |  5 ++---
 swank/gray.lisp    | 57 ++++++++++++++++++++++++++++++++----------------------
 2 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/swank/backend.lisp b/swank/backend.lisp
index 1ba3ade60b..b1266d6243 100644
--- a/swank/backend.lisp
+++ b/swank/backend.lisp
@@ -653,9 +653,8 @@ The stream calls READ-STRING when input is needed.")
          :name "auto-flush-thread"))
 
 (definterface really-finish-output (stream)
-  "Make an auto-flush thread"
-  (spawn (lambda () (auto-flush-loop stream *auto-flush-interval* nil))
-         :name "auto-flush-thread"))
+  "FINISH-OUTPUT or more"
+  (finish-output stream))
 
 
 ;;;; Documentation
diff --git a/swank/gray.lisp b/swank/gray.lisp
index 4f570ae016..3f5f09fc88 100644
--- a/swank/gray.lisp
+++ b/swank/gray.lisp
@@ -39,31 +39,42 @@
 
 (in-package swank/gray)
 
-(defclass slime-output-stream (fundamental-character-output-stream)
-  ((output-fn :initarg :output-fn)
-   (buffer :initform (make-string 64000))
-   (fill-pointer :initform 0)
-   (column :initform 0)
-   (lock :initform (make-lock :name "buffer write lock"))
-   (flush-thread :initarg :flush-thread
-                 :initform nil
-                 :accessor flush-thread)
-   (flush-scheduled :initarg :flush-scheduled
-                    :initform nil
-                    :accessor flush-scheduled)))
+;;; Avoid using CLOS in the auto-flush thread due to possible
+;;; deadlocks between CLOS and streams.  
+(defstruct stream-data
+  (output-fn)
+  (buffer (make-string 64000))
+  (fill-pointer 0)
+  (column 0)
+  (lock (make-lock :name "buffer write lock"))
+  (flush-thread)
+  (flush-scheduled))
 
-(defun maybe-schedule-flush (stream)
-  (when (flush-thread stream)
-    (or (flush-scheduled stream)
-        (progn
-          (setf (flush-scheduled stream) t)
-          (send (flush-thread stream) t)
-          t))))
+(defclass slime-output-stream (fundamental-character-output-stream)
+  ((data :initform (make-stream-data)
+         :initarg :data 
+         :accessor data)))
 
 (defmacro with-slime-output-stream (stream &body body)
-  `(with-slots (lock output-fn buffer fill-pointer column) ,stream
+  `(with-accessors ((lock stream-data-lock)
+                    (output-fn stream-data-output-fn)
+                    (buffer stream-data-buffer)
+                    (fill-pointer stream-data-fill-pointer)
+                    (column stream-data-column)
+                    (flush-thread stream-data-flush-thread)
+                    (flush-scheduled stream-data-flush-scheduled))
+       (data ,stream)
      (call-with-lock-held lock (lambda () ,@body))))
 
+(defun maybe-schedule-flush (stream)
+  (with-slime-output-stream stream
+    (when flush-thread
+      (or flush-scheduled
+          (progn
+            (setf flush-scheduled t)
+            (send flush-thread t)
+            t)))))
+
 (defmethod stream-write-char ((stream slime-output-stream) char)
   (with-slime-output-stream stream
     (setf (schar buffer fill-pointer) char)
@@ -111,7 +122,7 @@
     (unless (zerop fill-pointer)
       (funcall output-fn (subseq buffer 0 fill-pointer))
       (setf fill-pointer 0))
-    (setf (flush-scheduled stream) nil))
+    (setf flush-scheduled nil))
   nil)
 
 (defmethod stream-force-output ((stream slime-output-stream))
@@ -201,7 +212,7 @@
 
 (defimplementation make-auto-flush-thread (stream)
   (if (typep stream 'slime-output-stream)
-      (setf (flush-thread stream)
+      (setf (stream-data-flush-thread (data stream))
             (spawn (lambda () (auto-flush-loop stream 0.005 t 
#'%stream-finish-output))
                    :name "auto-flush-thread"))
       (spawn (lambda () (auto-flush-loop stream *auto-flush-interval*))
@@ -214,7 +225,7 @@
         (finish-output stream))))
 
 (defimplementation make-output-stream (write-string)
-  (make-instance 'slime-output-stream :output-fn write-string))
+  (make-instance 'slime-output-stream :data (make-stream-data :output-fn 
write-string)))
 
 (defimplementation make-input-stream (read-string)
   (make-instance 'slime-input-stream :input-fn read-string))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]