助田です。

いろいろありがとうございます。

OLEサーバーをReleaseしたタイミングでEVENTSINK_Invokeに通知が来るという
可能性をすっかり見落していました。

まだ、よく理解していないのですが...

arton wrote:
> コンセプトコードですが、こんな感じでしょうか?
> fole_free(VALUE self)
> {
>     struct oledata *pole;
>     rb_secure(4);
>     OLEData_Get_Struct(self, pole);
>    pole->freeing = TRUE;  // 新設
>     OLE_FREE(pole->pDispatch);
>     pole->pDispatch = NULL;
>     return Qnil;
> }

WIN32OLEオブジェクトが解放(OLE_FREE)中かどうかのflagを新設する。

> STDMETHODIMP EVENTSINK_Invoke(
>     PEVENTSINK pEventSink,
>    -- snip ---
>     UINT *puArgErr
>     ) {
>    -- snip ---
>     PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
>     pTypeInfo = pEV->pTypeInfo;
>     obj = evs_entry(pEV->m_event_id);
>     if (obj->freeing) {         --- 解放中なら無視
>         return NOERROR;
>     }
>     if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {
>         return NOERROR;
>     }

EVENTSINK_Invokeは自分がイベントを待っている相手の
WIN32OLEオブジェクト(OLEサーバ)が解放(OLE_FREE)中なら無視する。

あと、pole自体は、freeしないでfree対象キューに
別のタイミングでfreeしてメモリーリークしないようにする。

という解釈で合ってますか?

  助田 雅紀