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

mshtml: Support cycle collection for nsChannel.

This is traversed from the Gecko document, and should be part of the graph (it refers to gecko objects that participate in it, and which are part of a cycle). Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com>
parent 917ec2db
......@@ -37,7 +37,7 @@ typedef struct {
nsIHttpChannelInternal nsIHttpChannelInternal_iface;
nsICacheInfoChannel nsICacheInfoChannel_iface;
LONG ref;
nsCycleCollectingAutoRefCnt ccref;
nsWineURI *uri;
nsIInputStream *post_data_stream;
......
......@@ -45,6 +45,7 @@ static const IID NS_IOSERVICE_CID =
static const IID IID_nsWineURI =
{0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};
static ExternalCycleCollectionParticipant nschannel_ccp;
static nsIIOService *nsio = NULL;
static const char *request_method_strings[] = {"GET", "PUT", "POST"};
......@@ -540,6 +541,14 @@ static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef r
}else if(IsEqualGUID(&IID_nsICacheInfoChannel, riid)) {
TRACE("(%p)->(IID_nsICacheInfoChannel %p)\n", This, result);
*result = is_http_channel(This) ? &This->nsICacheInfoChannel_iface : NULL;
}else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) {
TRACE("(%p)->(IID_nsXPCOMCycleCollectionParticipant %p)\n", This, result);
*result = &nschannel_ccp;
return S_OK;
}else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
TRACE("(%p)->(IID_nsCycleCollectionISupports %p)\n", This, result);
*result = &This->nsIHttpChannel_iface;
return S_OK;
}else {
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
*result = NULL;
......@@ -556,7 +565,7 @@ static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef r
static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
{
nsChannel *This = impl_from_nsIHttpChannel(iface);
nsrefcnt ref = InterlockedIncrement(&This->ref);
nsrefcnt ref = ccref_incr(&This->ccref, (nsISupports*)&This->nsIHttpChannel_iface);
TRACE("(%p) ref=%ld\n", This, ref);
......@@ -566,30 +575,9 @@ static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
{
nsChannel *This = impl_from_nsIHttpChannel(iface);
LONG ref = InterlockedDecrement(&This->ref);
nsrefcnt ref = ccref_decr(&This->ccref, (nsISupports*)&This->nsIHttpChannel_iface, &nschannel_ccp);
if(!ref) {
nsIFileURL_Release(&This->uri->nsIFileURL_iface);
if(This->owner)
nsISupports_Release(This->owner);
if(This->post_data_stream)
nsIInputStream_Release(This->post_data_stream);
if(This->load_group)
nsILoadGroup_Release(This->load_group);
if(This->notif_callback)
nsIInterfaceRequestor_Release(This->notif_callback);
if(This->original_uri)
nsIURI_Release(This->original_uri);
if(This->referrer)
nsIURI_Release(This->referrer);
free_http_headers(&This->response_headers);
free_http_headers(&This->request_headers);
free(This->content_type);
free(This->charset);
free(This);
}
TRACE("(%p) ref=%ld\n", This, ref);
return ref;
}
......@@ -2263,6 +2251,86 @@ static const nsICacheInfoChannelVtbl nsCacheInfoChannelVtbl = {
nsCacheInfoChannel_SetAllowStaleCacheContent
};
static nsresult NSAPI nsChannel_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb)
{
nsChannel *This = impl_from_nsIHttpChannel(p);
TRACE("%p\n", This);
describe_cc_node(&This->ccref, "nsChannel", cb);
if(This->owner)
note_cc_edge(This->owner, "owner", cb);
if(This->post_data_stream)
note_cc_edge((nsISupports*)This->post_data_stream, "post_data_stream", cb);
if(This->load_group)
note_cc_edge((nsISupports*)This->load_group, "load_group", cb);
if(This->notif_callback)
note_cc_edge((nsISupports*)This->notif_callback, "notif_callback", cb);
if(This->original_uri)
note_cc_edge((nsISupports*)This->original_uri, "original_uri", cb);
if(This->referrer)
note_cc_edge((nsISupports*)This->referrer, "referrer", cb);
return NS_OK;
}
static nsresult NSAPI nsChannel_unlink(void *p)
{
nsChannel *This = impl_from_nsIHttpChannel(p);
TRACE("%p\n", This);
if(This->owner) {
nsISupports *owner = This->owner;
This->owner = NULL;
nsISupports_Release(owner);
}
if(This->post_data_stream) {
nsIInputStream *post_data_stream = This->post_data_stream;
This->post_data_stream = NULL;
nsIInputStream_Release(post_data_stream);
}
if(This->load_group) {
nsILoadGroup *load_group = This->load_group;
This->load_group = NULL;
nsILoadGroup_Release(load_group);
}
if(This->notif_callback) {
nsIInterfaceRequestor *notif_callback = This->notif_callback;
This->notif_callback = NULL;
nsIInterfaceRequestor_Release(notif_callback);
}
if(This->original_uri) {
nsIURI *original_uri = This->original_uri;
This->original_uri = NULL;
nsIURI_Release(original_uri);
}
if(This->referrer) {
nsIURI *referrer = This->referrer;
This->referrer = NULL;
nsIURI_Release(referrer);
}
return NS_OK;
}
static void NSAPI nsChannel_delete_cycle_collectable(void *p)
{
nsChannel *This = impl_from_nsIHttpChannel(p);
nsChannel_unlink(p);
TRACE("(%p)\n", This);
nsIFileURL_Release(&This->uri->nsIFileURL_iface);
free_http_headers(&This->response_headers);
free_http_headers(&This->request_headers);
free(This->content_type);
free(This->charset);
free(This);
}
static void invalidate_uri(nsWineURI *This)
{
if(This->uri) {
......@@ -3517,10 +3585,10 @@ static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
channel->nsICacheInfoChannel_iface.lpVtbl = &nsCacheInfoChannelVtbl;
channel->ref = 1;
channel->request_method = METHOD_GET;
list_init(&channel->response_headers);
list_init(&channel->request_headers);
ccref_init(&channel->ccref, 1);
nsIFileURL_AddRef(&uri->nsIFileURL_iface);
channel->uri = uri;
......@@ -3990,6 +4058,11 @@ static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl };
void init_nsio(nsIComponentManager *component_manager)
{
static const CCObjCallback nschannel_ccp_callback = {
nsChannel_traverse,
nsChannel_unlink,
nsChannel_delete_cycle_collectable
};
nsIFactory *old_factory = NULL;
nsresult nsres;
......@@ -4009,6 +4082,8 @@ void init_nsio(nsIComponentManager *component_manager)
nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook);
assert(nsres == NS_OK);
ccp_init(&nschannel_ccp, &nschannel_ccp_callback);
}
void release_nsio(void)
......
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