fix a race condition, and detect some startup errors better

This commit is contained in:
David Rose 2009-10-19 23:39:19 +00:00
parent 10e4427860
commit 8e0aed64a7
6 changed files with 44 additions and 16 deletions

View File

@ -824,21 +824,21 @@ class PackageInfo:
# there. We have to take a bit of care to check if it's # there. We have to take a bit of care to check if it's
# already there, since there can be some ambiguity in # already there, since there can be some ambiguity in
# os-specific path strings. # os-specific path strings.
root = self.packageDir.toOsSpecific() osRoot = self.packageDir.toOsSpecific()
foundOnPath = False foundOnPath = False
for p in sys.path: for p in sys.path:
if root == p: if osRoot == p:
# Already here, exactly. # Already here, exactly.
foundOnPath = True foundOnPath = True
break break
elif root == Filename.fromOsSpecific(p).toOsSpecific(): elif osRoot == Filename.fromOsSpecific(p).toOsSpecific():
# Already here, with some futzing. # Already here, with some futzing.
foundOnPath = True foundOnPath = True
break break
if not foundOnPath: if not foundOnPath:
# Not already here; add it. # Not already here; add it.
sys.path.append(root) sys.path.append(osRoot)
# Put it on the model-path, too. We do this indiscriminantly, # Put it on the model-path, too. We do this indiscriminantly,
# because the Panda3D runtime won't be adding things to the # because the Panda3D runtime won't be adding things to the
@ -847,11 +847,11 @@ class PackageInfo:
# Set the environment variable to reference the package root. # Set the environment variable to reference the package root.
envvar = '%s_ROOT' % (self.packageName.upper()) envvar = '%s_ROOT' % (self.packageName.upper())
ExecutionEnvironment.setEnvironmentVariable(envvar, self.packageDir.toOsSpecific()) ExecutionEnvironment.setEnvironmentVariable(envvar, osRoot)
# Now that the environment variable is set, read all of the # Now that the environment variable is set, read all of the
# prc files in the package. # prc files in the package.
appRunner.loadMultifilePrcFiles(mf, root) appRunner.loadMultifilePrcFiles(mf, self.packageDir)
# Also, find any toplevel Python packages, and add these as # Also, find any toplevel Python packages, and add these as
# shared packages. This will allow different packages # shared packages. This will allow different packages

View File

