remove util.cxx workaround for listener-call-at-exit-segfault, and make
NasalSys.cxx more robust instead. The reason for the crash was that during fgfs shutdown destroyed subsystems (GENERAL group) still need Nasal access (for AI Model destruction listeners), but at that point globals->get_subsystem() can't even deliver the "nasal" subsystem (INIT group). One way to solve that problem would have been to replace globals->get_subsystem("nasal") by globals->get_subsystem_mgr()->get_group(SGSubsystemMgr::INIT)->get_subsystem("nasal"), but Andy decided to store a pointer to the active "nasal" subsysten in NasalSys.cxx instead, as the "nasal" subsystem needs to be accessed in every single Nasal extension function, and multiple "nasal" subsystems are out of the question, anyway.
This commit is contained in:
parent
83418376d7
commit
ac0f49a929
2 changed files with 14 additions and 27 deletions
|
@ -107,18 +107,6 @@ fgSetupWind (double min_hdg, double max_hdg, double speed, double gust)
|
||||||
void
|
void
|
||||||
fgExit (int status)
|
fgExit (int status)
|
||||||
{
|
{
|
||||||
// remove subsystems first, which need access to other subsystems in their
|
|
||||||
// destructors (e.g. "nasal")
|
|
||||||
SGSubsystem *sub;
|
|
||||||
|
|
||||||
sub = globals->get_subsystem("ai_model");
|
|
||||||
globals->get_subsystem_mgr()->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
|
|
||||||
delete sub;
|
|
||||||
|
|
||||||
sub = globals->get_subsystem("submodel_mgr");
|
|
||||||
globals->get_subsystem_mgr()->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("submodel_mgr");
|
|
||||||
delete sub;
|
|
||||||
|
|
||||||
#ifdef OSG_LIBRARY_STATIC
|
#ifdef OSG_LIBRARY_STATIC
|
||||||
osgDB::Registry::instance( true);
|
osgDB::Registry::instance( true);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
|
|
||||||
#include "NasalSys.hxx"
|
#include "NasalSys.hxx"
|
||||||
|
|
||||||
|
static FGNasalSys* nasalSys = 0;
|
||||||
|
|
||||||
|
|
||||||
// Read and return file contents in a single buffer. Note use of
|
// Read and return file contents in a single buffer. Note use of
|
||||||
// stat() to get the file size. This is a win32 function, believe it
|
// stat() to get the file size. This is a win32 function, believe it
|
||||||
// or not. :) Note the REALLY IMPORTANT use of the "b" flag to fopen.
|
// or not. :) Note the REALLY IMPORTANT use of the "b" flag to fopen.
|
||||||
|
@ -52,6 +55,7 @@ static char* readfile(const char* file, int* lenOut)
|
||||||
|
|
||||||
FGNasalSys::FGNasalSys()
|
FGNasalSys::FGNasalSys()
|
||||||
{
|
{
|
||||||
|
nasalSys = this;
|
||||||
_context = 0;
|
_context = 0;
|
||||||
_globals = naNil();
|
_globals = naNil();
|
||||||
_gcHash = naNil();
|
_gcHash = naNil();
|
||||||
|
@ -82,6 +86,7 @@ naRef FGNasalSys::call(naRef code, naRef locals)
|
||||||
|
|
||||||
FGNasalSys::~FGNasalSys()
|
FGNasalSys::~FGNasalSys()
|
||||||
{
|
{
|
||||||
|
nasalSys = 0;
|
||||||
map<int, FGNasalListener *>::iterator it, end = _listener.end();
|
map<int, FGNasalListener *>::iterator it, end = _listener.end();
|
||||||
for(it = _listener.begin(); it != end; ++it)
|
for(it = _listener.begin(); it != end; ++it)
|
||||||
delete it->second;
|
delete it->second;
|
||||||
|
@ -254,8 +259,7 @@ static naRef f_fgcommand(naContext c, naRef me, int argc, naRef* args)
|
||||||
// FGNasalSys::setTimer(). See there for docs.
|
// FGNasalSys::setTimer(). See there for docs.
|
||||||
static naRef f_settimer(naContext c, naRef me, int argc, naRef* args)
|
static naRef f_settimer(naContext c, naRef me, int argc, naRef* args)
|
||||||
{
|
{
|
||||||
FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
|
nasalSys->setTimer(argc, args);
|
||||||
nasal->setTimer(argc, args);
|
|
||||||
return naNil();
|
return naNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,24 +267,21 @@ static naRef f_settimer(naContext c, naRef me, int argc, naRef* args)
|
||||||
// FGNasalSys::setListener(). See there for docs.
|
// FGNasalSys::setListener(). See there for docs.
|
||||||
static naRef f_setlistener(naContext c, naRef me, int argc, naRef* args)
|
static naRef f_setlistener(naContext c, naRef me, int argc, naRef* args)
|
||||||
{
|
{
|
||||||
FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
|
return nasalSys->setListener(c, argc, args);
|
||||||
return nasal->setListener(c, argc, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// removelistener(int) extension function. Falls through to
|
// removelistener(int) extension function. Falls through to
|
||||||
// FGNasalSys::removeListener(). See there for docs.
|
// FGNasalSys::removeListener(). See there for docs.
|
||||||
static naRef f_removelistener(naContext c, naRef me, int argc, naRef* args)
|
static naRef f_removelistener(naContext c, naRef me, int argc, naRef* args)
|
||||||
{
|
{
|
||||||
FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
|
return nasalSys->removeListener(c, argc, args);
|
||||||
return nasal->removeListener(c, argc, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a ghost handle to the argument to the currently executing
|
// Returns a ghost handle to the argument to the currently executing
|
||||||
// command
|
// command
|
||||||
static naRef f_cmdarg(naContext c, naRef me, int argc, naRef* args)
|
static naRef f_cmdarg(naContext c, naRef me, int argc, naRef* args)
|
||||||
{
|
{
|
||||||
FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
|
return nasalSys->cmdArgGhost();
|
||||||
return nasal->cmdArgGhost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up a property interpolation. The first argument is either a
|
// Sets up a property interpolation. The first argument is either a
|
||||||
|
@ -777,8 +778,7 @@ void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop,
|
||||||
|
|
||||||
_module = path;
|
_module = path;
|
||||||
const char *s = load ? load->getStringValue() : "";
|
const char *s = load ? load->getStringValue() : "";
|
||||||
FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
|
nasalSys->createModule(_module.c_str(), _module.c_str(), s, strlen(s), _props);
|
||||||
nas->createModule(_module.c_str(), _module.c_str(), s, strlen(s), _props);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FGNasalModelData::~FGNasalModelData()
|
FGNasalModelData::~FGNasalModelData()
|
||||||
|
@ -786,8 +786,7 @@ FGNasalModelData::~FGNasalModelData()
|
||||||
if(_module.empty())
|
if(_module.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
|
if(!nasalSys) {
|
||||||
if(!nas) {
|
|
||||||
SG_LOG(SG_NASAL, SG_ALERT, "Trying to run an <unload> script "
|
SG_LOG(SG_NASAL, SG_ALERT, "Trying to run an <unload> script "
|
||||||
"without Nasal subsystem present.");
|
"without Nasal subsystem present.");
|
||||||
return;
|
return;
|
||||||
|
@ -795,9 +794,9 @@ FGNasalModelData::~FGNasalModelData()
|
||||||
|
|
||||||
if(_unload) {
|
if(_unload) {
|
||||||
const char *s = _unload->getStringValue();
|
const char *s = _unload->getStringValue();
|
||||||
nas->createModule(_module.c_str(), _module.c_str(), s, strlen(s), _props);
|
nasalSys->createModule(_module.c_str(), _module.c_str(), s, strlen(s), _props);
|
||||||
}
|
}
|
||||||
nas->deleteModule(_module.c_str());
|
nasalSys->deleteModule(_module.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue