123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef nsBaseAppShell_h__
- #define nsBaseAppShell_h__
- #include "mozilla/Atomics.h"
- #include "nsIAppShell.h"
- #include "nsIThreadInternal.h"
- #include "nsIObserver.h"
- #include "nsIRunnable.h"
- #include "nsCOMPtr.h"
- #include "nsTArray.h"
- #include "prinrval.h"
- /**
- * A singleton that manages the UI thread's event queue. Subclass this class
- * to enable platform-specific event queue support.
- */
- class nsBaseAppShell : public nsIAppShell, public nsIThreadObserver,
- public nsIObserver
- {
- public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIAPPSHELL
- NS_DECL_NSITHREADOBSERVER
- NS_DECL_NSIOBSERVER
- nsBaseAppShell();
- protected:
- virtual ~nsBaseAppShell();
- /**
- * This method is called by subclasses when the app shell singleton is
- * instantiated.
- */
- nsresult Init();
- /**
- * Called by subclasses from a native event. See ScheduleNativeEventCallback.
- */
- void NativeEventCallback();
- /**
- * Make a decision as to whether or not NativeEventCallback will
- * trigger gecko event processing when there are pending gecko
- * events.
- */
- virtual void DoProcessMoreGeckoEvents();
- /**
- * Implemented by subclasses. Invoke NativeEventCallback from a native
- * event. This method may be called on any thread.
- */
- virtual void ScheduleNativeEventCallback() = 0;
- /**
- * Implemented by subclasses. Process the next native event. Only wait for
- * the next native event if mayWait is true. This method is only called on
- * the main application thread.
- *
- * @param mayWait
- * If "true", then this method may wait if necessary for the next available
- * native event. DispatchNativeEvent may be called to unblock a call to
- * ProcessNextNativeEvent that is waiting.
- * @return
- * This method returns "true" if a native event was processed.
- */
- virtual bool ProcessNextNativeEvent(bool mayWait) = 0;
- int32_t mSuspendNativeCount;
- uint32_t mEventloopNestingLevel;
- private:
- bool DoProcessNextNativeEvent(bool mayWait);
- bool DispatchDummyEvent(nsIThread* target);
- void IncrementEventloopNestingLevel();
- void DecrementEventloopNestingLevel();
- nsCOMPtr<nsIRunnable> mDummyEvent;
- /**
- * mBlockedWait points back to a slot that controls the wait loop in
- * an outer OnProcessNextEvent invocation. Nested calls always set
- * it to false to unblock an outer loop, since all events may
- * have been consumed by the inner event loop(s).
- */
- bool *mBlockedWait;
- int32_t mFavorPerf;
- mozilla::Atomic<bool> mNativeEventPending;
- PRIntervalTime mStarvationDelay;
- PRIntervalTime mSwitchTime;
- PRIntervalTime mLastNativeEventTime;
- enum EventloopNestingState {
- eEventloopNone, // top level thread execution
- eEventloopXPCOM, // innermost native event loop is ProcessNextNativeEvent
- eEventloopOther // innermost native event loop is a native library/plugin etc
- };
- EventloopNestingState mEventloopNestingState;
- bool mRunning;
- bool mExiting;
- /**
- * mBlockNativeEvent blocks the appshell from processing native events.
- * It is set to true while a nested native event loop (eEventloopOther)
- * is processing gecko events in NativeEventCallback(), thus queuing up
- * native events until we return to that loop (bug 420148).
- * We force mBlockNativeEvent to false in case handling one of the gecko
- * events spins up a nested XPCOM event loop (eg. modal window) which would
- * otherwise lead to a "deadlock" where native events aren't processed at all.
- */
- bool mBlockNativeEvent;
- /**
- * Tracks whether we have processed any gecko events in NativeEventCallback so
- * that we can avoid erroneously entering a blocking loop waiting for gecko
- * events to show up during OnProcessNextEvent. This is required because on
- * OS X ProcessGeckoEvents may be invoked inside the context of
- * ProcessNextNativeEvent and may result in NativeEventCallback being invoked
- * and in turn invoking NS_ProcessPendingEvents. Because
- * ProcessNextNativeEvent may be invoked prior to the NS_HasPendingEvents
- * waiting loop, this is the only way to make the loop aware that events may
- * have been processed.
- *
- * This variable is set to false in OnProcessNextEvent prior to the first
- * call to DoProcessNextNativeEvent. It is set to true by
- * NativeEventCallback after calling NS_ProcessPendingEvents.
- */
- bool mProcessedGeckoEvents;
- };
- #endif // nsBaseAppShell_h__
|