@ -35,6 +35,19 @@ enum NodeType {
static const size_t length_nonce1 = 812311453; static const size_t length_nonce1 = 812311453;
static const size_t length_nonce2 = 612811373; static const size_t length_nonce2 = 612811373;
////////////////////////////////////////////////////////////////////
// Function: init_xml
// Description: Should be called before spawning any threads to
// ensure the lock is initialized.
////////////////////////////////////////////////////////////////////
void
init_xml() {
if (!xml_lock_initialized) {
INIT_LOCK(xml_lock);
xml_lock_initialized = true;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: write_xml_node // Function: write_xml_node
// Description: Recursively writes a node and all of its children to // Description: Recursively writes a node and all of its children to
@ -254,9 +267,7 @@ read_xml_node(istream &in, char *&buffer, size_t &buffer_length,
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void void
write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) { write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
if (!xml_lock_initialized) { assert(xml_lock_initialized);
INIT_LOCK(xml_lock);
}
ACQUIRE_LOCK(xml_lock); ACQUIRE_LOCK(xml_lock);
#ifdef DO_BINARY_XML #ifdef DO_BINARY_XML
@ -301,10 +312,12 @@ write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
TiXmlDocument * TiXmlDocument *
read_xml(istream &in, ostream &logfile) { read_xml(istream &in, ostream &logfile) {
if (!xml_lock_initialized) { // We don't acquire xml_lock while reading. We can't, because our
INIT_LOCK(xml_lock); // XML readers are all designed to block until data is available,
} // and they can't block while holding the lock.
ACQUIRE_LOCK(xml_lock);
// Fortunately, there should be only one reader at a time, so a lock
// isn't really needed here.
#if DO_BINARY_XML #if DO_BINARY_XML
// binary read. // binary read.
@ -313,7 +326,6 @@ read_xml(istream &in, ostream &logfile) {
TiXmlNode *xnode = read_xml_node(in, buffer, buffer_length, logfile); TiXmlNode *xnode = read_xml_node(in, buffer, buffer_length, logfile);
delete[] buffer; delete[] buffer;
if (xnode == NULL) { if (xnode == NULL) {
RELEASE_LOCK(xml_lock);
return NULL; return NULL;
} }
@ -326,7 +338,6 @@ read_xml(istream &in, ostream &logfile) {
in >> *doc; in >> *doc;
if (in.fail() || in.eof()) { if (in.fail() || in.eof()) {
delete doc; delete doc;
RELEASE_LOCK(xml_lock);
return NULL; return NULL;
} }
#endif #endif
@ -339,6 +350,5 @@ read_xml(istream &in, ostream &logfile) {
logfile << logout.str() << flush; logfile << logout.str() << flush;
} }
RELEASE_LOCK(xml_lock);
return doc; return doc;
} }

View File

@ -26,6 +26,7 @@ using namespace std;
// operators, but this is a smidge more efficient and gives us more // operators, but this is a smidge more efficient and gives us more
// control. // control.
void init_xml();
void write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile); void write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile);
TiXmlDocument *read_xml(istream &in, ostream &logfile); TiXmlDocument *read_xml(istream &in, ostream &logfile);

View File

@ -25,6 +25,7 @@
#include "find_root_dir.h" #include "find_root_dir.h"
#include "fileSpec.h" #include "fileSpec.h"
#include "get_tinyxml.h" #include "get_tinyxml.h"
#include "binaryXml.h"
#include "mkdir_complete.h" #include "mkdir_complete.h"
// We can include this header file to get the DTOOL_PLATFORM // We can include this header file to get the DTOOL_PLATFORM
@ -53,6 +54,8 @@ P3DInstanceManager *P3DInstanceManager::_global_ptr;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3DInstanceManager:: P3DInstanceManager::
P3DInstanceManager() { P3DInstanceManager() {
init_xml();
_is_initialized = false; _is_initialized = false;
_next_temp_filename_counter = 1; _next_temp_filename_counter = 1;
_unique_id = 0; _unique_id = 0;

View File

@ -41,6 +41,7 @@ P3DPythonRun(const char *program_name, const char *archive_file,
FHandle input_handle, FHandle output_handle, FHandle input_handle, FHandle output_handle,
const char *log_pathname, bool interactive_console) { const char *log_pathname, bool interactive_console) {
P3DWindowHandle::init_type(); P3DWindowHandle::init_type();
init_xml();
_read_thread_continue = false; _read_thread_continue = false;
_program_continue = true; _program_continue = true;
@ -1179,6 +1180,9 @@ set_instance_info(P3DCInstance *inst, TiXmlElement *xinstance) {
if (result == NULL) { if (result == NULL) {
PyErr_Print(); PyErr_Print();
if (!_interactive_console) {
exit(1);
}
} }
Py_XDECREF(result); Py_XDECREF(result);
} }
@ -1210,6 +1214,9 @@ add_package_info(P3DCInstance *inst, TiXmlElement *xpackage) {
if (result == NULL) { if (result == NULL) {
PyErr_Print(); PyErr_Print();
if (!_interactive_console) {
exit(1);
}
} }
Py_XDECREF(result); Py_XDECREF(result);
} }
@ -1274,6 +1281,9 @@ set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) {
if (result == NULL) { if (result == NULL) {
PyErr_Print(); PyErr_Print();
if (!_interactive_console) {
exit(1);
}
} }
Py_XDECREF(result); Py_XDECREF(result);
} }
@ -1370,6 +1380,9 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) {
if (result == NULL) { if (result == NULL) {
PyErr_Print(); PyErr_Print();
if (!_interactive_console) {
exit(1);
}
} }
Py_XDECREF(result); Py_XDECREF(result);
} }

View File

@ -260,6 +260,7 @@ start_subprocess() {
if (child == 0) { if (child == 0) {
// Here we are in the child process. // Here we are in the child process.
init_xml();
// Open the read end of the pipe, and close the write end. // Open the read end of the pipe, and close the write end.
_pipe_read.open_read(to_fd[0]); _pipe_read.open_read(to_fd[0]);