mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
clean exit and log reporting
This commit is contained in:
parent
77b340fec7
commit
194979b51d
@ -113,6 +113,11 @@ class AppRunner(DirectObject):
|
|||||||
# hosts we have imported packages from.
|
# hosts we have imported packages from.
|
||||||
self.hosts = {}
|
self.hosts = {}
|
||||||
|
|
||||||
|
# Application code can assign a callable object here; if so,
|
||||||
|
# it will be invoked when an uncaught exception propagates to
|
||||||
|
# the top of the TaskMgr.run() loop.
|
||||||
|
self.exceptionHandler = None
|
||||||
|
|
||||||
# Managing packages for runtime download.
|
# Managing packages for runtime download.
|
||||||
self.downloadingPackages = []
|
self.downloadingPackages = []
|
||||||
self.downloadTask = None
|
self.downloadTask = None
|
||||||
@ -157,6 +162,49 @@ class AppRunner(DirectObject):
|
|||||||
# call back to the main thread.
|
# call back to the main thread.
|
||||||
self.accept('AppRunner_startIfReady', self.__startIfReady)
|
self.accept('AppRunner_startIfReady', self.__startIfReady)
|
||||||
|
|
||||||
|
def getToken(self, tokenName):
|
||||||
|
""" Returns the value of the indicated web token as a string,
|
||||||
|
if it was set, or None if it was not. """
|
||||||
|
|
||||||
|
return self.tokenDict.get(tokenName.lower(), None)
|
||||||
|
|
||||||
|
def getTokenInt(self, tokenName):
|
||||||
|
""" Returns the value of the indicated web token as an integer
|
||||||
|
value, if it was set, or None if it was not, or not an
|
||||||
|
integer. """
|
||||||
|
|
||||||
|
value = self.getToken(tokenName)
|
||||||
|
if value is not None:
|
||||||
|
try:
|
||||||
|
value = int(value)
|
||||||
|
except ValueError:
|
||||||
|
value = None
|
||||||
|
return value
|
||||||
|
|
||||||
|
def getTokenFloat(self, tokenName):
|
||||||
|
""" Returns the value of the indicated web token as a
|
||||||
|
floating-point value value, if it was set, or None if it was
|
||||||
|
not, or not a number. """
|
||||||
|
|
||||||
|
value = self.getToken(tokenName)
|
||||||
|
if value is not None:
|
||||||
|
try:
|
||||||
|
value = float(value)
|
||||||
|
except ValueError:
|
||||||
|
value = None
|
||||||
|
return value
|
||||||
|
|
||||||
|
def getTokenBool(self, tokenName):
|
||||||
|
""" Returns the value of the indicated web token as a boolean
|
||||||
|
value, if it was set, or None if it was not. """
|
||||||
|
|
||||||
|
value = self.getTokenInt(tokenName)
|
||||||
|
if value is not None:
|
||||||
|
value = bool(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def installPackage(self, packageName, version = None, hostUrl = None):
|
def installPackage(self, packageName, version = None, hostUrl = None):
|
||||||
|
|
||||||
""" Installs the named package, downloading it first if
|
""" Installs the named package, downloading it first if
|
||||||
@ -248,6 +296,33 @@ class AppRunner(DirectObject):
|
|||||||
# shuts down.
|
# shuts down.
|
||||||
taskMgr.doMethodLater(0.5, sys.exit, 'exit')
|
taskMgr.doMethodLater(0.5, sys.exit, 'exit')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
""" This method calls taskMgr.run(), with an optional
|
||||||
|
exception handler. This is generally the program's main loop
|
||||||
|
when running in a p3d environment (except on unusual platforms
|
||||||
|
like the iPhone, which have to hand the main loop off to the
|
||||||
|
OS, and don't use this interface. """
|
||||||
|
|
||||||
|
try:
|
||||||
|
taskMgr.run()
|
||||||
|
|
||||||
|
except SystemExit:
|
||||||
|
# Presumably the window has already been shut down here, but shut
|
||||||
|
# it down again for good measure.
|
||||||
|
if hasattr(__builtin__, "base"):
|
||||||
|
base.destroy()
|
||||||
|
|
||||||
|
self.notify.info("Normal exit.")
|
||||||
|
raise
|
||||||
|
|
||||||
|
except:
|
||||||
|
# Some unexpected Python exception; pass it to the
|
||||||
|
# optional handler, if it is defined.
|
||||||
|
if self.exceptionHandler:
|
||||||
|
self.exceptionHandler()
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
def setSessionId(self, sessionId):
|
def setSessionId(self, sessionId):
|
||||||
""" This message should come in at startup. """
|
""" This message should come in at startup. """
|
||||||
self.sessionId = sessionId
|
self.sessionId = sessionId
|
||||||
|
@ -73,6 +73,17 @@ close() {
|
|||||||
_buf.close();
|
_buf.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: HandleStream::close_handle
|
||||||
|
// Access: Public
|
||||||
|
// Description: Closes the underlying handle, *without* attempting to
|
||||||
|
// flush the stream.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline void HandleStream::
|
||||||
|
close_handle() {
|
||||||
|
_buf.close_handle();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: HandleStream::get_handle
|
// Function: HandleStream::get_handle
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
inline void open_read(FHandle handle);
|
inline void open_read(FHandle handle);
|
||||||
inline void open_write(FHandle handle);
|
inline void open_write(FHandle handle);
|
||||||
inline void close();
|
inline void close();
|
||||||
|
inline void close_handle();
|
||||||
|
|
||||||
inline FHandle get_handle() const;
|
inline FHandle get_handle() const;
|
||||||
|
|
||||||
|
@ -36,12 +36,9 @@ HandleStreamBuf() {
|
|||||||
_is_open_read = false;
|
_is_open_read = false;
|
||||||
_is_open_write = false;
|
_is_open_write = false;
|
||||||
|
|
||||||
#ifdef _WIN32
|
_handle = INVALID_HANDLE_VALUE;
|
||||||
// Windows case.
|
|
||||||
_handle = NULL;
|
INIT_LOCK(_lock);
|
||||||
#else
|
|
||||||
_handle = -1;
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
_buffer = new char[handle_buffer_size];
|
_buffer = new char[handle_buffer_size];
|
||||||
char *ebuf = _buffer + handle_buffer_size;
|
char *ebuf = _buffer + handle_buffer_size;
|
||||||
@ -59,6 +56,8 @@ HandleStreamBuf::
|
|||||||
close();
|
close();
|
||||||
|
|
||||||
delete[] _buffer;
|
delete[] _buffer;
|
||||||
|
|
||||||
|
DESTROY_LOCK(_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -123,6 +122,20 @@ close() {
|
|||||||
// Make sure the write buffer is flushed.
|
// Make sure the write buffer is flushed.
|
||||||
sync();
|
sync();
|
||||||
|
|
||||||
|
close_handle();
|
||||||
|
|
||||||
|
pbump(pbase() - pptr());
|
||||||
|
gbump(egptr() - gptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: HandleStreamBuf::close_handle
|
||||||
|
// Access: Public
|
||||||
|
// Description: Closes the underlying handle, *without* attempting to
|
||||||
|
// flush the stream.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void HandleStreamBuf::
|
||||||
|
close_handle() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (_handle != NULL) {
|
if (_handle != NULL) {
|
||||||
CloseHandle(_handle);
|
CloseHandle(_handle);
|
||||||
@ -137,9 +150,6 @@ close() {
|
|||||||
|
|
||||||
_is_open_read = false;
|
_is_open_read = false;
|
||||||
_is_open_write = false;
|
_is_open_write = false;
|
||||||
|
|
||||||
pbump(pbase() - pptr());
|
|
||||||
gbump(egptr() - gptr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -150,11 +160,15 @@ close() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int HandleStreamBuf::
|
int HandleStreamBuf::
|
||||||
overflow(int ch) {
|
overflow(int ch) {
|
||||||
|
ACQUIRE_LOCK(_lock);
|
||||||
|
|
||||||
bool okflag = true;
|
bool okflag = true;
|
||||||
|
|
||||||
|
assert(pptr() >= pbase());
|
||||||
size_t n = pptr() - pbase();
|
size_t n = pptr() - pbase();
|
||||||
if (n != 0) {
|
if (n != 0) {
|
||||||
size_t wrote = write_chars(pbase(), n);
|
size_t wrote = write_chars(pbase(), n);
|
||||||
|
assert(wrote <= n);
|
||||||
pbump(-(int)wrote);
|
pbump(-(int)wrote);
|
||||||
if (wrote != n) {
|
if (wrote != n) {
|
||||||
okflag = false;
|
okflag = false;
|
||||||
@ -172,6 +186,8 @@ overflow(int ch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELEASE_LOCK(_lock);
|
||||||
|
|
||||||
if (!okflag) {
|
if (!okflag) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
@ -186,11 +202,16 @@ overflow(int ch) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int HandleStreamBuf::
|
int HandleStreamBuf::
|
||||||
sync() {
|
sync() {
|
||||||
|
ACQUIRE_LOCK(_lock);
|
||||||
|
assert(pptr() >= pbase());
|
||||||
size_t n = pptr() - pbase();
|
size_t n = pptr() - pbase();
|
||||||
|
|
||||||
size_t wrote = write_chars(pbase(), n);
|
size_t wrote = write_chars(pbase(), n);
|
||||||
|
assert(wrote <= n);
|
||||||
pbump(-(int)wrote);
|
pbump(-(int)wrote);
|
||||||
|
|
||||||
|
RELEASE_LOCK(_lock);
|
||||||
|
|
||||||
if (n != wrote) {
|
if (n != wrote) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
@ -205,6 +226,7 @@ sync() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int HandleStreamBuf::
|
int HandleStreamBuf::
|
||||||
underflow() {
|
underflow() {
|
||||||
|
ACQUIRE_LOCK(_lock);
|
||||||
// Sometimes underflow() is called even if the buffer is not empty.
|
// Sometimes underflow() is called even if the buffer is not empty.
|
||||||
if (gptr() >= egptr()) {
|
if (gptr() >= egptr()) {
|
||||||
// Mark the buffer filled (with buffer_size bytes).
|
// Mark the buffer filled (with buffer_size bytes).
|
||||||
@ -218,6 +240,7 @@ underflow() {
|
|||||||
// Oops, we didn't read what we thought we would.
|
// Oops, we didn't read what we thought we would.
|
||||||
if (read_count == 0) {
|
if (read_count == 0) {
|
||||||
gbump(num_bytes);
|
gbump(num_bytes);
|
||||||
|
RELEASE_LOCK(_lock);
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +252,10 @@ underflow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (unsigned char)*gptr();
|
unsigned char next = *gptr();
|
||||||
|
RELEASE_LOCK(_lock);
|
||||||
|
|
||||||
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -309,6 +335,7 @@ write_chars(const char *start, size_t length) {
|
|||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
BOOL success = WriteFile(_handle, start, length, &bytes_written, NULL);
|
BOOL success = WriteFile(_handle, start, length, &bytes_written, NULL);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
assert(bytes_written <= length);
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
if (error != ERROR_NO_DATA && error != ERROR_BROKEN_PIPE) {
|
if (error != ERROR_NO_DATA && error != ERROR_BROKEN_PIPE) {
|
||||||
cerr << "Error writing " << length
|
cerr << "Error writing " << length
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define HANDLESTREAMBUF_H
|
#define HANDLESTREAMBUF_H
|
||||||
|
|
||||||
#include "fhandle.h"
|
#include "fhandle.h"
|
||||||
|
#include "p3d_lock.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -34,6 +35,7 @@ public:
|
|||||||
bool is_open_read() const;
|
bool is_open_read() const;
|
||||||
bool is_open_write() const;
|
bool is_open_write() const;
|
||||||
void close();
|
void close();
|
||||||
|
void close_handle();
|
||||||
|
|
||||||
inline FHandle get_handle() const;
|
inline FHandle get_handle() const;
|
||||||
|
|
||||||
@ -51,6 +53,7 @@ private:
|
|||||||
bool _is_open_write;
|
bool _is_open_write;
|
||||||
|
|
||||||
FHandle _handle;
|
FHandle _handle;
|
||||||
|
LOCK _lock;
|
||||||
|
|
||||||
char *_buffer;
|
char *_buffer;
|
||||||
};
|
};
|
||||||
|
@ -61,14 +61,14 @@ get_session_key() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::get_python_version
|
// Function: P3DInstance::get_session
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Returns a string that uniquely identifies this
|
// Description: Returns the P3DSession that is hosting this instance,
|
||||||
// instance's required Python version.
|
// or NULL if the instance is not running.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
inline const string &P3DInstance::
|
inline P3DSession *P3DInstance::
|
||||||
get_python_version() const {
|
get_session() const {
|
||||||
return _python_version;
|
return _session;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -58,6 +58,7 @@ P3DInstance(P3D_request_ready_func *func,
|
|||||||
{
|
{
|
||||||
_browser_script_object = NULL;
|
_browser_script_object = NULL;
|
||||||
_panda_script_object = new P3DMainObject;
|
_panda_script_object = new P3DMainObject;
|
||||||
|
_panda_script_object->set_instance(this);
|
||||||
_user_data = user_data;
|
_user_data = user_data;
|
||||||
_request_pending = false;
|
_request_pending = false;
|
||||||
_temp_p3d_filename = NULL;
|
_temp_p3d_filename = NULL;
|
||||||
@ -113,6 +114,7 @@ P3DInstance::
|
|||||||
|
|
||||||
nout << "panda_script_object ref = "
|
nout << "panda_script_object ref = "
|
||||||
<< _panda_script_object->_ref_count << "\n";
|
<< _panda_script_object->_ref_count << "\n";
|
||||||
|
_panda_script_object->set_instance(NULL);
|
||||||
P3D_OBJECT_DECREF(_panda_script_object);
|
P3D_OBJECT_DECREF(_panda_script_object);
|
||||||
|
|
||||||
// Tell all of the packages that we're no longer in business for
|
// Tell all of the packages that we're no longer in business for
|
||||||
@ -458,7 +460,7 @@ bake_requests() {
|
|||||||
// No more requests to process right now.
|
// No more requests to process right now.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we've got a request in XML form; convert it to P3D_request
|
// Now we've got a request in XML form; convert it to P3D_request
|
||||||
// form.
|
// form.
|
||||||
TiXmlElement *xrequest = doc->FirstChildElement("request");
|
TiXmlElement *xrequest = doc->FirstChildElement("request");
|
||||||
@ -1000,6 +1002,11 @@ make_p3d_request(TiXmlElement *xrequest) {
|
|||||||
// We no longer need to keep this reference.
|
// We no longer need to keep this reference.
|
||||||
_session->drop_p3dobj(object_id);
|
_session->drop_p3dobj(object_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strcmp(rtype, "stop") == 0) {
|
||||||
|
// A stop request from Python code. This is kind of weird, but OK.
|
||||||
|
request = new P3D_request;
|
||||||
|
request->_request_type = P3D_RT_stop;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nout << "Ignoring request of type " << rtype << "\n";
|
nout << "Ignoring request of type " << rtype << "\n";
|
||||||
|
@ -82,7 +82,8 @@ public:
|
|||||||
|
|
||||||
inline int get_instance_id() const;
|
inline int get_instance_id() const;
|
||||||
inline const string &get_session_key() const;
|
inline const string &get_session_key() const;
|
||||||
inline const string &get_python_version() const;
|
|
||||||
|
inline P3DSession *get_session() const;
|
||||||
|
|
||||||
inline P3D_request_ready_func *get_request_ready_func() const;
|
inline P3D_request_ready_func *get_request_ready_func() const;
|
||||||
|
|
||||||
@ -158,7 +159,6 @@ private:
|
|||||||
|
|
||||||
int _instance_id;
|
int _instance_id;
|
||||||
string _session_key;
|
string _session_key;
|
||||||
string _python_version;
|
|
||||||
string _log_basename;
|
string _log_basename;
|
||||||
bool _hidden;
|
bool _hidden;
|
||||||
bool _allow_python_dev;
|
bool _allow_python_dev;
|
||||||
|
@ -89,6 +89,21 @@ get_log_directory() const {
|
|||||||
return _log_directory;
|
return _log_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstanceManager::get_log_pathname
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the filename of the system log file; this
|
||||||
|
// file is responsible for downloading and installing
|
||||||
|
// updates, and launching applications. This is
|
||||||
|
// different from the session log file(s), which
|
||||||
|
// represent the output from a particular Python
|
||||||
|
// session.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline const string &P3DInstanceManager::
|
||||||
|
get_log_pathname() const {
|
||||||
|
return _log_pathname;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstanceManager::get_keep_cwd
|
// Function: P3DInstanceManager::get_keep_cwd
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
inline const string &get_root_dir() const;
|
inline const string &get_root_dir() const;
|
||||||
inline const string &get_platform() const;
|
inline const string &get_platform() const;
|
||||||
inline const string &get_log_directory() const;
|
inline const string &get_log_directory() const;
|
||||||
|
inline const string &get_log_pathname() const;
|
||||||
inline bool get_keep_cwd() const;
|
inline bool get_keep_cwd() const;
|
||||||
|
|
||||||
P3DInstance *
|
P3DInstance *
|
||||||
|
@ -13,6 +13,11 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "p3dMainObject.h"
|
#include "p3dMainObject.h"
|
||||||
|
#include "p3dInstance.h"
|
||||||
|
#include "p3dSession.h"
|
||||||
|
#include "p3dUndefinedObject.h"
|
||||||
|
#include "p3dStringObject.h"
|
||||||
|
#include "p3dInstanceManager.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DMainObject::Constructor
|
// Function: P3DMainObject::Constructor
|
||||||
@ -178,6 +183,13 @@ set_property(const string &property, P3D_object *value) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool P3DMainObject::
|
bool P3DMainObject::
|
||||||
has_method(const string &method_name) {
|
has_method(const string &method_name) {
|
||||||
|
// Some special-case methods implemented in-place.
|
||||||
|
if (method_name == "read_game_log") {
|
||||||
|
return true;
|
||||||
|
} else if (method_name == "read_system_log") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_pyobj == NULL) {
|
if (_pyobj == NULL) {
|
||||||
// No methods until we get our pyobj.
|
// No methods until we get our pyobj.
|
||||||
return false;
|
return false;
|
||||||
@ -202,6 +214,12 @@ has_method(const string &method_name) {
|
|||||||
P3D_object *P3DMainObject::
|
P3D_object *P3DMainObject::
|
||||||
call(const string &method_name, bool needs_response,
|
call(const string &method_name, bool needs_response,
|
||||||
P3D_object *params[], int num_params) {
|
P3D_object *params[], int num_params) {
|
||||||
|
if (method_name == "read_game_log") {
|
||||||
|
return call_read_game_log();
|
||||||
|
} else if (method_name == "read_system_log") {
|
||||||
|
return call_read_system_log();
|
||||||
|
}
|
||||||
|
|
||||||
if (_pyobj == NULL) {
|
if (_pyobj == NULL) {
|
||||||
// No methods until we get our pyobj.
|
// No methods until we get our pyobj.
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -263,3 +281,88 @@ P3D_object *P3DMainObject::
|
|||||||
get_pyobj() const {
|
get_pyobj() const {
|
||||||
return _pyobj;
|
return _pyobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMainObject::set_instance
|
||||||
|
// Access: Public
|
||||||
|
// Description: Sets a callback pointer to the instance that owns
|
||||||
|
// this object. When this instance destructs, it clears
|
||||||
|
// this pointer to NULL.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DMainObject::
|
||||||
|
set_instance(P3DInstance *inst) {
|
||||||
|
_inst = inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMainObject::call_read_game_log
|
||||||
|
// Access: Private
|
||||||
|
// Description: Reads the entire logfile as a string, and returns it
|
||||||
|
// to the calling JavaScript process.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
P3D_object *P3DMainObject::
|
||||||
|
call_read_game_log() {
|
||||||
|
nout << "call_read_game_log: " << _inst << "\n";
|
||||||
|
if (_inst == NULL) {
|
||||||
|
return new P3DUndefinedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
P3DSession *session = _inst->get_session();
|
||||||
|
nout << "session = " << session << "\n";
|
||||||
|
|
||||||
|
string log_pathname = session->get_log_pathname();
|
||||||
|
nout << "log_pathname = " << log_pathname << "\n";
|
||||||
|
|
||||||
|
ifstream log(log_pathname.c_str(), ios::in);
|
||||||
|
|
||||||
|
// Get the size of the file.
|
||||||
|
log.seekg(0, ios::end);
|
||||||
|
size_t size = (size_t)log.tellg();
|
||||||
|
log.seekg(0, ios::beg);
|
||||||
|
|
||||||
|
// Read the entire file into memory all at once.
|
||||||
|
char *buffer = new char[size];
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.read(buffer, size);
|
||||||
|
P3D_object *result = new P3DStringObject(buffer, size);
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DMainObject::call_read_system_log
|
||||||
|
// Access: Private
|
||||||
|
// Description: As above, but reads the system log, the logfile for
|
||||||
|
// the installation process.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
P3D_object *P3DMainObject::
|
||||||
|
call_read_system_log() {
|
||||||
|
nout << "call_read_system_log: " << _inst << "\n";
|
||||||
|
|
||||||
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
string log_pathname = inst_mgr->get_log_pathname();
|
||||||
|
nout << "log_pathname = " << log_pathname << "\n";
|
||||||
|
|
||||||
|
ifstream log(log_pathname.c_str(), ios::in);
|
||||||
|
|
||||||
|
// Get the size of the file.
|
||||||
|
log.seekg(0, ios::end);
|
||||||
|
size_t size = (size_t)log.tellg();
|
||||||
|
log.seekg(0, ios::beg);
|
||||||
|
|
||||||
|
// Read the entire file into memory all at once.
|
||||||
|
char *buffer = new char[size];
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.read(buffer, size);
|
||||||
|
P3D_object *result = new P3DStringObject(buffer, size);
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class P3DSession;
|
class P3DSession;
|
||||||
|
class P3DInstance;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : P3DMainObject
|
// Class : P3DMainObject
|
||||||
@ -63,8 +64,15 @@ public:
|
|||||||
void set_pyobj(P3D_object *pyobj);
|
void set_pyobj(P3D_object *pyobj);
|
||||||
P3D_object *get_pyobj() const;
|
P3D_object *get_pyobj() const;
|
||||||
|
|
||||||
|
void set_instance(P3DInstance *inst);
|
||||||
|
|
||||||
|
private:
|
||||||
|
P3D_object *call_read_game_log();
|
||||||
|
P3D_object *call_read_system_log();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
P3D_object *_pyobj;
|
P3D_object *_pyobj;
|
||||||
|
P3DInstance *_inst;
|
||||||
|
|
||||||
// This map is used to store properties and retrieve until
|
// This map is used to store properties and retrieve until
|
||||||
// set_pyobj() is called for the firs ttime. At that point, the
|
// set_pyobj() is called for the firs ttime. At that point, the
|
||||||
|
@ -32,7 +32,6 @@ main(int argc, char *argv[]) {
|
|||||||
const char *archive_file = NULL;
|
const char *archive_file = NULL;
|
||||||
const char *input_handle_str = NULL;
|
const char *input_handle_str = NULL;
|
||||||
const char *output_handle_str = NULL;
|
const char *output_handle_str = NULL;
|
||||||
const char *error_handle_str = NULL;
|
|
||||||
const char *interactive_console_str = NULL;
|
const char *interactive_console_str = NULL;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@ -45,10 +44,7 @@ main(int argc, char *argv[]) {
|
|||||||
output_handle_str = argv[3];
|
output_handle_str = argv[3];
|
||||||
}
|
}
|
||||||
if (argc > 4) {
|
if (argc > 4) {
|
||||||
error_handle_str = argv[4];
|
interactive_console_str = argv[4];
|
||||||
}
|
|
||||||
if (argc > 5) {
|
|
||||||
interactive_console_str = argv[5];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archive_file == NULL || *archive_file == '\0') {
|
if (archive_file == NULL || *archive_file == '\0') {
|
||||||
@ -74,15 +70,6 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FHandle error_handle = invalid_fhandle;
|
|
||||||
if (error_handle_str != NULL && *error_handle_str) {
|
|
||||||
stringstream stream(error_handle_str);
|
|
||||||
stream >> error_handle;
|
|
||||||
if (!stream) {
|
|
||||||
error_handle = invalid_fhandle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool interactive_console = false;
|
bool interactive_console = false;
|
||||||
if (interactive_console_str != NULL && *interactive_console_str) {
|
if (interactive_console_str != NULL && *interactive_console_str) {
|
||||||
stringstream stream(interactive_console_str);
|
stringstream stream(interactive_console_str);
|
||||||
@ -93,12 +80,11 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "handles: " << input_handle << ", " << output_handle
|
cerr << "handles: " << input_handle << ", " << output_handle << "\n";
|
||||||
<< ", " << error_handle << "\n";
|
|
||||||
cerr << "interactive_console = " << interactive_console << "\n";
|
cerr << "interactive_console = " << interactive_console << "\n";
|
||||||
|
|
||||||
if (!run_p3dpython(program_name, archive_file, input_handle, output_handle,
|
if (!run_p3dpython(program_name, archive_file, input_handle, output_handle,
|
||||||
error_handle, interactive_console)) {
|
NULL, interactive_console)) {
|
||||||
cerr << "Failure on startup.\n";
|
cerr << "Failure on startup.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ P3DPythonRun *P3DPythonRun::_global_ptr = NULL;
|
|||||||
P3DPythonRun::
|
P3DPythonRun::
|
||||||
P3DPythonRun(const char *program_name, const char *archive_file,
|
P3DPythonRun(const char *program_name, const char *archive_file,
|
||||||
FHandle input_handle, FHandle output_handle,
|
FHandle input_handle, FHandle output_handle,
|
||||||
FHandle error_handle, bool interactive_console) {
|
const char *log_pathname, bool interactive_console) {
|
||||||
_read_thread_continue = false;
|
_read_thread_continue = false;
|
||||||
_program_continue = true;
|
_program_continue = true;
|
||||||
_session_terminated = false;
|
_session_terminated = false;
|
||||||
@ -74,11 +74,14 @@ P3DPythonRun(const char *program_name, const char *archive_file,
|
|||||||
PySys_SetArgv(_py_argc, _py_argv);
|
PySys_SetArgv(_py_argc, _py_argv);
|
||||||
|
|
||||||
// Open the error output before we do too much more.
|
// Open the error output before we do too much more.
|
||||||
_error_log.open_write(error_handle);
|
if (log_pathname != NULL && *log_pathname != '\0') {
|
||||||
if (!_error_log.fail()) {
|
Filename f = Filename::from_os_specific(log_pathname);
|
||||||
// Set up the indicated error log as the Notify output.
|
f.set_text();
|
||||||
_error_log.setf(ios::unitbuf);
|
if (f.open_write(_error_log)) {
|
||||||
Notify::ptr()->set_ostream_ptr(&_error_log, false);
|
// Set up the indicated error log as the Notify output.
|
||||||
|
_error_log.setf(ios::unitbuf);
|
||||||
|
Notify::ptr()->set_ostream_ptr(&_error_log, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the pipe streams with the input and output handles from the
|
// Open the pipe streams with the input and output handles from the
|
||||||
@ -103,6 +106,9 @@ P3DPythonRun(const char *program_name, const char *archive_file,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DPythonRun::
|
P3DPythonRun::
|
||||||
~P3DPythonRun() {
|
~P3DPythonRun() {
|
||||||
|
// Close the write pipe, so the parent process will terminate us.
|
||||||
|
_pipe_write.close();
|
||||||
|
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
|
||||||
join_read_thread();
|
join_read_thread();
|
||||||
@ -339,22 +345,32 @@ run_python() {
|
|||||||
|
|
||||||
Py_DECREF(check_comm);
|
Py_DECREF(check_comm);
|
||||||
|
|
||||||
// Finally, get lost in taskMgr.run().
|
// Finally, get lost in AppRunner.run() (which is really a call to
|
||||||
bool okflag = true;
|
// taskMgr.run()).
|
||||||
PyObject *done = PyObject_CallMethod(_taskMgr, (char *)"run", (char *)"");
|
PyObject *done = PyObject_CallMethod(_runner, (char *)"run", (char *)"");
|
||||||
if (done == NULL) {
|
if (done == NULL) {
|
||||||
|
// An uncaught application exception, and not handled by
|
||||||
|
// appRunner.exceptionHandler.
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
okflag = false;
|
|
||||||
} else {
|
if (_interactive_console) {
|
||||||
Py_DECREF(done);
|
// Give an interactive user a chance to explore the exception.
|
||||||
|
run_interactive_console();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're done.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A normal exit from the taskManager. We're presumably done.
|
||||||
|
Py_DECREF(done);
|
||||||
|
|
||||||
if (_interactive_console) {
|
if (_interactive_console) {
|
||||||
run_interactive_console();
|
run_interactive_console();
|
||||||
okflag = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return okflag;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1032,8 +1048,6 @@ spawn_read_thread() {
|
|||||||
void P3DPythonRun::
|
void P3DPythonRun::
|
||||||
join_read_thread() {
|
join_read_thread() {
|
||||||
_read_thread_continue = false;
|
_read_thread_continue = false;
|
||||||
_pipe_read.close();
|
|
||||||
|
|
||||||
JOIN_THREAD(_read_thread);
|
JOIN_THREAD(_read_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "p3d_lock.h"
|
#include "p3d_lock.h"
|
||||||
#include "handleStream.h"
|
#include "handleStream.h"
|
||||||
#include "p3dCInstance.h"
|
#include "p3dCInstance.h"
|
||||||
|
#include "pandaFileStreamBuf.h"
|
||||||
#include "pythonTask.h"
|
#include "pythonTask.h"
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
#include "pdeque.h"
|
#include "pdeque.h"
|
||||||
@ -68,7 +69,7 @@ class P3DPythonRun {
|
|||||||
public:
|
public:
|
||||||
P3DPythonRun(const char *program_name, const char *archive_file,
|
P3DPythonRun(const char *program_name, const char *archive_file,
|
||||||
FHandle input_handle, FHandle output_handle,
|
FHandle input_handle, FHandle output_handle,
|
||||||
FHandle error_handle, bool interactive_console);
|
const char *log_pathname, bool interactive_console);
|
||||||
~P3DPythonRun();
|
~P3DPythonRun();
|
||||||
|
|
||||||
bool run_python();
|
bool run_python();
|
||||||
@ -155,7 +156,7 @@ private:
|
|||||||
|
|
||||||
HandleStream _pipe_read;
|
HandleStream _pipe_read;
|
||||||
HandleStream _pipe_write;
|
HandleStream _pipe_write;
|
||||||
HandleStream _error_log;
|
pofstream _error_log;
|
||||||
|
|
||||||
bool _read_thread_continue;
|
bool _read_thread_continue;
|
||||||
bool _program_continue;
|
bool _program_continue;
|
||||||
|
@ -25,14 +25,16 @@ get_session_key() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSession::get_python_version
|
// Function: P3DSession::get_log_pathname
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Returns a string that uniquely identifies this
|
// Description: Returns the log filename for this particular session,
|
||||||
// session's required Python version.
|
// if the session was started and if it has a log file.
|
||||||
|
// Returns empty string if the session never started or
|
||||||
|
// if it lacks a log file.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
inline const string &P3DSession::
|
inline const string &P3DSession::
|
||||||
get_python_version() const {
|
get_log_pathname() const {
|
||||||
return _python_version;
|
return _log_pathname;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -52,7 +52,6 @@ P3DSession(P3DInstance *inst) {
|
|||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
_session_id = inst_mgr->get_unique_id();
|
_session_id = inst_mgr->get_unique_id();
|
||||||
_session_key = inst->get_session_key();
|
_session_key = inst->get_session_key();
|
||||||
_python_version = inst->get_python_version();
|
|
||||||
|
|
||||||
_start_dir = inst_mgr->get_root_dir() + "/start";
|
_start_dir = inst_mgr->get_root_dir() + "/start";
|
||||||
_p3dpython_one_process = false;
|
_p3dpython_one_process = false;
|
||||||
@ -180,9 +179,6 @@ shutdown() {
|
|||||||
|
|
||||||
_p3dpython_running = false;
|
_p3dpython_running = false;
|
||||||
_p3dpython_started = false;
|
_p3dpython_started = false;
|
||||||
|
|
||||||
// Close the pipe now.
|
|
||||||
_pipe_read.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are any leftover commands in the queue (presumably
|
// If there are any leftover commands in the queue (presumably
|
||||||
@ -195,6 +191,9 @@ shutdown() {
|
|||||||
_commands.clear();
|
_commands.clear();
|
||||||
|
|
||||||
join_read_thread();
|
join_read_thread();
|
||||||
|
|
||||||
|
// Close the pipe now.
|
||||||
|
_pipe_read.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -211,7 +210,6 @@ void P3DSession::
|
|||||||
start_instance(P3DInstance *inst) {
|
start_instance(P3DInstance *inst) {
|
||||||
assert(inst->_session == NULL);
|
assert(inst->_session == NULL);
|
||||||
assert(inst->get_session_key() == _session_key);
|
assert(inst->get_session_key() == _session_key);
|
||||||
assert(inst->get_python_version() == _python_version);
|
|
||||||
|
|
||||||
inst->ref();
|
inst->ref();
|
||||||
ACQUIRE_LOCK(_instances_lock);
|
ACQUIRE_LOCK(_instances_lock);
|
||||||
@ -684,6 +682,10 @@ start_p3dpython(P3DInstance *inst) {
|
|||||||
mkdir_complete(_start_dir, nout);
|
mkdir_complete(_start_dir, nout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also make sure the prc directory is present.
|
||||||
|
string prc_root = inst_mgr->get_root_dir() + "/prc";
|
||||||
|
mkdir_complete(prc_root, nout);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char sep = ';';
|
char sep = ';';
|
||||||
#else
|
#else
|
||||||
@ -716,7 +718,14 @@ start_p3dpython(P3DInstance *inst) {
|
|||||||
|
|
||||||
string dyld_path = search_path;
|
string dyld_path = search_path;
|
||||||
string python_path = search_path;
|
string python_path = search_path;
|
||||||
string prc_path = search_path;
|
string prc_path = prc_root + sep + search_path;
|
||||||
|
|
||||||
|
string prc_name = inst->get_fparams().lookup_token("prc_name");
|
||||||
|
if (!prc_name.empty()) {
|
||||||
|
// Add the prc_name to the path too, even if this directory doesn't
|
||||||
|
// actually exist.
|
||||||
|
prc_path = inst_mgr->get_root_dir() + "/" + prc_name + sep + prc_path;
|
||||||
|
}
|
||||||
|
|
||||||
if (keep_pythonpath) {
|
if (keep_pythonpath) {
|
||||||
// With keep_pythonpath true, we preserve the PYTHONPATH setting
|
// With keep_pythonpath true, we preserve the PYTHONPATH setting
|
||||||
@ -929,34 +938,8 @@ start_p3dpython(P3DInstance *inst) {
|
|||||||
// Create the error stream for log output. This means opening the
|
// Create the error stream for log output. This means opening the
|
||||||
// logfile, if we have one, or keeping the standard error if we
|
// logfile, if we have one, or keeping the standard error if we
|
||||||
// don't.
|
// don't.
|
||||||
_got_error_handle = false;
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
_error_handle = GetStdHandle(STD_ERROR_HANDLE);
|
|
||||||
if (!_log_pathname.empty()) {
|
|
||||||
HANDLE handle = CreateFile
|
|
||||||
(_log_pathname.c_str(), GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
NULL, CREATE_ALWAYS, 0, NULL);
|
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
|
||||||
_error_handle = handle;
|
|
||||||
SetHandleInformation(_error_handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
|
||||||
_got_error_handle = true;
|
|
||||||
} else {
|
|
||||||
nout << "Unable to open " << _log_pathname << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
_error_handle = STDERR_FILENO;
|
|
||||||
if (!_log_pathname.empty()) {
|
|
||||||
int logfile_fd = open(_log_pathname.c_str(),
|
|
||||||
O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (logfile_fd < 0) {
|
|
||||||
nout << "Unable to open " << _log_pathname << "\n";
|
|
||||||
} else {
|
|
||||||
_error_handle = logfile_fd;
|
|
||||||
_got_error_handle = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
// Get the filename of the Panda3D multifile. We need to pass this
|
// Get the filename of the Panda3D multifile. We need to pass this
|
||||||
@ -1049,7 +1032,6 @@ join_read_thread() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_read_thread_continue = false;
|
_read_thread_continue = false;
|
||||||
_pipe_read.close();
|
|
||||||
|
|
||||||
JOIN_THREAD(_read_thread);
|
JOIN_THREAD(_read_thread);
|
||||||
_started_read_thread = false;
|
_started_read_thread = false;
|
||||||
@ -1171,10 +1153,34 @@ win_create_process() {
|
|||||||
// Make sure we see an error dialog if there is a missing DLL.
|
// Make sure we see an error dialog if there is a missing DLL.
|
||||||
SetErrorMode(0);
|
SetErrorMode(0);
|
||||||
|
|
||||||
|
// Open the log file.
|
||||||
|
HANDLE error_handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
bool got_error_handle = false;
|
||||||
|
if (!_log_pathname.empty()) {
|
||||||
|
HANDLE handle = CreateFile
|
||||||
|
(_log_pathname.c_str(), GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL, CREATE_ALWAYS, 0, NULL);
|
||||||
|
if (handle != INVALID_HANDLE_VALUE) {
|
||||||
|
error_handle = handle;
|
||||||
|
SetHandleInformation(error_handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
||||||
|
got_error_handle = true;
|
||||||
|
} else {
|
||||||
|
nout << "Unable to open " << _log_pathname << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STARTUPINFO startup_info;
|
STARTUPINFO startup_info;
|
||||||
ZeroMemory(&startup_info, sizeof(STARTUPINFO));
|
ZeroMemory(&startup_info, sizeof(STARTUPINFO));
|
||||||
startup_info.cb = sizeof(startup_info);
|
startup_info.cb = sizeof(startup_info);
|
||||||
|
|
||||||
|
// Set up the I/O handles. We send stderr and stdout to our
|
||||||
|
// error_handle.
|
||||||
|
startup_info.hStdError = error_handle;
|
||||||
|
startup_info.hStdOutput = error_handle;
|
||||||
|
startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
// Make sure the "python" console window is hidden.
|
// Make sure the "python" console window is hidden.
|
||||||
startup_info.wShowWindow = SW_HIDE;
|
startup_info.wShowWindow = SW_HIDE;
|
||||||
startup_info.dwFlags |= STARTF_USESHOWWINDOW;
|
startup_info.dwFlags |= STARTF_USESHOWWINDOW;
|
||||||
@ -1191,8 +1197,7 @@ win_create_process() {
|
|||||||
ostringstream stream;
|
ostringstream stream;
|
||||||
stream << "\"" << _p3dpython_exe << "\" \"" << _mf_filename
|
stream << "\"" << _p3dpython_exe << "\" \"" << _mf_filename
|
||||||
<< "\" \"" << _input_handle << "\" \"" << _output_handle
|
<< "\" \"" << _input_handle << "\" \"" << _output_handle
|
||||||
<< "\" \"" << _error_handle << "\" \"" << _interactive_console
|
<< "\" \"" << _interactive_console << "\"";
|
||||||
<< "\"";
|
|
||||||
|
|
||||||
// I'm not sure why CreateProcess wants a non-const char pointer for
|
// I'm not sure why CreateProcess wants a non-const char pointer for
|
||||||
// its command-line string, but I'm not taking chances. It gets a
|
// its command-line string, but I'm not taking chances. It gets a
|
||||||
@ -1213,8 +1218,8 @@ win_create_process() {
|
|||||||
// Close the pipe handles that are now owned by the child.
|
// Close the pipe handles that are now owned by the child.
|
||||||
CloseHandle(_output_handle);
|
CloseHandle(_output_handle);
|
||||||
CloseHandle(_input_handle);
|
CloseHandle(_input_handle);
|
||||||
if (_got_error_handle) {
|
if (got_error_handle) {
|
||||||
CloseHandle(_error_handle);
|
CloseHandle(error_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!started_program) {
|
if (!started_program) {
|
||||||
@ -1263,6 +1268,20 @@ posix_create_process() {
|
|||||||
_pipe_read.close();
|
_pipe_read.close();
|
||||||
_pipe_write.close();
|
_pipe_write.close();
|
||||||
|
|
||||||
|
if (!_log_pathname.empty()) {
|
||||||
|
// Open a logfile.
|
||||||
|
int logfile_fd = open(_log_pathname.c_str(),
|
||||||
|
O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||||
|
if (logfile_fd < 0) {
|
||||||
|
nout << "Unable to open " << _log_pathname << "\n";
|
||||||
|
} else {
|
||||||
|
// Redirect stderr and stdout onto our logfile.
|
||||||
|
dup2(logfile_fd, STDERR_FILENO);
|
||||||
|
dup2(logfile_fd, STDOUT_FILENO);
|
||||||
|
close(logfile_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_use_start_dir) {
|
if (_use_start_dir) {
|
||||||
if (chdir(_start_dir.c_str()) < 0) {
|
if (chdir(_start_dir.c_str()) < 0) {
|
||||||
nout << "Could not chdir to " << _start_dir << "\n";
|
nout << "Could not chdir to " << _start_dir << "\n";
|
||||||
@ -1290,13 +1309,9 @@ posix_create_process() {
|
|||||||
output_handle_stream << _output_handle;
|
output_handle_stream << _output_handle;
|
||||||
string output_handle_str = output_handle_stream.str();
|
string output_handle_str = output_handle_stream.str();
|
||||||
|
|
||||||
stringstream error_handle_stream;
|
|
||||||
error_handle_stream << _error_handle;
|
|
||||||
string error_handle_str = error_handle_stream.str();
|
|
||||||
|
|
||||||
execle(_p3dpython_exe.c_str(), _p3dpython_exe.c_str(),
|
execle(_p3dpython_exe.c_str(), _p3dpython_exe.c_str(),
|
||||||
_mf_filename.c_str(), input_handle_str.c_str(),
|
_mf_filename.c_str(), input_handle_str.c_str(),
|
||||||
output_handle_str.c_str(), error_handle_str.c_str(),
|
output_handle_str.c_str(),
|
||||||
_interactive_console ? "1" : "0", (char *)0, &ptrs[0]);
|
_interactive_console ? "1" : "0", (char *)0, &ptrs[0]);
|
||||||
nout << "Failed to exec " << _p3dpython_exe << "\n";
|
nout << "Failed to exec " << _p3dpython_exe << "\n";
|
||||||
_exit(1);
|
_exit(1);
|
||||||
@ -1305,9 +1320,6 @@ posix_create_process() {
|
|||||||
// Close the handles that are now owned by the child.
|
// Close the handles that are now owned by the child.
|
||||||
close(_input_handle);
|
close(_input_handle);
|
||||||
close(_output_handle);
|
close(_output_handle);
|
||||||
if (_got_error_handle) {
|
|
||||||
close(_error_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
@ -1391,7 +1403,7 @@ p3dpython_thread_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(),
|
if (!run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(),
|
||||||
_input_handle, _output_handle, _error_handle,
|
_input_handle, _output_handle, _log_pathname.c_str(),
|
||||||
_interactive_console)) {
|
_interactive_console)) {
|
||||||
nout << "Failure on startup.\n";
|
nout << "Failure on startup.\n";
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
inline const string &get_session_key() const;
|
inline const string &get_session_key() const;
|
||||||
inline const string &get_python_version() const;
|
inline const string &get_log_pathname() const;
|
||||||
|
|
||||||
void start_instance(P3DInstance *inst);
|
void start_instance(P3DInstance *inst);
|
||||||
void terminate_instance(P3DInstance *inst);
|
void terminate_instance(P3DInstance *inst);
|
||||||
@ -88,7 +88,6 @@ private:
|
|||||||
private:
|
private:
|
||||||
int _session_id;
|
int _session_id;
|
||||||
string _session_key;
|
string _session_key;
|
||||||
string _python_version;
|
|
||||||
string _log_pathname;
|
string _log_pathname;
|
||||||
string _python_root_dir;
|
string _python_root_dir;
|
||||||
string _start_dir;
|
string _start_dir;
|
||||||
@ -100,8 +99,7 @@ private:
|
|||||||
string _p3dpython_dll;
|
string _p3dpython_dll;
|
||||||
string _mf_filename;
|
string _mf_filename;
|
||||||
string _env;
|
string _env;
|
||||||
FHandle _input_handle, _output_handle, _error_handle;
|
FHandle _input_handle, _output_handle;
|
||||||
bool _got_error_handle;
|
|
||||||
bool _interactive_console;
|
bool _interactive_console;
|
||||||
|
|
||||||
typedef map<int, P3DInstance *> Instances;
|
typedef map<int, P3DInstance *> Instances;
|
||||||
|
@ -23,6 +23,15 @@ P3DStringObject::
|
|||||||
P3DStringObject(const string &value) : _value(value) {
|
P3DStringObject(const string &value) : _value(value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DStringObject::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
P3DStringObject::
|
||||||
|
P3DStringObject(const char *data, size_t size) : _value(data, size) {
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DStringObject::Copy Constructor
|
// Function: P3DStringObject::Copy Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
class P3DStringObject : public P3DObject {
|
class P3DStringObject : public P3DObject {
|
||||||
public:
|
public:
|
||||||
P3DStringObject(const string &value);
|
P3DStringObject(const string &value);
|
||||||
|
P3DStringObject(const char *data, size_t size);
|
||||||
P3DStringObject(const P3DStringObject ©);
|
P3DStringObject(const P3DStringObject ©);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
bool
|
bool
|
||||||
run_p3dpython(const char *program_name, const char *archive_file,
|
run_p3dpython(const char *program_name, const char *archive_file,
|
||||||
FHandle input_handle, FHandle output_handle,
|
FHandle input_handle, FHandle output_handle,
|
||||||
FHandle error_handle, bool interactive_console) {
|
const char *log_pathname, bool interactive_console) {
|
||||||
P3DPythonRun::_global_ptr =
|
P3DPythonRun::_global_ptr =
|
||||||
new P3DPythonRun(program_name, archive_file, input_handle, output_handle,
|
new P3DPythonRun(program_name, archive_file, input_handle, output_handle,
|
||||||
error_handle, interactive_console);
|
log_pathname, interactive_console);
|
||||||
bool result = P3DPythonRun::_global_ptr->run_python();
|
bool result = P3DPythonRun::_global_ptr->run_python();
|
||||||
delete P3DPythonRun::_global_ptr;
|
delete P3DPythonRun::_global_ptr;
|
||||||
P3DPythonRun::_global_ptr = NULL;
|
P3DPythonRun::_global_ptr = NULL;
|
||||||
|
@ -29,12 +29,12 @@
|
|||||||
typedef bool
|
typedef bool
|
||||||
run_p3dpython_func(const char *program_name, const char *archive_file,
|
run_p3dpython_func(const char *program_name, const char *archive_file,
|
||||||
FHandle input_handle, FHandle output_handle,
|
FHandle input_handle, FHandle output_handle,
|
||||||
FHandle error_handle, bool interactive_console);
|
const char *log_pathname, bool interactive_console);
|
||||||
|
|
||||||
extern "C" EXPCL_P3DPYTHON bool
|
extern "C" EXPCL_P3DPYTHON bool
|
||||||
run_p3dpython(const char *program_name, const char *archive_file,
|
run_p3dpython(const char *program_name, const char *archive_file,
|
||||||
FHandle input_handle, FHandle output_handle,
|
FHandle input_handle, FHandle output_handle,
|
||||||
FHandle error_handle, bool interactive_console);
|
const char *log_pathname, bool interactive_console);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -182,6 +182,7 @@ class VFSLoader:
|
|||||||
|
|
||||||
filename = Filename(self.filename)
|
filename = Filename(self.filename)
|
||||||
filename.setExtension('py')
|
filename.setExtension('py')
|
||||||
|
filename.setText()
|
||||||
vfile = vfs.getFile(filename)
|
vfile = vfs.getFile(filename)
|
||||||
if not vfile:
|
if not vfile:
|
||||||
raise IOError
|
raise IOError
|
||||||
|
Loading…
x
Reference in New Issue
Block a user