michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef CacheIOThread__h__ michael@0: #define CacheIOThread__h__ michael@0: michael@0: #include "nsIThreadInternal.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "prthread.h" michael@0: #include "nsTArray.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "mozilla/Monitor.h" michael@0: michael@0: class nsIRunnable; michael@0: michael@0: namespace mozilla { michael@0: namespace net { michael@0: michael@0: class CacheIOThread : public nsIThreadObserver michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSITHREADOBSERVER michael@0: michael@0: CacheIOThread(); michael@0: virtual ~CacheIOThread(); michael@0: michael@0: enum ELevel { michael@0: OPEN_PRIORITY, michael@0: READ_PRIORITY, michael@0: OPEN, michael@0: READ, michael@0: MANAGEMENT, michael@0: WRITE, michael@0: CLOSE, michael@0: INDEX, michael@0: EVICT, michael@0: LAST_LEVEL, michael@0: michael@0: // This is actually executed as the first level, but we want this enum michael@0: // value merely as an indicator while other values are used as indexes michael@0: // to the queue array. Hence put at end and not as the first. michael@0: XPCOM_LEVEL michael@0: }; michael@0: michael@0: nsresult Init(); michael@0: nsresult Dispatch(nsIRunnable* aRunnable, uint32_t aLevel); michael@0: // Makes sure that any previously posted event to OPEN or OPEN_PRIORITY michael@0: // levels (such as file opennings and dooms) are executed before aRunnable michael@0: // that is intended to evict stuff from the cache. michael@0: nsresult DispatchAfterPendingOpens(nsIRunnable* aRunnable); michael@0: bool IsCurrentThread(); michael@0: michael@0: /** michael@0: * Callable only on this thread, checks if there is an event waiting in michael@0: * the event queue with a higher execution priority. If so, the result michael@0: * is true and the current event handler should break it's work and return michael@0: * from Run() method immediately. The event handler will be rerun again michael@0: * when all more priority events are processed. Events pending after this michael@0: * handler (i.e. the one that called YieldAndRerun()) will not execute sooner michael@0: * then this handler is executed w/o a call to YieldAndRerun(). michael@0: */ michael@0: static bool YieldAndRerun() michael@0: { michael@0: return sSelf ? sSelf->YieldInternal() : false; michael@0: } michael@0: michael@0: nsresult Shutdown(); michael@0: already_AddRefed Target(); michael@0: michael@0: // Memory reporting michael@0: size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; michael@0: size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; michael@0: michael@0: private: michael@0: static void ThreadFunc(void* aClosure); michael@0: void ThreadFunc(); michael@0: void LoopOneLevel(uint32_t aLevel); michael@0: bool EventsPending(uint32_t aLastLevel = LAST_LEVEL); michael@0: nsresult DispatchInternal(nsIRunnable* aRunnable, uint32_t aLevel); michael@0: bool YieldInternal(); michael@0: michael@0: static CacheIOThread* sSelf; michael@0: michael@0: mozilla::Monitor mMonitor; michael@0: PRThread* mThread; michael@0: nsCOMPtr mXPCOMThread; michael@0: uint32_t mLowestLevelWaiting; michael@0: uint32_t mCurrentlyExecutingLevel; michael@0: nsTArray > mEventQueue[LAST_LEVEL]; michael@0: michael@0: bool mHasXPCOMEvents; michael@0: bool mRerunCurrentEvent; michael@0: bool mShutdown; michael@0: }; michael@0: michael@0: } // net michael@0: } // mozilla michael@0: michael@0: #endif