(session-interactive-threads *session*))))
(get-foreground)))
-(defun thread-repl-prompt-fun (out-stream)
- (get-foreground)
- (let ((stopped-threads (cdr (session-interactive-threads *session*))))
- (when stopped-threads
- (format out-stream "~{~&Thread ~A suspended~}~%" stopped-threads))
- (sb!impl::repl-prompt-fun out-stream)))
(defun get-foreground ()
- (loop
- (with-mutex ((session-lock *session*))
- (let ((tid (current-thread-id))
- (int-t (session-interactive-threads *session*)))
- (when (eql (car int-t) tid)
- (sb!sys:enable-interrupt sb!unix:sigint #'sb!unix::sigint-handler)
- (return-from get-foreground t))
- (unless (member tid int-t)
- (setf (cdr (last int-t))
- (list tid)))
- (condition-wait
- (session-interactive-threads-queue *session*)
- (session-lock *session*))))))
+ (let ((was-foreground t))
+ (loop
+ (with-mutex ((session-lock *session*))
+ (let ((tid (current-thread-id))
+ (int-t (session-interactive-threads *session*)))
+ (when (eql (car int-t) tid)
+ (unless was-foreground
+ (format *query-io* "Resuming thread ~A~%" tid))
+ (sb!sys:enable-interrupt sb!unix:sigint #'sb!unix::sigint-handler)
+ (return-from get-foreground t))
+ (setf was-foreground nil)
+ (unless (member tid int-t)
+ (setf (cdr (last int-t))
+ (list tid)))
+ (condition-wait
+ (session-interactive-threads-queue *session*)
+ (session-lock *session*)))))))
(defun release-foreground (&optional next)
"Background this thread. If NEXT is supplied, arrange for it to have the foreground next"
#include <sys/param.h>
#include <sys/stat.h>
#include <signal.h>
-#ifdef LISP_FEATURE_SB_THREAD
-#include <sys/ptrace.h>
-#endif
#include <sched.h>
#include <errno.h>
", SBCL_VERSION_STRING);
}
\f
-int gc_thread_pid;
FILE *stdlog;
\f
fflush(stdout);
}
-#ifdef MACH
- mach_init();
-#endif
#if defined(SVR4) || defined(__linux__)
tzset();
#endif
create_thread(initial_function);
/* in a unithread build, create_thread never returns */
#ifdef LISP_FEATURE_SB_THREAD
- gc_thread_pid=getpid();
parent_loop();
#endif
}
-static void parent_sighandler(int signum,siginfo_t *info, void *void_context)
-{
-#if 0
- os_context_t *context = (os_context_t*)void_context;
- fprintf(stderr,
- "parent thread got signal %d from %d, maybe_gc_pending=%d\n",
- signum, info->si_pid,
- maybe_gc_pending);
-#endif
-}
-
#ifdef LISP_FEATURE_SB_THREAD
-int show_thread_exit=0;
+
+/* this is being pared down as time goes on; eventually we want to get
+ * to the point that we have no parent loop at all and the parent
+ * thread runs Lisp just like any other */
static void /* noreturn */ parent_loop(void)
{
pid_t pid=0;
sigemptyset(&sigset);
-
- sigaddset(&sigset, SIGCHLD);
- sigaddset(&sigset, SIG_THREAD_EXIT);
- sigprocmask(SIG_UNBLOCK,&sigset,0);
- sa.sa_handler=parent_sighandler;
- sa.sa_mask=sigset;
- sa.sa_flags=SA_SIGINFO;
- sigaction(SIGCHLD, &sa, 0);
-
- sigemptyset(&sigset);
sa.sa_handler=SIG_IGN;
sa.sa_mask=sigset;
sa.sa_flags=0;
- sigaction(SIGINT, &sa, 0);
+ sigaction(SIGINT, &sa, 0); /* ^c should go to the lisp thread instead */
sigaction(SIG_THREAD_EXIT, &sa, 0);
+ sigaction(SIGCHLD, &sa, 0);
while(!all_threads) {
sched_yield();
}
while(all_threads && (pid=waitpid(-1,&status,__WALL))) {
struct thread *th;
- int real_errno=errno;
if(pid==-1) {
- if(real_errno == EINTR) {
- continue;
- }
- if(real_errno == ECHILD) break;
- fprintf(stderr,"waitpid: %s\n",strerror(real_errno));
- continue;
+ if(errno == EINTR) continue;
+ fprintf(stderr,"waitpid: %s\n",strerror(errno));
}
- if(WIFEXITED(status) || WIFSIGNALED(status)) {
+ else if(WIFEXITED(status) || WIFSIGNALED(status)) {
th=find_thread_by_pid(pid);
if(!th) continue;
- if(show_thread_exit)
- fprintf(stderr,"waitpid : child %d %x exited \n", pid,th);
destroy_thread(th);
if(!all_threads) break;
}