Skip to content

Commit

Permalink
Added another hack to avoid message loop reentry during COM object de…
Browse files Browse the repository at this point in the history
…struction
  • Loading branch information
TheQwertiest committed Sep 10, 2021
1 parent bf9d614 commit 54f2dcf
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 4 deletions.
50 changes: 46 additions & 4 deletions foo_spider_monkey_panel/com_objects/drop_target_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "drop_target_impl.h"

#include <utils/logging.h>

#include <qwr/winapi_error_helpers.h>

_COM_SMARTPTR_TYPEDEF( IDropTargetHelper, IID_IDropTargetHelper );
Expand Down Expand Up @@ -63,7 +65,17 @@ STDMETHODIMP IDropTargetImpl::DragEnter( IDataObject* pDataObj, DWORD grfKeyStat
}

POINT point{ pt.x, pt.y };
GetDropTargetHelper()->DragEnter( hWnd_, pDataObj, &point, *pdwEffect );
try
{
GetDropTargetHelper()->DragEnter( hWnd_, pDataObj, &point, *pdwEffect );
}
catch ( const qwr::QwrException& e )
{
smp::utils::LogWarning( fmt::format( "DnD initialization failed:\n"
" {}",
e.what() ) );
return E_FAIL;
}

*pdwEffect = OnDragEnter( pDataObj, grfKeyState, pt, *pdwEffect );

Expand All @@ -78,7 +90,17 @@ STDMETHODIMP IDropTargetImpl::DragOver( DWORD grfKeyState, POINTL pt, DWORD* pdw
}

POINT point{ pt.x, pt.y };
GetDropTargetHelper()->DragOver( &point, *pdwEffect );
try
{
GetDropTargetHelper()->DragOver( &point, *pdwEffect );
}
catch ( const qwr::QwrException& e )
{
smp::utils::LogWarning( fmt::format( "DnD initialization failed:\n"
" {}",
e.what() ) );
return E_FAIL;
}

*pdwEffect = OnDragOver( grfKeyState, pt, *pdwEffect );

Expand All @@ -87,7 +109,17 @@ STDMETHODIMP IDropTargetImpl::DragOver( DWORD grfKeyState, POINTL pt, DWORD* pdw

STDMETHODIMP IDropTargetImpl::DragLeave()
{
GetDropTargetHelper()->DragLeave();
try
{
GetDropTargetHelper()->DragLeave();
}
catch ( const qwr::QwrException& e )
{
smp::utils::LogWarning( fmt::format( "DnD initialization failed:\n"
" {}",
e.what() ) );
return E_FAIL;
}

OnDragLeave();

Expand All @@ -106,7 +138,17 @@ STDMETHODIMP IDropTargetImpl::Drop( IDataObject* pDataObj, DWORD grfKeyState, PO
}

POINT point{ pt.x, pt.y };
GetDropTargetHelper()->Drop( pDataObj, &point, *pdwEffect );
try
{
GetDropTargetHelper()->Drop( pDataObj, &point, *pdwEffect );
}
catch ( const qwr::QwrException& e )
{
smp::utils::LogWarning( fmt::format( "DnD initialization failed:\n"
" {}",
e.what() ) );
return E_FAIL;
}

*pdwEffect = OnDrop( pDataObj, grfKeyState, pt, *pdwEffect );

Expand Down
27 changes: 27 additions & 0 deletions foo_spider_monkey_panel/events/event_drag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,32 @@

#include "event_drag.h"

#include <com_utils/com_destruction_handler.h>
#include <js_engine/js_container.h>
#include <panel/js_panel_window.h>

// TODO: store IDataObjectPtr in some panel object instead

namespace smp
{

Event_Drag::Event_Drag( EventId id, int32_t x, int32_t y, uint32_t mask, uint32_t modifiers, const panel::DragActionParams& dragParams, IDataObjectPtr pData )
: Event_Mouse( id, x, y, mask, modifiers )
, dragParams_( dragParams )
, pDataObject_( pData )
, pStorage_( com::GetNewStoredObject() )
{
assert( core_api::is_main_thread() );
assert( pDataObject_ );
assert( pStorage_ );

pDataObject_->AddRef();
pStorage_->pUnknown = pDataObject_;
}

Event_Drag::~Event_Drag()
{
assert( !pDataObject_ || core_api::is_main_thread() );
}

Event_Drag* Event_Drag::AsDragEvent()
Expand All @@ -33,7 +48,19 @@ const panel::DragActionParams& Event_Drag::GetDragParams() const

IDataObjectPtr Event_Drag::GetStoredData() const
{
assert( pDataObject_ );
return pDataObject_;
}

void Event_Drag::DisposeStoredData()
{
assert( core_api::is_main_thread() );
if ( pStorage_ )
{
pDataObject_ = nullptr;
com::MarkStoredObjectAsToBeDeleted( pStorage_ );
pStorage_ = nullptr;
}
}

} // namespace smp
13 changes: 13 additions & 0 deletions foo_spider_monkey_panel/events/event_drag.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ class JsContainer;

} // namespace mozjs

namespace smp::com
{

struct StorageObject;

}

namespace smp
{

Expand All @@ -20,7 +27,9 @@ class Event_Drag
: public Event_Mouse
{
public:
/// @remark Should be called only from the main thread
Event_Drag( EventId id, int32_t x, int32_t y, uint32_t mask, uint32_t modifiers, const panel::DragActionParams& dragParams, IDataObjectPtr pData );
~Event_Drag() override;

[[nodiscard]] Event_Drag* AsDragEvent() override;

Expand All @@ -29,9 +38,13 @@ class Event_Drag
[[nodiscard]] const panel::DragActionParams& GetDragParams() const;
[[nodiscard]] IDataObjectPtr GetStoredData() const;

/// @remark Should be called only from the main thread
void DisposeStoredData();

private:
const panel::DragActionParams dragParams_;
IDataObjectPtr pDataObject_;
com::StorageObject* pStorage_;
};

} // namespace smp
10 changes: 10 additions & 0 deletions foo_spider_monkey_panel/panel/js_panel_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,17 @@ void js_panel_window::ExecuteJsTask( EventId id, Event_JsExecutor& task )
}
}

pDragEvent->DisposeStoredData();

break;
}
case EventId::kMouseDragLeave:
{
const auto pDragEvent = task.AsDragEvent();
assert( pDragEvent );

lastDragParams_.reset();
pDragEvent->DisposeStoredData();

if ( pJsContainer_ )
{
Expand All @@ -458,6 +464,8 @@ void js_panel_window::ExecuteJsTask( EventId id, Event_JsExecutor& task )
}
}

pDragEvent->DisposeStoredData();

break;
}
case EventId::kMouseDragDrop:
Expand All @@ -477,7 +485,9 @@ void js_panel_window::ExecuteJsTask( EventId id, Event_JsExecutor& task )
smp::com::TrackDropTarget::ProcessDropEvent( pDragEvent->GetStoredData(), dragParams );
}
}

lastDragParams_.reset();
pDragEvent->DisposeStoredData();

break;
}
Expand Down

0 comments on commit 54f2dcf

Please sign in to comment.