a few race conditions

This commit is contained in:
David Rose 2009-07-28 20:17:14 +00:00
parent bf179efd76
commit 6b908cb525
5 changed files with 133 additions and 43 deletions

View File

@ -208,6 +208,24 @@ finish_instance(P3DInstance *inst) {
unref_delete(inst);
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstanceManager::validate_instance
// Access: Public
// Description: Returns the P3DInstance pointer corresponding to the
// indicated P3D_instance if it is valid, or NULL if it
// is not.
////////////////////////////////////////////////////////////////////
P3DInstance *P3DInstanceManager::
validate_instance(P3D_instance *instance) {
Instances::iterator ii;
ii = _instances.find((P3DInstance *)instance);
if (ii != _instances.end()) {
return (*ii);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstanceManager::check_request
// Access: Public

View File

@ -52,6 +52,8 @@ public:
const P3D_token tokens[], size_t num_tokens);
void finish_instance(P3DInstance *inst);
P3DInstance *validate_instance(P3D_instance *instance);
P3DInstance *check_request();
void wait_request();

View File

@ -41,8 +41,6 @@ P3DWinSplashWindow(P3DInstance *inst) :
_install_progress = 0.0;
INIT_LOCK(_install_lock);
start_thread();
}
////////////////////////////////////////////////////////////////////
@ -57,6 +55,22 @@ P3DWinSplashWindow::
DESTROY_LOCK(_install_lock);
}
////////////////////////////////////////////////////////////////////
// Function: P3DWinSplashWindow::set_wparams
// Access: Public, Virtual
// Description: Changes the window parameters, e.g. to resize or
// reposition the window; or sets the parameters for the
// first time, creating the initial window.
////////////////////////////////////////////////////////////////////
void P3DWinSplashWindow::
set_wparams(const P3DWindowParams &wparams) {
P3DSplashWindow::set_wparams(wparams);
if (_thread_id == 0) {
start_thread();
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DWinSplashWindow::set_image_filename
// Access: Public, Virtual
@ -76,13 +90,15 @@ set_image_filename(const string &image_filename,
}
RELEASE_LOCK(_install_lock);
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
if (_thread_id != 0) {
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the
// instance, too.
_inst->request_stop();
if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the
// instance, too.
_inst->request_stop();
}
}
}
@ -101,13 +117,15 @@ set_install_label(const string &install_label) {
}
RELEASE_LOCK(_install_lock);
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
if (_thread_id != 0) {
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the
// instance, too.
_inst->request_stop();
if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the
// instance, too.
_inst->request_stop();
}
}
}
@ -124,13 +142,15 @@ set_install_progress(double install_progress) {
_install_progress = install_progress;
RELEASE_LOCK(_install_lock);
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
if (_thread_id != 0) {
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the
// instance, too.
_inst->request_stop();
if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the
// instance, too.
_inst->request_stop();
}
}
}
@ -198,19 +218,24 @@ start_thread() {
void P3DWinSplashWindow::
stop_thread() {
_thread_continue = false;
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
// We can't actually wait for the thread to finish, since there
// might be a deadlock there: the thread can't finish deleting its
// window unless we're pumping the message loop for the parent,
// which won't happen if we're sitting here waiting. No worries; we
// don't *really* need to wait for the thread.
if (_thread_id != 0) {
// Post a silly message to spin the message loop.
PostThreadMessage(_thread_id, WM_USER, 0, 0);
}
// WaitForSingleObject(_thread, INFINITE);
if (_thread != NULL){
// We can't actually wait for the thread to finish, since there
// might be a deadlock there: the thread can't finish deleting its
// window unless we're pumping the message loop for the parent,
// which won't happen if we're sitting here waiting. No worries;
// we don't *really* need to wait for the thread.
// WaitForSingleObject(_thread, INFINITE);
CloseHandle(_thread);
_thread = NULL;
CloseHandle(_thread);
_thread = NULL;
}
}
////////////////////////////////////////////////////////////////////

View File

@ -34,6 +34,7 @@ public:
P3DWinSplashWindow(P3DInstance *inst);
virtual ~P3DWinSplashWindow();
virtual void set_wparams(const P3DWindowParams &wparams);
virtual void set_image_filename(const string &image_filename,
bool image_filename_temp);
virtual void set_install_label(const string &install_label);

View File

@ -91,8 +91,11 @@ P3D_instance_start(P3D_instance *instance, const char *p3d_filename,
}
ACQUIRE_LOCK(_api_lock);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
bool result = inst_mgr->start_instance
((P3DInstance *)instance, p3d_filename, tokens, num_tokens);
P3DInstance *inst = inst_mgr->validate_instance(instance);
bool result = false;
if (inst != NULL) {
result = inst_mgr->start_instance(inst, p3d_filename, tokens, num_tokens);
}
RELEASE_LOCK(_api_lock);
return result;
}
@ -102,7 +105,10 @@ P3D_instance_finish(P3D_instance *instance) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
inst_mgr->finish_instance((P3DInstance *)instance);
P3DInstance *inst = inst_mgr->validate_instance(instance);
if (inst != NULL) {
inst_mgr->finish_instance(inst);
}
RELEASE_LOCK(_api_lock);
}
@ -117,7 +123,11 @@ P3D_instance_setup_window(P3D_instance *instance,
win_width, win_height, parent_window);
ACQUIRE_LOCK(_api_lock);
((P3DInstance *)instance)->set_wparams(wparams);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(instance);
if (inst != NULL) {
inst->set_wparams(wparams);
}
RELEASE_LOCK(_api_lock);
}
@ -331,7 +341,12 @@ P3D_instance_get_panda_script_object(P3D_instance *instance) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_object *result = ((P3DInstance *)instance)->get_panda_script_object();
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(instance);
P3D_object *result = NULL;
if (inst != NULL) {
result = inst->get_panda_script_object();
}
RELEASE_LOCK(_api_lock);
return result;
@ -343,7 +358,11 @@ P3D_instance_set_browser_script_object(P3D_instance *instance,
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
((P3DInstance *)instance)->set_browser_script_object(object);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(instance);
if (inst != NULL) {
inst->set_browser_script_object(object);
}
RELEASE_LOCK(_api_lock);
}
@ -353,7 +372,14 @@ P3D_request *
P3D_instance_get_request(P3D_instance *instance) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_request *result = ((P3DInstance *)instance)->get_request();
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(instance);
P3D_request *result = NULL;
if (inst != NULL) {
result = inst->get_request();
}
RELEASE_LOCK(_api_lock);
return result;
}
@ -387,7 +413,11 @@ P3D_request_finish(P3D_request *request, bool handled) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
if (request != (P3D_request *)NULL) {
((P3DInstance *)request->_instance)->finish_request(request, handled);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(request->_instance);
if (inst != NULL) {
inst->finish_request(request, handled);
}
}
RELEASE_LOCK(_api_lock);
}
@ -401,10 +431,17 @@ P3D_instance_feed_url_stream(P3D_instance *instance, int unique_id,
size_t this_data_size) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
bool result = ((P3DInstance *)instance)->
feed_url_stream(unique_id, result_code, http_status_code,
total_expected_data,
(const unsigned char *)this_data, this_data_size);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(instance);
bool result = false;
if (inst != NULL) {
result = inst->
feed_url_stream(unique_id, result_code, http_status_code,
total_expected_data,
(const unsigned char *)this_data, this_data_size);
}
RELEASE_LOCK(_api_lock);
return result;
}
@ -413,7 +450,14 @@ bool
P3D_instance_handle_event(P3D_instance *instance, P3D_event_data event) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
bool result = ((P3DInstance *)instance)->handle_event(event);
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DInstance *inst = inst_mgr->validate_instance(instance);
bool result = false;
if (inst != NULL) {
result = inst->handle_event(event);
}
RELEASE_LOCK(_api_lock);
return result;
}