- fix signal handling in wxWindows. The problem was that a signal gets
delivered to both the GUI and simulator thread, so they both call bx_signal_handler. This can lead to deadlock as multiple threads enter BX_PANIC and try to show a dialog box at once. To solve the problem, I made a function isSimThread() which can be called from anywhere. If the bx_signal_handler is called from any thread OTHER THAN the simulation thread, it returns without doing anything. As a result, only one thread is allowed to enter the signal handler code, and now control-C works correctly.
This commit is contained in:
parent
b79630a14e
commit
b9bfa8ed7f
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: siminterface.h,v 1.57 2002-09-05 07:01:30 bdenney Exp $
|
||||
// $Id: siminterface.h,v 1.58 2002-09-05 07:48:38 bdenney Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Before I can describe what this file is for, I have to make the
|
||||
@ -874,3 +874,9 @@ extern bx_simulator_interface_c *SIM;
|
||||
extern void bx_init_siminterface ();
|
||||
extern void bx_init_main (int argc, char *argv[]);
|
||||
extern int bx_continue_after_config_interface (int argc, char *argv[]);
|
||||
|
||||
#if BX_WITH_WX
|
||||
// returns true if called from the simulator thread.
|
||||
// defined in wxmain.cc, usable anywhere.
|
||||
bool isSimThread ();
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// $Id: wxmain.cc,v 1.34 2002-09-05 07:01:30 bdenney Exp $
|
||||
// $Id: wxmain.cc,v 1.35 2002-09-05 07:48:39 bdenney Exp $
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs.
|
||||
@ -72,6 +72,16 @@
|
||||
MyFrame *theFrame = NULL;
|
||||
MyPanel *thePanel = NULL;
|
||||
|
||||
bool isSimThread () {
|
||||
wxThread *current = wxThread::This ();
|
||||
if (current == (wxThread*) theFrame->GetSimThread ()) {
|
||||
wxLogDebug ("isSimThread? yes");
|
||||
return true;
|
||||
}
|
||||
wxLogDebug ("isSimThread? no");
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// class declarations
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// $Id: wxmain.h,v 1.18 2002-09-03 05:32:49 bdenney Exp $
|
||||
// $Id: wxmain.h,v 1.19 2002-09-05 07:48:39 bdenney Exp $
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// This file defines variables and classes that the wxWindows .cc files
|
||||
// share. It should be included only by wx.cc and wxmain.cc.
|
||||
@ -161,6 +161,7 @@ public:
|
||||
|
||||
// called from the sim thread's OnExit() method.
|
||||
void OnSimThreadExit ();
|
||||
SimThread *GetSimThread () { return sim_thread; }
|
||||
|
||||
private:
|
||||
wxCriticalSection sim_thread_lock;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: main.cc,v 1.136 2002-09-05 07:01:28 bdenney Exp $
|
||||
// $Id: main.cc,v 1.137 2002-09-05 07:48:38 bdenney Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -1477,7 +1477,7 @@ bx_init_hardware()
|
||||
BX_DEBUG(("bx_init_hardware is setting signal handlers"));
|
||||
// if not using debugger, then we can take control of SIGINT.
|
||||
// If using debugger, it needs control of this.
|
||||
#if BX_DEBUGGER==0
|
||||
#if !BX_DEBUGGER /* && !BX_WITH_WX seems like an improvement */
|
||||
signal(SIGINT, bx_signal_handler);
|
||||
#endif
|
||||
|
||||
@ -2757,6 +2757,18 @@ bx_write_configuration (char *rc, int overwrite)
|
||||
void
|
||||
bx_signal_handler( int signum)
|
||||
{
|
||||
#if BX_WITH_WX
|
||||
// in a multithreaded environment, a signal such as SIGINT can be sent to all
|
||||
// threads. This function is only intended to handle signals in the
|
||||
// simulator thread. It will simply return if called from any other thread.
|
||||
// Otherwise the BX_PANIC() below can be called in multiple threads at
|
||||
// once, leading to multiple threads trying to display a dialog box,
|
||||
// leading to GUI deadlock.
|
||||
if (!isSimThread ()) {
|
||||
BX_INFO (("bx_signal_handler: ignored sig %d because it wasn't called from the simulator thread", signum));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if BX_GUI_SIGHANDLER
|
||||
// GUI signal handler gets first priority, if the mask says it's wanted
|
||||
if ((1<<signum) & bx_gui.get_sighandler_mask ()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user