mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
reload crashes
This commit is contained in:
parent
52b1a2af67
commit
93726b88c1
@ -23,6 +23,28 @@ get_url() const {
|
||||
return _url;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::set_instance
|
||||
// Access: Public
|
||||
// Description: Specifies the particular P3DInstance that is
|
||||
// responsible for downloading this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void P3DDownload::
|
||||
set_instance(P3DInstance *instance) {
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::get_instance
|
||||
// Access: Public
|
||||
// Description: Returns the particular P3DInstance that is
|
||||
// responsible for downloading this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline P3DInstance *P3DDownload::
|
||||
get_instance() const {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::get_download_progress
|
||||
// Access: Public
|
||||
|
@ -30,6 +30,7 @@ P3DDownload() {
|
||||
|
||||
_canceled = false;
|
||||
_download_id = 0;
|
||||
_instance = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -50,6 +51,7 @@ P3DDownload(const P3DDownload ©) :
|
||||
|
||||
_canceled = false;
|
||||
_download_id = 0;
|
||||
_instance = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "p3d_plugin_common.h"
|
||||
#include "p3dReferenceCount.h"
|
||||
class P3DInstance;
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@ -37,6 +38,9 @@ public:
|
||||
void set_url(const string &url);
|
||||
inline const string &get_url() const;
|
||||
|
||||
inline void set_instance(P3DInstance *instance);
|
||||
inline P3DInstance *get_instance() const;
|
||||
|
||||
inline double get_download_progress() const;
|
||||
inline bool is_download_progress_known() const;
|
||||
inline bool get_download_finished() const;
|
||||
@ -78,6 +82,7 @@ private:
|
||||
bool _canceled;
|
||||
int _download_id;
|
||||
string _url;
|
||||
P3DInstance *_instance;
|
||||
};
|
||||
|
||||
#include "p3dDownload.I"
|
||||
|
@ -63,6 +63,12 @@ P3DHost::
|
||||
}
|
||||
}
|
||||
_packages.clear();
|
||||
|
||||
FailedPackages::iterator pi;
|
||||
for (pi = _failed_packages.begin(); pi != _failed_packages.end(); ++pi) {
|
||||
delete (*pi);
|
||||
}
|
||||
_failed_packages.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -285,13 +291,21 @@ get_package(const string &package_name, const string &package_version,
|
||||
string key = package_name + "_" + package_version;
|
||||
PackageMap::iterator pi = package_map.find(key);
|
||||
if (pi != package_map.end()) {
|
||||
return (*pi).second;
|
||||
P3DPackage *package = (*pi).second;
|
||||
if (!package->get_failed()) {
|
||||
return package;
|
||||
}
|
||||
|
||||
// If the package has previously failed, move it aside and try
|
||||
// again (maybe it just failed because the user interrupted it).
|
||||
nout << "Package " << key << " has previously failed; trying again.\n";
|
||||
_failed_packages.push_back(package);
|
||||
(*pi).second = NULL;
|
||||
}
|
||||
|
||||
P3DPackage *package =
|
||||
new P3DPackage(this, package_name, package_version, alt_host);
|
||||
bool inserted = package_map.insert(PackageMap::value_type(key, package)).second;
|
||||
assert(inserted);
|
||||
package_map[key] = package;
|
||||
|
||||
return package;
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ private:
|
||||
typedef map<string, P3DPackage *> PackageMap;
|
||||
typedef map<string, PackageMap> Packages;
|
||||
Packages _packages;
|
||||
typedef vector<P3DPackage *> FailedPackages;
|
||||
FailedPackages _failed_packages;
|
||||
|
||||
friend class P3DInstanceManager;
|
||||
};
|
||||
|
@ -269,6 +269,9 @@ P3DInstance::
|
||||
Downloads::iterator di;
|
||||
for (di = _downloads.begin(); di != _downloads.end(); ++di) {
|
||||
P3DDownload *download = (*di).second;
|
||||
if (download->get_instance() == this) {
|
||||
download->set_instance(NULL);
|
||||
}
|
||||
p3d_unref_delete(download);
|
||||
}
|
||||
_downloads.clear();
|
||||
@ -880,12 +883,16 @@ feed_url_stream(int unique_id,
|
||||
}
|
||||
|
||||
P3DDownload *download = (*di).second;
|
||||
assert(download->get_instance() == this);
|
||||
bool download_ok = download->feed_url_stream
|
||||
(result_code, http_status_code, total_expected_data,
|
||||
this_data, this_data_size);
|
||||
|
||||
if (!download_ok || download->get_download_finished()) {
|
||||
// All done.
|
||||
if (download->get_instance() == this) {
|
||||
download->set_instance(NULL);
|
||||
}
|
||||
_downloads.erase(di);
|
||||
p3d_unref_delete(download);
|
||||
}
|
||||
@ -1128,6 +1135,7 @@ start_download(P3DDownload *download, bool add_request) {
|
||||
|
||||
int download_id = inst_mgr->get_unique_id();
|
||||
download->set_download_id(download_id);
|
||||
download->set_instance(this);
|
||||
|
||||
download->ref();
|
||||
bool inserted = _downloads.insert(Downloads::value_type(download_id, download)).second;
|
||||
|
@ -129,8 +129,14 @@ P3DInstanceManager::
|
||||
sigaction(SIGPIPE, &_old_sigpipe, NULL);
|
||||
#endif // _WIN32
|
||||
|
||||
assert(_instances.empty());
|
||||
// force-finish any remaining instances.
|
||||
while (!_instances.empty()) {
|
||||
P3DInstance *inst = *(_instances.begin());
|
||||
finish_instance(inst);
|
||||
}
|
||||
|
||||
assert(_sessions.empty());
|
||||
assert(_instances.empty());
|
||||
|
||||
if (_auth_session != NULL) {
|
||||
p3d_unref_delete(_auth_session);
|
||||
@ -421,11 +427,12 @@ start_instance(P3DInstance *inst) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstanceManager::
|
||||
finish_instance(P3DInstance *inst) {
|
||||
nout << "finish_instance\n";
|
||||
nout << "finish_instance: " << inst << "\n";
|
||||
Instances::iterator ii;
|
||||
ii = _instances.find(inst);
|
||||
assert(ii != _instances.end());
|
||||
_instances.erase(ii);
|
||||
if (ii != _instances.end()) {
|
||||
_instances.erase(ii);
|
||||
}
|
||||
|
||||
Sessions::iterator si = _sessions.find(inst->get_session_key());
|
||||
if (si != _sessions.end()) {
|
||||
@ -442,9 +449,7 @@ finish_instance(P3DInstance *inst) {
|
||||
}
|
||||
|
||||
inst->cleanup();
|
||||
nout << "done cleanup, calling delete\n";
|
||||
p3d_unref_delete(inst);
|
||||
nout << "done finish_instance\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -1197,6 +1197,37 @@ is_extractable(FileSpec &file, const string &filename) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::instance_terminating
|
||||
// Access: Private
|
||||
// Description: Called when P3D_RC_shutdown is received by any
|
||||
// Download object, which indicates that the instance
|
||||
// owning this download object is terminating and we
|
||||
// should either find a new instance or abort the
|
||||
// download.
|
||||
//
|
||||
// The return value is true if a new instance is
|
||||
// available, or false if not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DPackage::
|
||||
instance_terminating(P3DInstance *instance) {
|
||||
if (_instances.empty() ||
|
||||
(_instances.size() == 1 && instance == _instances[0])) {
|
||||
// No other instances.
|
||||
return false;
|
||||
}
|
||||
|
||||
// There are more instances available to continue this download;
|
||||
// pick one of them. Move this one to the end of the list.
|
||||
Instances::iterator ii = find(_instances.begin(), _instances.end(), instance);
|
||||
if (ii != _instances.end()) {
|
||||
_instances.erase(ii);
|
||||
_instances.push_back(instance);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::Download::Constructor
|
||||
// Access: Public
|
||||
@ -1423,10 +1454,24 @@ do_step(bool download_finished) {
|
||||
if (_download->get_download_success()) {
|
||||
// The Download object has already validated the hash.
|
||||
return IT_step_complete;
|
||||
|
||||
} else if (_download->get_download_terminated()) {
|
||||
// The download was interrupted because we're shutting down.
|
||||
// Don't try any other plans.
|
||||
return IT_terminate;
|
||||
// The download was interrupted because its instance is shutting
|
||||
// down. Don't try any other plans, unless we have some more
|
||||
// instances.
|
||||
P3DInstance *instance = _download->get_instance();
|
||||
if (!_package->instance_terminating(instance)) {
|
||||
// That was the only instance referencing this package, so stop
|
||||
// the download.
|
||||
nout << "Terminating download of " << _urlbase << "\n";
|
||||
return IT_terminate;
|
||||
}
|
||||
nout << "Restarting download of " << _urlbase << " on new instance\n";
|
||||
|
||||
p3d_unref_delete(_download);
|
||||
_download = NULL;
|
||||
return IT_continue;
|
||||
|
||||
} else {
|
||||
// The Download object has already tried all of the mirrors, and
|
||||
// they all failed.
|
||||
|
@ -213,6 +213,7 @@ private:
|
||||
void set_saved_download(Download *download);
|
||||
|
||||
bool is_extractable(FileSpec &file, const string &filename) const;
|
||||
bool instance_terminating(P3DInstance *instance);
|
||||
|
||||
public:
|
||||
class RequiredPackage {
|
||||
|
@ -86,6 +86,7 @@ P3D_initialize(int api_version, const char *contents_filename,
|
||||
|
||||
void
|
||||
P3D_finalize() {
|
||||
nout << "P3D_finalize called\n";
|
||||
P3DInstanceManager::delete_global_ptr();
|
||||
}
|
||||
|
||||
|
@ -336,6 +336,7 @@ stop_outstanding_streams() {
|
||||
NPStream *stream = (*si);
|
||||
nout << "Stopping stream " << (void *)stream << "\n";
|
||||
browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK);
|
||||
destroy_stream(stream, NPRES_USER_BREAK);
|
||||
}
|
||||
|
||||
assert(_streams.empty());
|
||||
@ -450,9 +451,7 @@ write_stream(NPStream *stream, int offset, int len, void *buffer) {
|
||||
NPError PPInstance::
|
||||
destroy_stream(NPStream *stream, NPReason reason) {
|
||||
Streams::iterator si = find(_streams.begin(), _streams.end(), stream);
|
||||
if (si == _streams.end()) {
|
||||
nout << "Got destroy_stream for unknown stream\n";
|
||||
} else {
|
||||
if (si != _streams.end()) {
|
||||
_streams.erase(si);
|
||||
}
|
||||
|
||||
|
@ -418,10 +418,11 @@ NPP_SetWindow(NPP instance, NPWindow *window) {
|
||||
NPError
|
||||
NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream,
|
||||
NPBool seekable, uint16_t *stype) {
|
||||
nout << "NewStream " << type << ", " << stream->url
|
||||
<< ", " << stream->end
|
||||
nout << "NewStream " << type << ": " << (void *)stream
|
||||
<< ", " << stream->url << ", size = " << stream->end
|
||||
<< ", notifyData = " << stream->notifyData
|
||||
<< "\n";
|
||||
<< ", for " << instance
|
||||
<< ", " << (PPInstance *)(instance->pdata) << "\n";
|
||||
PPInstance::generic_browser_call();
|
||||
PPInstance *inst = (PPInstance *)(instance->pdata);
|
||||
assert(inst != NULL);
|
||||
@ -436,8 +437,7 @@ NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NPError
|
||||
NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) {
|
||||
nout << "DestroyStream " << stream->url
|
||||
<< ", " << stream->end
|
||||
nout << "DestroyStream: " << (void *)stream << ", " << stream->url
|
||||
<< ", notifyData = " << stream->notifyData
|
||||
<< ", reason = " << reason
|
||||
<< ", for " << instance
|
||||
|
Loading…
x
Reference in New Issue
Block a user