mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-27 07:34:20 +00:00
Bug 1405286: Part 1 - Allow retrieving the delivery target from retargetable requests. r=dragana
After data delivery for a request has been retargeted, there's no reliable way to get the appropriate event target to re-dispatch data events after asynchronous processing. While it's technically possible to retrieve the current thread from OnDataAvailable callbacks and re-use that for later dispatch, that approach has some issues: 1) It's not currently possible to reliably map the current thread to the thread pool that owns it. That means that if data delivery is being targetted to a thread pool, attempts to redispatch events to the previous delivery thread might lead to long delays when one thread in a pool is blocked. 2) If a filter wishes to dispatch data events to the wrapped listeners before it's recieved any data (as extensions StreamFilters sometimes do), there's no way to determine the proper event target without waiting for initial data to be received. Simply returning the correct event target from the request solves both of these problems. MozReview-Commit-ID: CJxq7O4399R --HG-- extra : rebase_source : db2f659ecad16daafdbcc108d7b1a51ea1af31f9
This commit is contained in:
parent
05889a48b5
commit
635fc0e1ae
@ -1174,6 +1174,19 @@ nsJARChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget)
|
||||
return request->RetargetDeliveryTo(aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIThreadRetargetableRequest> request = do_QueryInterface(mRequest);
|
||||
if (!request) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
return request->GetDeliveryTarget(aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::CheckListenerChain()
|
||||
{
|
||||
|
@ -974,6 +974,20 @@ nsBaseChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget)
|
||||
return req->RetargetDeliveryTo(aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
NS_ENSURE_TRUE(mRequest, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<nsIThreadRetargetableRequest> req;
|
||||
req = do_QueryInterface(mRequest);
|
||||
|
||||
NS_ENSURE_TRUE(req, NS_ERROR_NOT_IMPLEMENTED);
|
||||
return req->GetDeliveryTarget(aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseChannel::CheckListenerChain()
|
||||
{
|
||||
|
@ -32,4 +32,12 @@ interface nsIThreadRetargetableRequest : nsISupports
|
||||
* the new target thread.
|
||||
*/
|
||||
void retargetDeliveryTo(in nsIEventTarget aNewTarget);
|
||||
|
||||
/**
|
||||
* Returns the event target where OnDataAvailable events will be dispatched.
|
||||
*
|
||||
* This is only valid after OnStartRequest has been called. Any time before
|
||||
* that point, the value may be changed by `retargetDeliveryTo` calls.
|
||||
*/
|
||||
readonly attribute nsIEventTarget deliveryTarget;
|
||||
};
|
||||
|
@ -775,3 +775,13 @@ nsInputStreamPump::RetargetDeliveryTo(nsIEventTarget* aNewTarget)
|
||||
(nsIStreamListener*)mListener, static_cast<uint32_t>(rv)));
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamPump::GetDeliveryTarget(nsIEventTarget** aNewTarget)
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mMutex);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target = mTargetThread;
|
||||
target.forget(aNewTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3386,6 +3386,19 @@ HttpChannelChild::RetargetDeliveryTo(nsIEventTarget* aNewTarget)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetDeliveryTarget(nsIEventTarget** aEventTarget)
|
||||
{
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target = mODATarget;
|
||||
if (!mODATarget) {
|
||||
target = GetCurrentThreadEventTarget();
|
||||
}
|
||||
target.forget(aEventTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::ResetInterception()
|
||||
{
|
||||
|
@ -1078,6 +1078,15 @@ InterceptedHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget)
|
||||
return mPump->RetargetDeliveryTo(aNewTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedHttpChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget)
|
||||
{
|
||||
if (!mPump) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return mPump->GetDeliveryTarget(aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedHttpChannel::CheckListenerChain()
|
||||
{
|
||||
|
@ -7751,6 +7751,19 @@ nsHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::GetDeliveryTarget(nsIEventTarget** aEventTarget)
|
||||
{
|
||||
if (mCachePump) {
|
||||
return mCachePump->GetDeliveryTarget(aEventTarget);
|
||||
}
|
||||
if (mTransactionPump) {
|
||||
return mTransactionPump->GetDeliveryTarget(aEventTarget);
|
||||
}
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsThreadRetargetableStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -359,6 +359,19 @@ BaseWebSocketChannel::RetargetDeliveryTo(nsIEventTarget* aTargetThread)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BaseWebSocketChannel::GetDeliveryTarget(nsIEventTarget** aTargetThread)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target = mTargetThread;
|
||||
if (!target) {
|
||||
target = GetCurrentThreadEventTarget();
|
||||
}
|
||||
target.forget(aTargetThread);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BaseWebSocketChannel::ListenerAndContextContainer::ListenerAndContextContainer(
|
||||
nsIWebSocketListener* aListener,
|
||||
nsISupports* aContext)
|
||||
|
Loading…
x
Reference in New Issue
Block a user