Commit c786ff05 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Implement Cycle Collection for XMLHttpRequest.

parent 6a16a72d
......@@ -1994,28 +1994,6 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
return TRUE;
}
BOOL dispex_query_interface_no_cc(DispatchEx *This, REFIID riid, void **ppv)
{
if(IsEqualGUID(&IID_IDispatch, riid))
*ppv = &This->IDispatchEx_iface;
else if(IsEqualGUID(&IID_IDispatchEx, riid))
*ppv = &This->IDispatchEx_iface;
else if(IsEqualGUID(&IID_IDispatchJS, riid))
*ppv = NULL;
else if(IsEqualGUID(&IID_UndocumentedScriptIface, riid))
*ppv = NULL;
else if(IsEqualGUID(&IID_IMarshal, riid))
*ppv = NULL;
else if(IsEqualGUID(&IID_IManagedObject, riid))
*ppv = NULL;
else
return FALSE;
if(*ppv)
IUnknown_AddRef((IUnknown*)*ppv);
return TRUE;
}
LONG dispex_ref_decr(DispatchEx *dispex)
{
LONG ref = ccref_decr(&dispex->ccref, (nsISupports*)&dispex->IDispatchEx_iface, &dispex_ccp);
......@@ -2104,26 +2082,6 @@ static nsresult NSAPI dispex_unlink(void *p)
static void NSAPI dispex_delete_cycle_collectable(void *p)
{
DispatchEx *This = impl_from_IDispatchEx(p);
release_dispex(This);
}
void init_dispex_cc(void)
{
static const CCObjCallback dispex_ccp_callback = {
dispex_traverse,
dispex_unlink,
dispex_delete_cycle_collectable
};
ccp_init(&dispex_ccp, &dispex_ccp_callback);
}
const void *dispex_get_vtbl(DispatchEx *dispex)
{
return dispex->info->desc->vtbl;
}
void release_dispex(DispatchEx *This)
{
dynamic_prop_t *prop;
if(This->info->desc->vtbl->unlink)
......@@ -2159,6 +2117,21 @@ destructor:
This->info->desc->vtbl->destructor(This);
}
void init_dispex_cc(void)
{
static const CCObjCallback dispex_ccp_callback = {
dispex_traverse,
dispex_unlink,
dispex_delete_cycle_collectable
};
ccp_init(&dispex_ccp, &dispex_ccp_callback);
}
const void *dispex_get_vtbl(DispatchEx *dispex)
{
return dispex->info->desc->vtbl;
}
void init_dispatch(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data, compat_mode_t compat_mode)
{
assert(compat_mode < COMPAT_MODE_CNT);
......
......@@ -4560,27 +4560,6 @@ HRESULT EventTarget_QI(EventTarget *event_target, REFIID riid, void **ppv)
return E_NOINTERFACE;
}
HRESULT EventTarget_QI_no_cc(EventTarget *event_target, REFIID riid, void **ppv)
{
if(IsEqualGUID(riid, &IID_IEventTarget)) {
if(use_event_quirks(event_target)) {
WARN("IEventTarget queried, but not supported by in document mode\n");
*ppv = NULL;
return E_NOINTERFACE;
}
IEventTarget_AddRef(&event_target->IEventTarget_iface);
*ppv = &event_target->IEventTarget_iface;
return S_OK;
}
if(dispex_query_interface_no_cc(&event_target->dispex, riid, ppv))
return *ppv ? S_OK : E_NOINTERFACE;
WARN("(%p)->(%s %p)\n", event_target, debugstr_mshtml_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
void EventTarget_init_dispex_info(dispex_data_t *dispex_info, compat_mode_t compat_mode)
{
static const dispex_hook_t IEventTarget_hooks[] = {
......
......@@ -437,9 +437,7 @@ static inline LONG dispex_ref_incr(DispatchEx *dispex)
extern LONG dispex_ref_decr(DispatchEx*);
void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t);
void release_dispex(DispatchEx*);
BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
BOOL dispex_query_interface_no_cc(DispatchEx*,REFIID,void**);
void dispex_props_unlink(DispatchEx*);
HRESULT change_type(VARIANT*,VARIANT*,VARTYPE,IServiceProvider*);
HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
......@@ -1209,7 +1207,6 @@ void HTMLElement_Init(HTMLElement*,HTMLDocumentNode*,nsIDOMElement*,dispex_stati
void EventTarget_Init(EventTarget*,IUnknown*,dispex_static_data_t*,compat_mode_t);
HRESULT EventTarget_QI(EventTarget*,REFIID,void**);
HRESULT EventTarget_QI_no_cc(EventTarget*,REFIID,void**);
void EventTarget_init_dispex_info(dispex_data_t*,compat_mode_t);
HRESULT HTMLDOMNode_QI(HTMLDOMNode*,REFIID,void**);
......
......@@ -136,7 +136,6 @@ struct HTMLXMLHttpRequest {
IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface;
IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface;
IProvideClassInfo2 IProvideClassInfo2_iface;
LONG ref;
LONG task_magic;
LONG ready_state;
response_type_t response_type;
......@@ -526,7 +525,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *ifa
}else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
*ppv = &This->IProvideClassInfo2_iface;
}else {
return EventTarget_QI_no_cc(&This->event_target, riid, ppv);
return EventTarget_QI(&This->event_target, riid, ppv);
}
IUnknown_AddRef((IUnknown*)*ppv);
......@@ -536,7 +535,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *ifa
static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
{
HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
LONG ref = InterlockedIncrement(&This->ref);
LONG ref = dispex_ref_incr(&This->event_target.dispex);
TRACE("(%p) ref=%ld\n", This, ref);
......@@ -546,13 +545,10 @@ static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
{
HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
LONG ref = InterlockedDecrement(&This->ref);
LONG ref = dispex_ref_decr(&This->event_target.dispex);
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref)
release_dispex(&This->event_target.dispex);
return ref;
}
......@@ -1521,10 +1517,20 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
}
static void HTMLXMLHttpRequest_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
if(This->window)
note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb);
if(This->pending_progress_event)
note_cc_edge((nsISupports*)&This->pending_progress_event->IDOMEvent_iface, "pending_progress_event", cb);
if(This->nsxhr)
note_cc_edge((nsISupports*)This->nsxhr, "nsxhr", cb);
}
static void HTMLXMLHttpRequest_unlink(DispatchEx *dispex)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
remove_target_tasks(This->task_magic);
if(This->event_listener) {
XMLHttpReqEventListener *event_listener = This->event_listener;
This->event_listener = NULL;
......@@ -1550,6 +1556,12 @@ static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex)
free(This);
}
static void HTMLXMLHttpRequest_last_release(DispatchEx *dispex)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
remove_target_tasks(This->task_magic);
}
static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
......@@ -1595,7 +1607,9 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode
static const event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = {
{
.destructor = HTMLXMLHttpRequest_destructor,
.unlink = HTMLXMLHttpRequest_unlink
.traverse = HTMLXMLHttpRequest_traverse,
.unlink = HTMLXMLHttpRequest_unlink,
.last_release = HTMLXMLHttpRequest_last_release
},
.get_gecko_target = HTMLXMLHttpRequest_get_gecko_target,
.bind_event = HTMLXMLHttpRequest_bind_event
......@@ -1736,7 +1750,6 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl;
EventTarget_Init(&ret->event_target, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
&HTMLXMLHttpRequest_dispex, This->window->doc->document_mode);
ret->ref = 1;
/* Always register the handlers because we need them to track state */
event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment