vm: interrupt stdin_loop when entering fep
The stdin_loop thread will keep trying to consume input unless we stop it by sending it a signal. Use SIGUSR2 to stop the read syscall and a mutex to hold up the loop while the fep is active.db4
parent
04c6b2c393
commit
f9aa0419c4
13
vm/debug.cpp
13
vm/debug.cpp
|
@ -438,6 +438,12 @@ void factor_vm::factorbug_usage(bool advanced_p)
|
|||
|
||||
}
|
||||
|
||||
static void exit_fep(factor_vm *vm)
|
||||
{
|
||||
vm->unlock_console();
|
||||
vm->fep_p = false;
|
||||
}
|
||||
|
||||
void factor_vm::factorbug()
|
||||
{
|
||||
if(fep_disabled)
|
||||
|
@ -452,6 +458,9 @@ void factor_vm::factorbug()
|
|||
fep_p = true;
|
||||
|
||||
std::cout << "Starting low level debugger..." << std::endl;
|
||||
|
||||
lock_console();
|
||||
|
||||
if (!fep_help_was_shown) {
|
||||
factorbug_usage(false);
|
||||
fep_help_was_shown = true;
|
||||
|
@ -530,12 +539,12 @@ void factor_vm::factorbug()
|
|||
dump_generations();
|
||||
else if(strcmp(cmd,"c") == 0)
|
||||
{
|
||||
fep_p = false;
|
||||
exit_fep(this);
|
||||
return;
|
||||
}
|
||||
else if(strcmp(cmd,"t") == 0)
|
||||
{
|
||||
fep_p = false;
|
||||
exit_fep(this);
|
||||
general_error(ERROR_INTERRUPT,false_object,false_object);
|
||||
assert(false);
|
||||
}
|
||||
|
|
|
@ -317,8 +317,6 @@ void factor_vm::unix_init_signals()
|
|||
sigaction_safe(SIGABRT,&synchronous_sigaction,NULL);
|
||||
|
||||
init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler);
|
||||
sigaction_safe(SIGUSR1,&enqueue_sigaction,NULL);
|
||||
sigaction_safe(SIGUSR2,&enqueue_sigaction,NULL);
|
||||
sigaction_safe(SIGWINCH,&enqueue_sigaction,NULL);
|
||||
#ifdef SIGINFO
|
||||
sigaction_safe(SIGINFO,&enqueue_sigaction,NULL);
|
||||
|
@ -336,6 +334,8 @@ void factor_vm::unix_init_signals()
|
|||
io.launcher.unix for this. */
|
||||
init_sigaction_with_handler(&ignore_sigaction, ignore_signal_handler);
|
||||
sigaction_safe(SIGPIPE,&ignore_sigaction,NULL);
|
||||
/* We send SIGUSR2 to the stdin_loop thread to interrupt it on FEP */
|
||||
sigaction_safe(SIGUSR2,&ignore_sigaction,NULL);
|
||||
}
|
||||
|
||||
/* On Unix, shared fds such as stdin cannot be set to non-blocking mode
|
||||
|
@ -355,6 +355,9 @@ extern "C" {
|
|||
|
||||
int size_read;
|
||||
int size_write;
|
||||
|
||||
THREADHANDLE stdin_thread;
|
||||
pthread_mutex_t stdin_mutex;
|
||||
}
|
||||
|
||||
void safe_close(int fd)
|
||||
|
@ -404,13 +407,18 @@ void *stdin_loop(void *arg)
|
|||
unsigned char buf[4096];
|
||||
bool loop_running = true;
|
||||
|
||||
// If we fep, the parent thread will grab a mutex and send us SIGUSR2 to make
|
||||
// us relinquish our hold on stdin.
|
||||
sigset_t mask;
|
||||
sigfillset(&mask);
|
||||
pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
sigdelset(&mask, SIGUSR2);
|
||||
pthread_sigmask(SIG_SETMASK, &mask, NULL);
|
||||
|
||||
while(loop_running)
|
||||
{
|
||||
if(!safe_read(control_read,buf,1))
|
||||
bool readp = safe_read(control_read,buf,1);
|
||||
|
||||
if(!readp)
|
||||
break;
|
||||
|
||||
if(buf[0] != 'X')
|
||||
|
@ -418,6 +426,8 @@ void *stdin_loop(void *arg)
|
|||
|
||||
for(;;)
|
||||
{
|
||||
pthread_mutex_lock(&stdin_mutex);
|
||||
pthread_mutex_unlock(&stdin_mutex);
|
||||
ssize_t bytes = read(0,buf,sizeof(buf));
|
||||
if(bytes < 0)
|
||||
{
|
||||
|
@ -446,12 +456,24 @@ void *stdin_loop(void *arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void open_console()
|
||||
void factor_vm::open_console()
|
||||
{
|
||||
safe_pipe(&control_read,&control_write);
|
||||
safe_pipe(&size_read,&size_write);
|
||||
safe_pipe(&stdin_read,&stdin_write);
|
||||
start_thread(stdin_loop,NULL);
|
||||
stdin_thread = start_thread(stdin_loop,NULL);
|
||||
pthread_mutex_init(&stdin_mutex, NULL);
|
||||
}
|
||||
|
||||
void factor_vm::lock_console()
|
||||
{
|
||||
pthread_mutex_lock(&stdin_mutex);
|
||||
pthread_kill(stdin_thread, SIGUSR2);
|
||||
}
|
||||
|
||||
void factor_vm::unlock_console()
|
||||
{
|
||||
pthread_mutex_unlock(&stdin_mutex);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "atomic-gcc.hpp"
|
||||
|
||||
|
@ -41,7 +42,6 @@ inline static THREADHANDLE thread_id() { return pthread_self(); }
|
|||
|
||||
u64 nano_count();
|
||||
void sleep_nanos(u64 nsec);
|
||||
void open_console();
|
||||
|
||||
void move_file(const vm_char *path1, const vm_char *path2);
|
||||
|
||||
|
|
|
@ -301,6 +301,14 @@ void factor_vm::open_console()
|
|||
SetConsoleCtrlHandler(factor::ctrl_handler, TRUE);
|
||||
}
|
||||
|
||||
void factor_vm::lock_console()
|
||||
{
|
||||
}
|
||||
|
||||
void factor_vm::unlock_console()
|
||||
{
|
||||
}
|
||||
|
||||
void factor_vm::sampler_thread_loop()
|
||||
{
|
||||
LARGE_INTEGER counter, new_counter, units_per_second;
|
||||
|
|
|
@ -736,6 +736,9 @@ struct factor_vm
|
|||
void init_signals();
|
||||
void start_sampling_profiler_timer();
|
||||
void end_sampling_profiler_timer();
|
||||
void open_console();
|
||||
void lock_console();
|
||||
void unlock_console();
|
||||
|
||||
// os-windows
|
||||
#if defined(WINDOWS)
|
||||
|
@ -747,7 +750,6 @@ struct factor_vm
|
|||
void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length);
|
||||
BOOL windows_stat(vm_char *path);
|
||||
|
||||
void open_console();
|
||||
LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch);
|
||||
|
||||
#else // UNIX
|
||||
|
|
Loading…
Reference in New Issue