file streaming, logfile cleanup

This commit is contained in:
David Rose 2009-07-17 17:33:12 +00:00
parent 208eee53c6
commit fb782894eb
11 changed files with 125 additions and 118 deletions

View File

@ -18,7 +18,7 @@
// Actually, we haven't implemented the binary I/O for XML files yet.
// We just map these directly to the classic formatted I/O for now.
static const bool debug_xml_output = true;
static const bool debug_xml_output = false;
////////////////////////////////////////////////////////////////////
// Function: write_xml

View File

@ -170,8 +170,6 @@ load_plugin(const string &p3d_plugin_filename) {
#endif // _WIN32
cerr << "Got module = " << module << "\n";
// Now get all of the function pointers.
P3D_initialize = (P3D_initialize_func *)get_func(module, "P3D_initialize");
P3D_finalize = (P3D_finalize_func *)get_func(module, "P3D_finalize");
@ -317,8 +315,6 @@ unload_plugin() {
return;
}
cerr << "unload_plugin called\n";
P3D_finalize();
unload_dso();
}

View File

@ -167,9 +167,6 @@ set_fparams(const P3DFileParams &fparams) {
string expression = _fparams.lookup_token("onpluginload");
if (!expression.empty() && _browser_script_object != NULL) {
P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str());
if (result != NULL) {
nout << "onpluginload returned: " << *result << "\n";
}
P3D_OBJECT_XDECREF(result);
}
@ -217,7 +214,6 @@ set_wparams(const P3DWindowParams &wparams) {
// to the browser. Set up this mechanism.
int x_size = _wparams.get_win_width();
int y_size = _wparams.get_win_height();
nout << "size = " << x_size << " * " << y_size << "\n" << flush;
if (_shared_fd == -1 && x_size != 0 && y_size != 0) {
_swbuffer = SubprocessWindowBuffer::new_buffer
(_shared_fd, _shared_mmap_size, _shared_filename, x_size, y_size);
@ -340,7 +336,6 @@ bake_requests() {
// No more requests to process right now.
return;
}
nout << "received: " << *doc << "\n" << flush;
// Now we've got a request in XML form; convert it to P3D_request
// form.
@ -365,7 +360,6 @@ bake_requests() {
////////////////////////////////////////////////////////////////////
void P3DInstance::
add_raw_request(TiXmlDocument *doc) {
nout << "add_raw_request " << this << "\n" << flush;
ACQUIRE_LOCK(_request_lock);
_raw_requests.push_back(doc);
_request_pending = true;
@ -379,7 +373,6 @@ add_raw_request(TiXmlDocument *doc) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
inst_mgr->signal_request_ready(this);
_session->signal_request_ready(this);
nout << "done add_raw_request " << this << "\n" << flush;
}
////////////////////////////////////////////////////////////////////
@ -505,7 +498,6 @@ handle_event(P3D_event_data event) {
Point pt = er->where;
GlobalToLocal(&pt);
P3D_window_handle window = _wparams.get_parent_window();
cerr << "mouse " << pt.h << " " << pt.v << "\n";
if (_swbuffer != NULL) {
SubprocessWindowBuffer::Event swb_event;
swb_event._source = SubprocessWindowBuffer::ES_mouse;
@ -531,7 +523,6 @@ handle_event(P3D_event_data event) {
case keyDown:
case keyUp:
case autoKey:
cerr << "keycode: " << hex << (er->message & 0xffff) << dec << "\n";
if (_swbuffer != NULL) {
SubprocessWindowBuffer::Event swb_event;
swb_event._source = SubprocessWindowBuffer::ES_keyboard;
@ -554,13 +545,14 @@ handle_event(P3D_event_data event) {
break;
case activateEvt:
cerr << "activate window: " << er->message << "\n";
break;
case diskEvt:
break;
case osEvt:
// Not getting this event for some reason?
/*
if ((er->message & 0xf0000000) == suspendResumeMessage) {
if (er->message & 1) {
cerr << "suspend\n";
@ -572,14 +564,13 @@ handle_event(P3D_event_data event) {
} else {
cerr << "unhandled osEvt: " << hex << er->message << dec << "\n";
}
*/
break;
case kHighLevelEvent:
cerr << "high level: " << er->message << "\n";
break;
default:
cerr << "unhandled event: " << er->what << ", " << er->message << "\n";
break;
}
@ -794,8 +785,6 @@ void P3DInstance::
handle_notify_request(const string &message) {
// We look for certain notify events that have particular meaning
// to this instance.
nout << "handle_notify: " << message << "\n";
if (message == "onpythonload") {
// Once Python is up and running, we can get the actual toplevel
// object from the Python side, and merge it with our own.

View File

@ -166,7 +166,6 @@ handle_event(P3D_event_data event) {
////////////////////////////////////////////////////////////////////
void P3DOsxSplashWindow::
paint_window() {
cerr << "paint_window, _image = " << _image << ", label = " << _install_label << "\n";
GrafPtr out_port = _wparams.get_parent_window()._port;
GrafPtr portSave = NULL;
Boolean portChanged = QDSwapPort(out_port, &portSave);
@ -253,8 +252,6 @@ paint_window() {
int ascent = font_info.ascent * numer.v / denom.v;
int descent = font_info.descent * numer.v / denom.v;
cerr << "ascent = " << font_info.ascent << " * " << numer.v << " / " << denom.v << "\n";
int text_width = TextWidth(_install_label.data(), 0, _install_label.size());
int text_x = (win_width - text_width) / 2;
int text_y = bar_y - descent - 8;

View File

@ -25,7 +25,6 @@ P3DPythonObject(P3DSession *session, int object_id) :
_object_id(object_id)
{
_session->ref();
nout << "new P3DPythonObject " << this << " : " << object_id << "\n" << flush;
}
////////////////////////////////////////////////////////////////////
@ -35,7 +34,6 @@ P3DPythonObject(P3DSession *session, int object_id) :
////////////////////////////////////////////////////////////////////
P3DPythonObject::
~P3DPythonObject() {
nout << "del P3DPythonObject " << this << " : " << _object_id << "\n";
// When the P3DPythonObject wrapper goes away, we have to inform the
// child process that we no longer need the corresponding PyObject
// to be kept around.

View File

@ -319,7 +319,6 @@ handle_command(TiXmlDocument *doc) {
} else if (strcmp(cmd, "drop_pyobj") == 0) {
int object_id;
if (xcommand->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {
nout << "got drop_pyobj(" << object_id << ")\n" << flush;
SentObjects::iterator si = _sent_objects.find(object_id);
if (si != _sent_objects.end()) {
PyObject *obj = (*si).second;
@ -813,7 +812,6 @@ py_request_func(PyObject *args) {
if (!PyArg_ParseTuple(extra_args, "i", &object_id)) {
return NULL;
}
nout << "got drop_p3dobj(" << object_id << ")\n" << flush;
xrequest->SetAttribute("object_id", object_id);
write_xml(_pipe_write, &doc, nout);

View File

@ -129,7 +129,6 @@ shutdown() {
int start_ms = start.tv_sec * 1000 + start.tv_usec / 1000;
int status;
nout << "waiting for pid " << _p3dpython_pid << "\n" << flush;
pid_t result = waitpid(_p3dpython_pid, &status, WNOHANG);
while (result != _p3dpython_pid) {
if (result == -1) {
@ -318,10 +317,7 @@ command_and_response(TiXmlDocument *command) {
write_xml(_pipe_write, command, nout);
delete command;
// Now block, waiting for a response to be delivered. We assume
// only one thread will be waiting at a time.
nout << "waiting for response " << response_id << "\n" << flush;
// Now block, waiting for the response to be delivered.
_response_ready.acquire();
Responses::iterator ri = _responses.find(response_id);
while (ri == _responses.end()) {
@ -387,13 +383,10 @@ command_and_response(TiXmlDocument *command) {
_response_ready.wait(0.5);
#endif // _WIN32
nout << "." << flush;
ri = _responses.find(response_id);
}
// When we exit the loop, we've found the desired response.
TiXmlDocument *response = (*ri).second;
nout << "got response: " << *response << "\n" << flush;
_responses.erase(ri);
_response_ready.release();
@ -616,7 +609,6 @@ signal_request_ready(P3DInstance *inst) {
////////////////////////////////////////////////////////////////////
void P3DSession::
drop_pyobj(int object_id) {
nout << "got drop_pyobj(" << object_id << ")\n" << flush;
if (_p3dpython_running) {
TiXmlDocument doc;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
@ -640,7 +632,6 @@ drop_pyobj(int object_id) {
////////////////////////////////////////////////////////////////////
void P3DSession::
drop_p3dobj(int object_id) {
nout << "got drop_p3dobj(" << object_id << ")\n" << flush;
SentObjects::iterator si = _sent_objects.find(object_id);
if (si != _sent_objects.end()) {
P3D_object *obj = (*si).second;
@ -828,7 +819,6 @@ rt_thread_run() {
////////////////////////////////////////////////////////////////////
void P3DSession::
rt_handle_request(TiXmlDocument *doc) {
nout << "rt_handle_request in " << this << "\n" << flush;
TiXmlElement *xresponse = doc->FirstChildElement("response");
if (xresponse != (TiXmlElement *)NULL) {
int response_id;
@ -840,7 +830,6 @@ rt_handle_request(TiXmlDocument *doc) {
assert(inserted);
_response_ready.notify();
_response_ready.release();
nout << "done a, rt_handle_request in " << this << "\n" << flush;
return;
}
}
@ -865,7 +854,6 @@ rt_handle_request(TiXmlDocument *doc) {
if (doc != NULL) {
delete doc;
}
nout << "done rt_handle_request in " << this << "\n" << flush;
}
////////////////////////////////////////////////////////////////////

View File

@ -180,15 +180,11 @@ set_property(const string &property, P3D_object *value) {
////////////////////////////////////////////////////////////////////
P3D_object *PPBrowserObject::
call(const string &method_name, P3D_object *params[], int num_params) const {
logfile << "call " << method_name << "(";
// First, convert all of the parameters.
NPVariant *npparams = new NPVariant[num_params];
for (int i = 0; i < num_params; ++i) {
_instance->p3dobj_to_variant(&npparams[i], params[i]);
_instance->output_np_variant(logfile, npparams[i]);
logfile << ", ";
}
logfile << ")\n";
NPVariant result;
if (method_name.empty()) {
@ -196,7 +192,6 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
if (!browser->invokeDefault(_instance->get_npp_instance(), _npobj,
npparams, num_params, &result)) {
// Failed to invoke.
logfile << "invokeDefault failed\n" << flush;
delete[] npparams;
return NULL;
}
@ -207,7 +202,6 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
if (!browser->invoke(_instance->get_npp_instance(), _npobj, method_id,
npparams, num_params, &result)) {
// Failed to invoke.
logfile << "invoke failed\n" << flush;
delete[] npparams;
return NULL;
}
@ -215,8 +209,6 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
delete[] npparams;
logfile << "invoke succeeded\n" << flush;
P3D_object *object = _instance->variant_to_p3dobj(&result);
browser->releasevariantvalue(&result);
return object;
@ -230,8 +222,6 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
////////////////////////////////////////////////////////////////////
P3D_object *PPBrowserObject::
eval(const string &expression) const {
logfile << "eval " << expression << "\n";
NPString npexpr;
npexpr.utf8characters = expression.c_str();
npexpr.utf8length = expression.length();
@ -240,12 +230,9 @@ eval(const string &expression) const {
if (!browser->evaluate(_instance->get_npp_instance(), _npobj,
&npexpr, &result)) {
// Failed to eval.
logfile << "eval failed\n" << flush;
return NULL;
}
logfile << "eval succeeded\n" << flush;
P3D_object *object = _instance->variant_to_p3dobj(&result);
browser->releasevariantvalue(&result);
return object;

View File

@ -23,6 +23,8 @@
#include <fstream>
#include <string.h> // strcmp()
PPInstance::FileDatas PPInstance::_file_datas;
////////////////////////////////////////////////////////////////////
// Function: PPInstance::Constructor
// Access: Public
@ -364,9 +366,7 @@ stream_as_file(NPStream *stream, const char *fname) {
char *name = tempnam(NULL, "p3d_");
// We prefer just making a hard link; it's quick and easy.
if (link(filename.c_str(), name) == 0) {
logfile << "linked " << filename << " to " << name << "\n";
} else {
if (link(filename.c_str(), name) != 0) {
// But sometimes the hard link might fail, particularly if these
// are two different file systems. In this case we have to open
// the files and copy the data by hand.
@ -383,7 +383,6 @@ stream_as_file(NPStream *stream, const char *fname) {
in.read(buffer, buffer_size);
count = in.gcount();
}
logfile << "copied " << filename << " to " << name << "\n";
}
filename = name;
@ -605,7 +604,6 @@ variant_to_p3dobj(const NPVariant *variant) {
// This is really a PPPandaObject.
PPPandaObject *ppobject = (PPPandaObject *)object;
P3D_object *obj = ppobject->get_p3d_object();
logfile << "Found nested Panda Object " << obj << "\n" << flush;
return obj;
}
@ -785,47 +783,12 @@ downloaded_file(PPDownloadRequest *req, const string &filename) {
// Function: PPInstance::feed_file
// Access: Private
// Description: Opens the named file (extracted from a file:// URL)
// and feeds its contents to the plugin.
// and feeds its contents to the core API.
////////////////////////////////////////////////////////////////////
void PPInstance::
feed_file(PPDownloadRequest *req, const string &filename) {
ifstream file(filename.c_str(), ios::in | ios::binary);
// First, seek to the end to get the file size.
file.seekg(0, ios::end);
size_t file_size = file.tellg();
// Then return to the beginning to read the data.
file.seekg(0, ios::beg);
static const size_t buffer_size = 4096;
char buffer[buffer_size];
file.read(buffer, buffer_size);
size_t count = file.gcount();
size_t total_count = 0;
while (count != 0) {
bool download_ok = P3D_instance_feed_url_stream
(_p3d_inst, req->_user_id, P3D_RC_in_progress,
0, file_size, (const unsigned char *)buffer, count);
if (!download_ok) {
// Never mind.
return;
}
file.read(buffer, buffer_size);
count = file.gcount();
total_count += count;
}
P3D_result_code result = P3D_RC_done;
if (file.fail() && !file.eof()) {
// Got an error while reading.
result = P3D_RC_generic_error;
}
P3D_instance_feed_url_stream
(_p3d_inst, req->_user_id, result, 0, total_count, NULL, 0);
StreamingFileData *file_data = new StreamingFileData(req, filename, _p3d_inst);
_file_datas.push_back(file_data);
}
////////////////////////////////////////////////////////////////////
@ -1025,10 +988,7 @@ send_window() {
y = 0;
#elif defined(__APPLE__)
logfile << "windowed plugin\n" << flush;
NP_Port *port = (NP_Port *)_window.window;
logfile << "portx, porty = " << port->portx << ", " << port->porty << "\n";
logfile << "x, y = " << _window.x << ", " << _window.y << "\n";
parent_window._port = port->port;
#elif defined(HAVE_X11)
@ -1051,10 +1011,7 @@ send_window() {
}
#elif defined(__APPLE__)
logfile << "windowless plugin\n" << flush;
NP_Port *port = (NP_Port *)_window.window;
logfile << "portx, porty = " << port->portx << ", " << port->porty << "\n";
logfile << "x, y = " << _window.x << ", " << _window.y << "\n";
parent_window._port = port->port;
#elif defined(HAVE_X11)
@ -1132,6 +1089,23 @@ handle_request_loop() {
}
p3d_inst = P3D_check_request(false);
}
// Also check to see if we have any file datas that need streaming.
// Only stream up to the front four in the queue, so we don't
// overwhelm the browser all at once.
size_t num_file_datas = min(_file_datas.size(), (size_t)4);
size_t i = 0;
while (i < num_file_datas) {
if (_file_datas[i]->feed_data()) {
// This one keeps going.
++i;
} else {
// This one is done.
delete _file_datas[i];
_file_datas.erase(_file_datas.begin() + i);
--num_file_datas;
}
}
}
////////////////////////////////////////////////////////////////////
@ -1144,14 +1118,13 @@ handle_request_loop() {
////////////////////////////////////////////////////////////////////
void PPInstance::
browser_sync_callback(void *) {
logfile << "browser_sync_callback\n";
handle_request_loop();
}
#ifdef _WIN32
////////////////////////////////////////////////////////////////////
// Function: window_proc
// Function: PPInstance::window_proc
// Access: Private, Static
// Description: We bind this function to the parent window we were
// given in set_window, so we can spin the request_loop
@ -1181,3 +1154,77 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
return DefWindowProc(hwnd, msg, wparam, lparam);
}
#endif // _WIN32
////////////////////////////////////////////////////////////////////
// Function: PPInstance::StreamingFileData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PPInstance::StreamingFileData::
StreamingFileData(PPDownloadRequest *req, const string &filename,
P3D_instance *p3d_inst) :
_p3d_inst(p3d_inst),
_user_id(req->_user_id),
_filename(filename),
_file(filename.c_str(), ios::in | ios::binary)
{
// First, seek to the end to get the file size.
_file.seekg(0, ios::end);
_file_size = _file.tellg();
_total_count = 0;
// Then return to the beginning to read the data.
_file.seekg(0, ios::beg);
}
////////////////////////////////////////////////////////////////////
// Function: PPInstance::StreamingFileData::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PPInstance::StreamingFileData::
~StreamingFileData() {
}
////////////////////////////////////////////////////////////////////
// Function: PPInstance::StreamingFileData::feed_data
// Access: Public
// Description: Feeds the next batch of the file to the instance.
// Returns true if there is more to come and this method
// should be called again, false if we're done.
////////////////////////////////////////////////////////////////////
bool PPInstance::StreamingFileData::
feed_data() {
static const size_t buffer_size = 81920;
char buffer[buffer_size];
_file.read(buffer, buffer_size);
size_t count = _file.gcount();
if (count != 0) {
_total_count += count;
bool download_ok = P3D_instance_feed_url_stream
(_p3d_inst, _user_id, P3D_RC_in_progress,
0, _file_size, (const unsigned char *)buffer, count);
if (!download_ok) {
// Never mind.
return false;
}
// So far, so good.
return true;
}
// End of file.
P3D_result_code result = P3D_RC_done;
if (_file.fail() && !_file.eof()) {
// Got an error while reading.
result = P3D_RC_generic_error;
}
P3D_instance_feed_url_stream
(_p3d_inst, _user_id, result, 0, _total_count, NULL, 0);
// We're done.
return false;
}

View File

@ -98,6 +98,28 @@ private:
bool _got_instance_data;
string _p3d_filename;
// This class is used for feeding local files (accessed via a
// "file://" url) into the core API.
class StreamingFileData {
public:
StreamingFileData(PPDownloadRequest *req, const string &filename,
P3D_instance *p3d_inst);
~StreamingFileData();
bool feed_data();
private:
P3D_instance *_p3d_inst;
int _user_id;
string _filename;
ifstream _file;
size_t _file_size;
size_t _total_count;
};
typedef vector<StreamingFileData *> FileDatas;
static FileDatas _file_datas;
bool _got_window;
NPWindow _window;
#ifdef _WIN32

View File

@ -75,7 +75,6 @@ set_p3d_object(P3D_object *p3d_object) {
////////////////////////////////////////////////////////////////////
void PPPandaObject::
construct(PPInstance *inst, P3D_object *p3d_object) {
logfile << "construct: " << this << "\n" << flush;
_instance = inst;
_p3d_object = NULL;
set_p3d_object(p3d_object);
@ -88,7 +87,6 @@ construct(PPInstance *inst, P3D_object *p3d_object) {
////////////////////////////////////////////////////////////////////
void PPPandaObject::
invalidate() {
logfile << "invalidate: " << this << "\n" << flush;
_instance = NULL;
set_p3d_object(NULL);
}
@ -102,7 +100,6 @@ invalidate() {
bool PPPandaObject::
has_method(NPIdentifier name) {
string method_name = identifier_to_string(name);
logfile << "has_method: " << this << ", " << method_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -134,7 +131,6 @@ bool PPPandaObject::
invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount,
NPVariant *result) {
string method_name = identifier_to_string(name);
logfile << "invoke: " << this << ", " << method_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -174,7 +170,6 @@ invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount,
bool PPPandaObject::
invoke_default(const NPVariant *args, uint32_t argCount,
NPVariant *result) {
logfile << "invoke_default: " << this << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -213,7 +208,6 @@ invoke_default(const NPVariant *args, uint32_t argCount,
bool PPPandaObject::
has_property(NPIdentifier name) {
string property_name = identifier_to_string(name);
logfile << "has_property: " << this << ", " << property_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -242,7 +236,6 @@ has_property(NPIdentifier name) {
bool PPPandaObject::
get_property(NPIdentifier name, NPVariant *result) {
string property_name = identifier_to_string(name);
logfile << "get_property: " << this << ", " << property_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -251,7 +244,6 @@ get_property(NPIdentifier name, NPVariant *result) {
P3D_object *value = P3D_OBJECT_GET_PROPERTY(_p3d_object, property_name.c_str());
if (value == NULL) {
// No such property.
logfile << " no such property\n" << flush;
return false;
}
@ -270,7 +262,6 @@ get_property(NPIdentifier name, NPVariant *result) {
bool PPPandaObject::
set_property(NPIdentifier name, const NPVariant *value) {
string property_name = identifier_to_string(name);
logfile << "set_property: " << this << ", " << property_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -291,7 +282,6 @@ set_property(NPIdentifier name, const NPVariant *value) {
bool PPPandaObject::
remove_property(NPIdentifier name) {
string property_name = identifier_to_string(name);
logfile << "remove_property: " << this << ", " << property_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
@ -309,7 +299,6 @@ remove_property(NPIdentifier name) {
////////////////////////////////////////////////////////////////////
bool PPPandaObject::
enumerate(NPIdentifier **value, uint32_t *count) {
logfile << "enumerate: " << this << "\n" << flush;
// TODO: Not implemented yet.
// Note that the array of values must be allocated here with
@ -362,7 +351,6 @@ identifier_to_string(NPIdentifier ident) {
////////////////////////////////////////////////////////////////////
NPObject *PPPandaObject::
NPAllocate(NPP npp, NPClass *aClass) {
logfile << "NPAllocate\n";
assert(aClass == &_object_class);
return (PPPandaObject *)malloc(sizeof(PPPandaObject));
}
@ -375,7 +363,6 @@ NPAllocate(NPP npp, NPClass *aClass) {
////////////////////////////////////////////////////////////////////
void PPPandaObject::
NPDeallocate(NPObject *npobj) {
logfile << "NPDeallocate: " << npobj << "\n" << flush;
((PPPandaObject *)npobj)->invalidate();
free(npobj);
}
@ -387,8 +374,6 @@ NPDeallocate(NPObject *npobj) {
////////////////////////////////////////////////////////////////////
void PPPandaObject::
NPInvalidate(NPObject *npobj) {
logfile << "NPInvalidate: " << npobj << "\n" << flush;
// It turns out that this method isn't actually called by Safari's
// implementation of NPAPI, so we'll move the actual destructor call
// into NPDeallocate, above.