зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1119158 - Retarget OnDataAvailable to a new I/O thread instead of the image decoding thread pool. r=sworkman
This commit is contained in:
Родитель
f5461f43c6
Коммит
183cbfe57e
|
@ -12,6 +12,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIThreadPool.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "prsystem.h"
|
||||
|
||||
|
@ -180,7 +181,7 @@ DecodePool::Singleton()
|
|||
}
|
||||
|
||||
DecodePool::DecodePool()
|
||||
: mThreadPoolMutex("Thread Pool")
|
||||
: mMutex("image::DecodePool")
|
||||
{
|
||||
mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID);
|
||||
MOZ_RELEASE_ASSERT(mThreadPool,
|
||||
|
@ -204,6 +205,11 @@ DecodePool::DecodePool()
|
|||
}
|
||||
#endif
|
||||
|
||||
// Initialize the I/O thread.
|
||||
nsresult rv = NS_NewNamedThread("ImageIO", getter_AddRefs(mIOThread));
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mIOThread,
|
||||
"Should successfully create image I/O thread");
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
||||
if (obsSvc) {
|
||||
obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
|
||||
|
@ -221,17 +227,22 @@ DecodePool::Observe(nsISupports*, const char* aTopic, const char16_t*)
|
|||
MOZ_ASSERT(strcmp(aTopic, "xpcom-shutdown-threads") == 0, "Unexpected topic");
|
||||
|
||||
nsCOMPtr<nsIThreadPool> threadPool;
|
||||
nsCOMPtr<nsIThread> ioThread;
|
||||
|
||||
{
|
||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
||||
threadPool = mThreadPool;
|
||||
mThreadPool = nullptr;
|
||||
MutexAutoLock lock(mMutex);
|
||||
threadPool.swap(mThreadPool);
|
||||
ioThread.swap(mIOThread);
|
||||
}
|
||||
|
||||
if (threadPool) {
|
||||
threadPool->Shutdown();
|
||||
}
|
||||
|
||||
if (ioThread) {
|
||||
ioThread->Shutdown();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -244,7 +255,7 @@ DecodePool::AsyncDecode(Decoder* aDecoder)
|
|||
|
||||
// Dispatch to the thread pool if it exists. If it doesn't, we're currently
|
||||
// shutting down, so it's OK to just drop the job on the floor.
|
||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
||||
MutexAutoLock threadPoolLock(mMutex);
|
||||
if (mThreadPool) {
|
||||
mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL);
|
||||
}
|
||||
|
@ -274,11 +285,19 @@ DecodePool::SyncDecodeIfPossible(Decoder* aDecoder)
|
|||
already_AddRefed<nsIEventTarget>
|
||||
DecodePool::GetEventTarget()
|
||||
{
|
||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
||||
MutexAutoLock threadPoolLock(mMutex);
|
||||
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(mThreadPool);
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIEventTarget>
|
||||
DecodePool::GetIOEventTarget()
|
||||
{
|
||||
MutexAutoLock threadPoolLock(mMutex);
|
||||
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(mIOThread);
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIRunnable>
|
||||
DecodePool::CreateDecodeWorker(Decoder* aDecoder)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsIEventTarget.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
class nsIThread;
|
||||
class nsIThreadPool;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -69,6 +70,15 @@ public:
|
|||
*/
|
||||
already_AddRefed<nsIEventTarget> GetEventTarget();
|
||||
|
||||
/**
|
||||
* Returns an event target interface to the DecodePool's I/O thread. Callers
|
||||
* who want to deliver data to workers on the DecodePool can use this event
|
||||
* target.
|
||||
*
|
||||
* @return An nsIEventTarget interface to the thread pool's I/O thread.
|
||||
*/
|
||||
already_AddRefed<nsIEventTarget> GetIOEventTarget();
|
||||
|
||||
/**
|
||||
* Creates a worker which can be used to attempt further decoding using the
|
||||
* provided decoder.
|
||||
|
@ -91,11 +101,10 @@ private:
|
|||
|
||||
static StaticRefPtr<DecodePool> sSingleton;
|
||||
|
||||
// mThreadPoolMutex protects mThreadPool. For all RasterImages R,
|
||||
// R::mDecodingMonitor must be acquired before mThreadPoolMutex
|
||||
// if both are acquired; the other order may cause deadlock.
|
||||
Mutex mThreadPoolMutex;
|
||||
// mMutex protects mThreadPool and mIOThread.
|
||||
Mutex mMutex;
|
||||
nsCOMPtr<nsIThreadPool> mThreadPool;
|
||||
nsCOMPtr<nsIThread> mIOThread;
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
|
|
|
@ -699,10 +699,9 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
|
|||
nsAutoCString mimeType;
|
||||
nsresult rv = httpChannel->GetContentType(mimeType);
|
||||
if (NS_SUCCEEDED(rv) && !mimeType.EqualsLiteral(IMAGE_SVG_XML)) {
|
||||
// Image object not created until OnDataAvailable, so forward to static
|
||||
// DecodePool directly.
|
||||
// Retarget OnDataAvailable to the DecodePool's IO thread.
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
DecodePool::Singleton()->GetEventTarget();
|
||||
DecodePool::Singleton()->GetIOEventTarget();
|
||||
rv = retargetable->RetargetDeliveryTo(target);
|
||||
}
|
||||
PR_LOG(GetImgLog(), PR_LOG_WARNING,
|
||||
|
|
Загрузка…
Ссылка в новой задаче