(#.(sb!vm:fixnumize 2) :suspended)
(#.(sb!vm:fixnumize 3) :dead))))
-(defun %set-thread-state (thread state)
- (setf (sb!sys:sap-ref-sap (thread-%sap thread)
- (* sb!vm::thread-state-slot
- sb!vm::n-word-bytes))
- (sb!sys:int-sap
- (ecase state
- (:starting #.(sb!vm:fixnumize 0))
- (:running #.(sb!vm:fixnumize 1))
- (:suspended #.(sb!vm:fixnumize 2))
- (:dead #.(sb!vm:fixnumize 3))))))
-
(defun thread-alive-p (thread)
#!+sb-doc
"Check if THREAD is running."
system-area-pointer
(lisp-fun-address unsigned-long))
+ (define-alien-routine "block_deferrable_signals_and_inhibit_gc"
+ void)
+
(define-alien-routine reap-dead-thread void
(thread-sap system-area-pointer))
(defun release-foreground (&optional next)
#!+sb-doc
"Background this thread. If NEXT is supplied, arrange for it to
-have the foreground next"
+have the foreground next."
#!-sb-thread (declare (ignore next))
#!-sb-thread nil
#!+sb-thread
(with-session-lock (*session*)
- (setf (session-interactive-threads *session*)
- (delete *current-thread* (session-interactive-threads *session*)))
+ (when (rest (session-interactive-threads *session*))
+ (setf (session-interactive-threads *session*)
+ (delete *current-thread* (session-interactive-threads *session*))))
(when next
(setf (session-interactive-threads *session*)
(list* next
(sb!kernel::*restart-clusters* nil)
(sb!kernel::*handler-clusters* nil)
(sb!kernel::*condition-restarts* nil)
- (sb!impl::*descriptor-handlers* nil) ; serve-event
- (sb!impl::*available-buffers* nil)) ;for fd-stream
+ (sb!impl::*descriptor-handlers* nil)) ; serve-event
;; can't use handling-end-of-the-world, because that flushes
;; output streams, and we don't necessarily have any (or we
;; could be sharing them)
(funcall real-function)
;; we're going down, can't handle
;; interrupts sanely anymore
- (sb!unix::block-blockable-signals)))))
- ;; mark the thread dead, so that the gc does not
- ;; wait for it to handle sig-stop-for-gc
- (%set-thread-state thread :dead)
- ;; and remove what can be the last reference to
- ;; the thread object
+ (block-deferrable-signals-and-inhibit-gc)))))
+ ;; and remove what can be the last references to the
+ ;; thread object
(handle-thread-exit thread)
+ (setq *current-thread* nil)
0))
(values))))))
(when (sb!sys:sap= thread-sap (sb!sys:int-sap 0))
#!-sb-thread
(funcall function)
#!+sb-thread
- (let ((function (coerce function 'function)))
- (multiple-value-bind (res err)
- (sb!unix::syscall ("interrupt_thread"
- system-area-pointer sb!alien:unsigned-long)
- thread
- (thread-%sap thread)
- (sb!kernel:get-lisp-obj-address function))
- (unless res
- (error 'interrupt-thread-error :thread thread :errno err)))))
+ (if (eq thread *current-thread*)
+ (funcall function)
+ (let ((function (coerce function 'function)))
+ (multiple-value-bind (res err)
+ ;; protect against gcing just when the ub32 address is
+ ;; just ready to be passed to C
+ (sb!sys::with-pinned-objects (function)
+ (sb!unix::syscall ("interrupt_thread"
+ system-area-pointer sb!alien:unsigned-long)
+ thread
+ (thread-%sap thread)
+ (sb!kernel:get-lisp-obj-address function)))
+ (unless res
+ (error 'interrupt-thread-error :thread thread :errno err))))))
(defun terminate-thread (thread)
#!+sb-doc