;; 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)
- (sb!sys:enable-interrupt :sigint :ignore)
+ (sb!sys:enable-interrupt sb!unix:sigint :ignore)
(sb!unix:unix-exit
(catch 'sb!impl::%end-of-the-world
(with-simple-restart
(funcall real-function))
0))))))))
+;;; Conventional wisdom says that it's a bad idea to use these unless
+;;; you really need to. Use a lock or a waitqueue instead
+(defun suspend-thread (thread-id)
+ (sb!unix:unix-kill thread-id sb!unix:sigstop))
+(defun resume-thread (thread-id)
+ (sb!unix:unix-kill thread-id sb!unix:sigcont))
+;;; Note warning about cleanup forms
(defun destroy-thread (thread-id)
- (sb!unix:unix-kill thread-id :sigterm)
+ "Destroy the thread identified by THREAD-ID abruptly, without running cleanup forms"
+ (sb!unix:unix-kill thread-id sb!unix:sigterm)
;; may have been stopped for some reason, so now wake it up to
;; deliver the TERM
- (sb!unix:unix-kill thread-id :sigcont))
+ (sb!unix:unix-kill thread-id sb!unix:sigcont))
+
+
+;;; a moderate degree of care is expected for use of interrupt-thread,
+;;; due to its nature: if you interrupt a thread that was holding
+;;; important locks then do something that turns out to need those
+;;; locks, you probably won't like the effect. Used with thought
+;;; though, it's a good deal gentler than the last-resort functions above
+
+(defun interrupt-thread (thread function)
+ "Interrupt THREAD and make it run FUNCTION. "
+ (sb!unix::syscall* ("interrupt_thread"
+ sb!alien:unsigned-long sb!alien:unsigned-long)
+ thread
+ thread (sb!kernel:get-lisp-obj-address
+ (coerce function 'function))))
+(defun terminate-thread (thread-id)
+ "Terminate the thread identified by THREAD-ID, by causing it to run
+SB-EXT:QUIT - the usual cleanup forms will be evaluated"
+ (interrupt-thread thread-id 'sb!ext:quit))
-;; Conventional wisdom says that it's a bad idea to use these unless
-;; you really need to. Use a lock or a waitqueue instead
-(defun suspend-thread (thread-id)
- (sb!unix:unix-kill thread-id :sigstop))
-(defun resume-thread (thread-id)
- (sb!unix:unix-kill thread-id :sigcont))
(defun current-thread-id ()
(sb!sys:sap-int
(setf (waitqueue-data queue)
(delete pid (waitqueue-data queue))))))
-;;; this should probably only be called while holding the queue spinlock.
-;;; not sure
+;;; this should only be called while holding the queue spinlock.
(defun signal-queue-head (queue)
(let ((p (car (waitqueue-data queue))))
- (when p (sb!unix:unix-kill p :sigcont))))
+ (when p (sb!unix:unix-kill p sb!unix:sigcont))))
;;;; mutex
(sb!sys:make-fd-stream err :input t :output t :buffering :line))
(sb!impl::*descriptor-handlers* nil))
(get-mutex *session-lock*)
- (sb!sys:enable-interrupt :sigint #'sb!unix::sigint-handler)
+ (sb!sys:enable-interrupt sb!unix:sigint #'sb!unix::sigint-handler)
(unwind-protect
(sb!impl::toplevel-repl nil)
(sb!int:flush-standard-output-streams)))))
(cond (wait-p (get-foreground))
(t (invoke-restart (car (compute-restarts))))))))
-;;; install this with (setf SB!INT:*REPL-PROMPT-FUN* #'thread-prompt-fun)
+;;; install this with
+;;; (setf SB-INT:*REPL-PROMPT-FUN* #'sb-thread::thread-repl-prompt-fun)
;;; One day it will be default
(defun thread-repl-prompt-fun (out-stream)
(let ((lock *session-lock*))