On Mon Aug 28 12:10:34 2023 +0000, Jacek Caban wrote:
`ccref_is_0` is not great, esp. with modifications to each task handler that can't be easily moved out of them. Did you try porting `NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE` and do it the way cycle collector developers intended it to be used? This feels like the cleanest solution to me so far and it seems straightforward. On Wine side, dispex_ref_decr could probably look like:
cpp_bool should_delete; LONG ref = ccref_decr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface, &should_delete); if(!ref) { if(dispex->info->vtbl->last_release) { ccref_incr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface); dispex->info->vtbl->last_release(dispex); ccref_decr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface, NULL); } if(should_delete) { ccref_stabilize_for_deletion(&dispex->ccref); release_dispex(dispex); } }
Then, inside `last_release`, we could safely use This pointer without any hacks. Reading closer Gecko code, it seems that should_delete is only important during XPCOM shutdown (`NS_ShutdownXPCOM`). Since we never shutdown XPCOM properly (because it can't be re-initialized and we don't know if we will need it again), maybe we could even get away without it. I'm not sure, it would need a better look at Gecko code to be sure. (Still, we will probably want to handle it given how easy it is, but perhaps we can live without it for the first iteration).
I didn't look into that yet because I didn't want to rely on a solution that needs wine-gecko changes, since it can take a while and I wanted to get these in for now (even if they could be changed/improved later when wine-gecko is updated).
I'll see if I can do something about it now, but from the snippet you posted, it looks like we can assume the ccref never immediately destroys the object when it reaches 0?