Bug 1494162 - Part 45: Lazy load Menu and MenuItem in TabBar. r=pbro
[gecko.git] / netwerk / cache2 / CacheIOThread.h
blob21928ea46e778d4f43930f1479e8af30e36aee75
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef CacheIOThread__h__
6 #define CacheIOThread__h__
8 #include "nsIThreadInternal.h"
9 #include "nsISupportsImpl.h"
10 #include "prthread.h"
11 #include "nsTArray.h"
12 #include "nsAutoPtr.h"
13 #include "mozilla/Monitor.h"
14 #include "mozilla/DebugOnly.h"
15 #include "mozilla/Atomics.h"
16 #include "mozilla/UniquePtr.h"
18 class nsIRunnable;
20 namespace mozilla {
21 namespace net {
23 namespace detail {
24 // A class keeping platform specific information needed to watch and
25 // cancel any long blocking synchronous IO. Must be predeclared here
26 // since including windows.h breaks stuff with number of macro definition
27 // conflicts.
28 class BlockingIOWatcher;
31 class CacheIOThread final : public nsIThreadObserver
33 virtual ~CacheIOThread();
35 public:
36 NS_DECL_THREADSAFE_ISUPPORTS
37 NS_DECL_NSITHREADOBSERVER
39 CacheIOThread();
41 typedef nsTArray<nsCOMPtr<nsIRunnable>> EventQueue;
43 enum ELevel : uint32_t {
44 OPEN_PRIORITY,
45 READ_PRIORITY,
46 MANAGEMENT, // Doesn't do any actual I/O
47 OPEN,
48 READ,
49 WRITE_PRIORITY,
50 WRITE,
51 INDEX,
52 EVICT,
53 LAST_LEVEL,
55 // This is actually executed as the first level, but we want this enum
56 // value merely as an indicator while other values are used as indexes
57 // to the queue array. Hence put at end and not as the first.
58 XPCOM_LEVEL
61 nsresult Init();
62 nsresult Dispatch(nsIRunnable* aRunnable, uint32_t aLevel);
63 nsresult Dispatch(already_AddRefed<nsIRunnable>, uint32_t aLevel);
64 // Makes sure that any previously posted event to OPEN or OPEN_PRIORITY
65 // levels (such as file opennings and dooms) are executed before aRunnable
66 // that is intended to evict stuff from the cache.
67 nsresult DispatchAfterPendingOpens(nsIRunnable* aRunnable);
68 bool IsCurrentThread();
70 uint32_t QueueSize(bool highPriority);
72 uint32_t EventCounter() const { return mEventCounter; }
74 /**
75 * Callable only on this thread, checks if there is an event waiting in
76 * the event queue with a higher execution priority. If so, the result
77 * is true and the current event handler should break it's work and return
78 * from Run() method immediately. The event handler will be rerun again
79 * when all more priority events are processed. Events pending after this
80 * handler (i.e. the one that called YieldAndRerun()) will not execute sooner
81 * then this handler is executed w/o a call to YieldAndRerun().
83 static bool YieldAndRerun()
85 return sSelf ? sSelf->YieldInternal() : false;
88 void Shutdown();
89 // This method checks if there is a long blocking IO on the
90 // IO thread and tries to cancel it. It waits maximum of
91 // two seconds.
92 void CancelBlockingIO();
93 already_AddRefed<nsIEventTarget> Target();
95 // A stack class used to annotate running interruptable I/O event
96 class Cancelable
98 bool mCancelable;
99 public:
100 explicit Cancelable(bool aCancelable);
101 ~Cancelable();
104 // Memory reporting
105 size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
106 size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
108 private:
109 static void ThreadFunc(void* aClosure);
110 void ThreadFunc();
111 void LoopOneLevel(uint32_t aLevel);
112 bool EventsPending(uint32_t aLastLevel = LAST_LEVEL);
113 nsresult DispatchInternal(already_AddRefed<nsIRunnable> aRunnable, uint32_t aLevel);
114 bool YieldInternal();
116 static CacheIOThread* sSelf;
118 mozilla::Monitor mMonitor;
119 PRThread* mThread;
120 UniquePtr<detail::BlockingIOWatcher> mBlockingIOWatcher;
121 Atomic<nsIThread *> mXPCOMThread;
122 Atomic<uint32_t, Relaxed> mLowestLevelWaiting;
123 uint32_t mCurrentlyExecutingLevel;
125 // Keeps the length of the each event queue, since LoopOneLevel moves all
126 // events into a local array.
127 Atomic<int32_t> mQueueLength[LAST_LEVEL];
129 EventQueue mEventQueue[LAST_LEVEL];
130 // Raised when nsIEventTarget.Dispatch() is called on this thread
131 Atomic<bool, Relaxed> mHasXPCOMEvents;
132 // See YieldAndRerun() above
133 bool mRerunCurrentEvent;
134 // Signal to process all pending events and then shutdown
135 // Synchronized by mMonitor
136 bool mShutdown;
137 // If > 0 there is currently an I/O operation on the thread that
138 // can be canceled when after shutdown, see the Shutdown() method
139 // for usage. Made a counter to allow nesting of the Cancelable class.
140 Atomic<uint32_t, Relaxed> mIOCancelableEvents;
141 // Event counter that increases with every event processed.
142 Atomic<uint32_t, Relaxed> mEventCounter;
143 #ifdef DEBUG
144 bool mInsideLoop;
145 #endif
148 } // namespace net
149 } // namespace mozilla
151 #endif