1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/SharedThreadPool.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,90 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef SharedThreadPool_h_ 1.11 +#define SharedThreadPool_h_ 1.12 + 1.13 +#include <queue> 1.14 +#include "mozilla/RefPtr.h" 1.15 +#include "nsThreadUtils.h" 1.16 +#include "nsIThreadPool.h" 1.17 +#include "nsISupports.h" 1.18 +#include "nsISupportsImpl.h" 1.19 +#include "nsCOMPtr.h" 1.20 + 1.21 +namespace mozilla { 1.22 + 1.23 +// Wrapper that makes an nsIThreadPool a singleton, and provides a 1.24 +// consistent threadsafe interface to get instances. Callers simply get a 1.25 +// SharedThreadPool by the name of its nsIThreadPool. All get requests of 1.26 +// the same name get the same SharedThreadPool. Users must store a reference 1.27 +// to the pool, and when the last reference to a SharedThreadPool is dropped 1.28 +// the pool is shutdown and deleted. Users aren't required to manually 1.29 +// shutdown the pool, and can release references on any thread. On Windows 1.30 +// all threads in the pool have MSCOM initialized with COINIT_MULTITHREADED. 1.31 +class SharedThreadPool : public nsIThreadPool 1.32 +{ 1.33 +public: 1.34 + 1.35 + // Gets (possibly creating) the shared thread pool singleton instance with 1.36 + // thread pool named aName. 1.37 + // *Must* be called on the main thread. 1.38 + static TemporaryRef<SharedThreadPool> Get(const nsCString& aName, 1.39 + uint32_t aThreadLimit = 4); 1.40 + 1.41 + // Spins the event loop until all thread pools are shutdown. 1.42 + // *Must* be called on the main thread. 1.43 + static void SpinUntilShutdown(); 1.44 + 1.45 + // We implement custom threadsafe AddRef/Release pair, that destroys the 1.46 + // the shared pool singleton when the refcount drops to 0. The addref/release 1.47 + // are implemented using locking, so it's not recommended that you use them 1.48 + // in a tight loop. 1.49 + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); 1.50 + NS_IMETHOD_(MozExternalRefCountType) AddRef(void); 1.51 + NS_IMETHOD_(MozExternalRefCountType) Release(void); 1.52 + 1.53 + // Forward behaviour to wrapped thread pool implementation. 1.54 + NS_FORWARD_SAFE_NSITHREADPOOL(mPool); 1.55 + NS_FORWARD_SAFE_NSIEVENTTARGET(GetEventTarget()); 1.56 + 1.57 + nsIEventTarget* GetEventTarget() { 1.58 + return mEventTarget; 1.59 + } 1.60 + 1.61 +private: 1.62 + 1.63 + // Creates necessary statics. 1.64 + // Main thread only. 1.65 + static void EnsureInitialized(); 1.66 + 1.67 + // Creates a singleton SharedThreadPool wrapper around aPool. 1.68 + // aName is the name of the aPool, and is used to lookup the 1.69 + // SharedThreadPool in the hash table of all created pools. 1.70 + SharedThreadPool(const nsCString& aName, 1.71 + nsIThreadPool* aPool); 1.72 + virtual ~SharedThreadPool(); 1.73 + 1.74 + nsresult EnsureThreadLimitIsAtLeast(uint32_t aThreadLimit); 1.75 + 1.76 + // Name of mPool. 1.77 + const nsCString mName; 1.78 + 1.79 + // Thread pool being wrapped. 1.80 + nsCOMPtr<nsIThreadPool> mPool; 1.81 + 1.82 + // Refcount. We implement custom ref counting so that the thread pool is 1.83 + // shutdown in a threadsafe manner and singletonness is preserved. 1.84 + nsrefcnt mRefCnt; 1.85 + 1.86 + // mPool QI'd to nsIEventTarget. We cache this, so that we can use 1.87 + // NS_FORWARD_SAFE_NSIEVENTTARGET above. 1.88 + nsCOMPtr<nsIEventTarget> mEventTarget; 1.89 +}; 1.90 + 1.91 +} // namespace mozilla 1.92 + 1.93 +#endif // SharedThreadPool_h_