From eff462f13f7df3610c8705f7c69600d5bf05f4ac Mon Sep 17 00:00:00 2001 From: Arkady Trestman Date: Mon, 11 Jan 2010 05:02:28 +0000 Subject: [PATCH] fixed reinit race condition --- direct/src/plugin_activex/P3DActiveXCtrl.cpp | 5 ++ direct/src/plugin_activex/P3DActiveXCtrl.h | 1 + .../src/plugin_activex/PPDownloadCallback.cpp | 7 ++- .../src/plugin_activex/PPDownloadCallback.h | 1 + .../src/plugin_activex/PPDownloadRequest.cpp | 3 + direct/src/plugin_activex/PPInstance.cpp | 55 +++++++++++-------- direct/src/plugin_activex/PPInstance.h | 2 + 7 files changed, 51 insertions(+), 23 deletions(-) diff --git a/direct/src/plugin_activex/P3DActiveXCtrl.cpp b/direct/src/plugin_activex/P3DActiveXCtrl.cpp index 35663565e2..ef26f749db 100644 --- a/direct/src/plugin_activex/P3DActiveXCtrl.cpp +++ b/direct/src/plugin_activex/P3DActiveXCtrl.cpp @@ -197,6 +197,11 @@ void CP3DActiveXCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInv DoSuperclassPaint(pdc, rcBounds); } +void CP3DActiveXCtrl::OnClose( DWORD dwSaveOption ) +{ + m_instance.Stop(); + COleControl::OnClose( dwSaveOption ); +} // CP3DActiveXCtrl::DoPropExchange - Persistence support diff --git a/direct/src/plugin_activex/P3DActiveXCtrl.h b/direct/src/plugin_activex/P3DActiveXCtrl.h index 412da1d91b..e97a9928a4 100644 --- a/direct/src/plugin_activex/P3DActiveXCtrl.h +++ b/direct/src/plugin_activex/P3DActiveXCtrl.h @@ -36,6 +36,7 @@ public: // Overrides public: virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); + virtual void OnClose( DWORD dwSaveOption ); virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual void DoPropExchange(CPropExchange* pPX); virtual void OnResetState(); diff --git a/direct/src/plugin_activex/PPDownloadCallback.cpp b/direct/src/plugin_activex/PPDownloadCallback.cpp index 8a2bcef6bc..d02bc643d3 100644 --- a/direct/src/plugin_activex/PPDownloadCallback.cpp +++ b/direct/src/plugin_activex/PPDownloadCallback.cpp @@ -23,6 +23,11 @@ PPDownloadCallback::PPDownloadCallback( PPDownloadCallbackSync& downloadSync ) { } +PPDownloadCallback::~PPDownloadCallback() +{ + m_spStream.Release(); +} + STDMETHODIMP PPDownloadCallback::QueryInterface(REFIID riid, void **ppvObject) { TRACE(_T("IUnknown::QueryInterface\n")); @@ -224,7 +229,7 @@ STDMETHODIMP PPDownloadCallback::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, } } - if (BSCF_LASTDATANOTIFICATION & grfBSCF) + if (BSCF_LASTDATANOTIFICATION & grfBSCF || E_ABORT == hr ) { m_spStream.Release(); } diff --git a/direct/src/plugin_activex/PPDownloadCallback.h b/direct/src/plugin_activex/PPDownloadCallback.h index 1f05b3c934..538d3f7e35 100644 --- a/direct/src/plugin_activex/PPDownloadCallback.h +++ b/direct/src/plugin_activex/PPDownloadCallback.h @@ -35,6 +35,7 @@ class PPDownloadCallback : public IBindStatusCallback { public: PPDownloadCallback( PPDownloadCallbackSync& downloadSync ); + virtual ~PPDownloadCallback(); // IUnknown methods STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); diff --git a/direct/src/plugin_activex/PPDownloadRequest.cpp b/direct/src/plugin_activex/PPDownloadRequest.cpp index 12fafe5751..3e53fce359 100644 --- a/direct/src/plugin_activex/PPDownloadRequest.cpp +++ b/direct/src/plugin_activex/PPDownloadRequest.cpp @@ -19,6 +19,8 @@ bool PPDownloadRequest::Begin( ) { + m_instance.m_eventStop.ResetEvent( ); + m_instance.m_eventDownloadStopped.ResetEvent( ); return true; } @@ -94,5 +96,6 @@ bool PPDownloadRequest::End( ) ::CloseHandle( m_hFile ); m_hFile = INVALID_HANDLE_VALUE; } + m_instance.m_eventDownloadStopped.SetEvent( ); return true; } diff --git a/direct/src/plugin_activex/PPInstance.cpp b/direct/src/plugin_activex/PPInstance.cpp index 843d7dd436..c41486bd8b 100644 --- a/direct/src/plugin_activex/PPInstance.cpp +++ b/direct/src/plugin_activex/PPInstance.cpp @@ -49,7 +49,6 @@ #define P3D_DEFAULT_PLUGIN_FILENAME "p3d_plugin.dll" static int s_instanceCount = 0; - void P3D_NotificationSync(P3D_instance *instance) { static bool handleRequestOnUIThread = true; @@ -89,30 +88,19 @@ PPInstance::PPInstance( CP3DActiveXCtrl& parentCtrl ) : PPInstance::~PPInstance( ) { - if ( m_p3dInstance ) - { - P3D_instance_finish_ptr( m_p3dInstance ); - m_p3dInstance = NULL; - } - if ( m_p3dObject ) - { - P3D_OBJECT_DECREF( m_p3dObject ); - m_p3dObject = NULL; - } - if ( m_pluginLoaded ) - { - UnloadPlugin(); - } } int PPInstance::DownloadFile( const std::string& from, const std::string& to ) { int error( 0 ); - PPDownloadRequest p3dFileDownloadRequest( *this, to ); - PPDownloadCallback dcForFile( p3dFileDownloadRequest ); + HRESULT hr( S_OK ); nout << "Downloading " << from << " into " << to << "\n"; - HRESULT hr = ::URLOpenStream( m_parentCtrl.GetControllingUnknown(), from.c_str(), 0, &dcForFile ); + { + PPDownloadRequest p3dFileDownloadRequest( *this, to ); + PPDownloadCallback dcForFile( p3dFileDownloadRequest ); + hr = ::URLOpenStream( m_parentCtrl.GetControllingUnknown(), from.c_str(), 0, &dcForFile ); + } if ( FAILED( hr ) ) { error = 1; @@ -568,6 +556,27 @@ int PPInstance::Start( const std::string& p3dFilename ) return 0; } +int PPInstance::Stop( ) +{ + m_eventStop.SetEvent( ); + ::WaitForSingleObject( m_eventDownloadStopped.m_hObject, INFINITE ); + if ( m_p3dInstance ) + { + P3D_instance_finish_ptr( m_p3dInstance ); + m_p3dInstance = NULL; + } + if ( m_p3dObject ) + { + P3D_OBJECT_DECREF( m_p3dObject ); + m_p3dObject = NULL; + } + if ( m_pluginLoaded ) + { + UnloadPlugin(); + } + return 0; +} + std::string PPInstance::GetHostUrl( ) { CString hostingPageLocation = m_parentCtrl.m_hostingPageUrl.Left( m_parentCtrl.m_hostingPageUrl.ReverseFind( '/' ) );; @@ -614,6 +623,7 @@ void PPInstance::HandleRequestLoop() void PPInstance::HandleRequestGetUrl( void* data ) { + HRESULT hr( S_OK ); P3D_request *request = static_cast( data ); if ( !request ) { @@ -629,10 +639,11 @@ void PPInstance::HandleRequestGetUrl( void* data ) } nout << "Handling P3D_RT_get_url request from " << url << "\n"; - PPDownloadRequest p3dObjectDownloadRequest( parent->m_instance, request ); - PPDownloadCallback bsc( p3dObjectDownloadRequest ); - HRESULT hr = ::URLOpenStream( parent->GetControllingUnknown(), url.c_str(), 0, &bsc ); - + { + PPDownloadRequest p3dObjectDownloadRequest( parent->m_instance, request ); + PPDownloadCallback bsc( p3dObjectDownloadRequest ); + hr = ::URLOpenStream( parent->GetControllingUnknown(), url.c_str(), 0, &bsc ); + } P3D_result_code result_code = P3D_RC_done; if ( FAILED( hr ) ) { diff --git a/direct/src/plugin_activex/PPInstance.h b/direct/src/plugin_activex/PPInstance.h index ccd825e231..c307ffd685 100644 --- a/direct/src/plugin_activex/PPInstance.h +++ b/direct/src/plugin_activex/PPInstance.h @@ -46,6 +46,7 @@ public: static void unref_plugin(); int Start( const std::string& p3dFileName ); + int Stop( ); std::string GetHostUrl( ); std::string GetP3DFilename( ); @@ -56,6 +57,7 @@ public: HWND m_parentWnd; CEvent m_eventStop; + CEvent m_eventDownloadStopped; P3D_object* m_p3dObject;