fixed reinit race condition

This commit is contained in:
Arkady Trestman 2010-01-11 05:02:28 +00:00
parent 264c603608
commit eff462f13f
7 changed files with 51 additions and 23 deletions

View File

@ -197,6 +197,11 @@ void CP3DActiveXCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInv
DoSuperclassPaint(pdc, rcBounds); DoSuperclassPaint(pdc, rcBounds);
} }
void CP3DActiveXCtrl::OnClose( DWORD dwSaveOption )
{
m_instance.Stop();
COleControl::OnClose( dwSaveOption );
}
// CP3DActiveXCtrl::DoPropExchange - Persistence support // CP3DActiveXCtrl::DoPropExchange - Persistence support

View File

@ -36,6 +36,7 @@ public:
// Overrides // Overrides
public: public:
virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
virtual void OnClose( DWORD dwSaveOption );
virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void DoPropExchange(CPropExchange* pPX); virtual void DoPropExchange(CPropExchange* pPX);
virtual void OnResetState(); virtual void OnResetState();

View File

@ -23,6 +23,11 @@ PPDownloadCallback::PPDownloadCallback( PPDownloadCallbackSync& downloadSync )
{ {
} }
PPDownloadCallback::~PPDownloadCallback()
{
m_spStream.Release();
}
STDMETHODIMP PPDownloadCallback::QueryInterface(REFIID riid, void **ppvObject) STDMETHODIMP PPDownloadCallback::QueryInterface(REFIID riid, void **ppvObject)
{ {
TRACE(_T("IUnknown::QueryInterface\n")); 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(); m_spStream.Release();
} }

View File

@ -35,6 +35,7 @@ class PPDownloadCallback : public IBindStatusCallback
{ {
public: public:
PPDownloadCallback( PPDownloadCallbackSync& downloadSync ); PPDownloadCallback( PPDownloadCallbackSync& downloadSync );
virtual ~PPDownloadCallback();
// IUnknown methods // IUnknown methods
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);

View File

@ -19,6 +19,8 @@
bool PPDownloadRequest::Begin( ) bool PPDownloadRequest::Begin( )
{ {
m_instance.m_eventStop.ResetEvent( );
m_instance.m_eventDownloadStopped.ResetEvent( );
return true; return true;
} }
@ -94,5 +96,6 @@ bool PPDownloadRequest::End( )
::CloseHandle( m_hFile ); ::CloseHandle( m_hFile );
m_hFile = INVALID_HANDLE_VALUE; m_hFile = INVALID_HANDLE_VALUE;
} }
m_instance.m_eventDownloadStopped.SetEvent( );
return true; return true;
} }

View File

@ -49,7 +49,6 @@
#define P3D_DEFAULT_PLUGIN_FILENAME "p3d_plugin.dll" #define P3D_DEFAULT_PLUGIN_FILENAME "p3d_plugin.dll"
static int s_instanceCount = 0; static int s_instanceCount = 0;
void P3D_NotificationSync(P3D_instance *instance) void P3D_NotificationSync(P3D_instance *instance)
{ {
static bool handleRequestOnUIThread = true; static bool handleRequestOnUIThread = true;
@ -89,30 +88,19 @@ PPInstance::PPInstance( CP3DActiveXCtrl& parentCtrl ) :
PPInstance::~PPInstance( ) 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 PPInstance::DownloadFile( const std::string& from, const std::string& to )
{ {
int error( 0 ); int error( 0 );
PPDownloadRequest p3dFileDownloadRequest( *this, to ); HRESULT hr( S_OK );
PPDownloadCallback dcForFile( p3dFileDownloadRequest );
nout << "Downloading " << from << " into " << to << "\n"; 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 ) ) if ( FAILED( hr ) )
{ {
error = 1; error = 1;
@ -568,6 +556,27 @@ int PPInstance::Start( const std::string& p3dFilename )
return 0; 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( ) std::string PPInstance::GetHostUrl( )
{ {
CString hostingPageLocation = m_parentCtrl.m_hostingPageUrl.Left( m_parentCtrl.m_hostingPageUrl.ReverseFind( '/' ) );; CString hostingPageLocation = m_parentCtrl.m_hostingPageUrl.Left( m_parentCtrl.m_hostingPageUrl.ReverseFind( '/' ) );;
@ -614,6 +623,7 @@ void PPInstance::HandleRequestLoop()
void PPInstance::HandleRequestGetUrl( void* data ) void PPInstance::HandleRequestGetUrl( void* data )
{ {
HRESULT hr( S_OK );
P3D_request *request = static_cast<P3D_request*>( data ); P3D_request *request = static_cast<P3D_request*>( data );
if ( !request ) if ( !request )
{ {
@ -629,10 +639,11 @@ void PPInstance::HandleRequestGetUrl( void* data )
} }
nout << "Handling P3D_RT_get_url request from " << url << "\n"; nout << "Handling P3D_RT_get_url request from " << url << "\n";
{
PPDownloadRequest p3dObjectDownloadRequest( parent->m_instance, request ); PPDownloadRequest p3dObjectDownloadRequest( parent->m_instance, request );
PPDownloadCallback bsc( p3dObjectDownloadRequest ); PPDownloadCallback bsc( p3dObjectDownloadRequest );
HRESULT hr = ::URLOpenStream( parent->GetControllingUnknown(), url.c_str(), 0, &bsc ); hr = ::URLOpenStream( parent->GetControllingUnknown(), url.c_str(), 0, &bsc );
}
P3D_result_code result_code = P3D_RC_done; P3D_result_code result_code = P3D_RC_done;
if ( FAILED( hr ) ) if ( FAILED( hr ) )
{ {

View File

@ -46,6 +46,7 @@ public:
static void unref_plugin(); static void unref_plugin();
int Start( const std::string& p3dFileName ); int Start( const std::string& p3dFileName );
int Stop( );
std::string GetHostUrl( ); std::string GetHostUrl( );
std::string GetP3DFilename( ); std::string GetP3DFilename( );
@ -56,6 +57,7 @@ public:
HWND m_parentWnd; HWND m_parentWnd;
CEvent m_eventStop; CEvent m_eventStop;
CEvent m_eventDownloadStopped;
P3D_object* m_p3dObject; P3D_object* m_p3dObject;