diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-06 21:27:02 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-06 21:27:02 +0000 |
commit | ee132adb94b58e7ea585b1fadf232aa60810ff1b (patch) | |
tree | 71f598a0ed4ea1d7d6e31f3ecf54eefdc4fd2e3b | |
parent | 1671de4c8e8867be055ff22045afc1d9d946fc84 (diff) | |
download | chromium_src-ee132adb94b58e7ea585b1fadf232aa60810ff1b.zip chromium_src-ee132adb94b58e7ea585b1fadf232aa60810ff1b.tar.gz chromium_src-ee132adb94b58e7ea585b1fadf232aa60810ff1b.tar.bz2 |
just some hopefully non-contentious stuff to get out of the way before doing the real MessageLoop changes.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@459 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/id_map.h | 10 | ||||
-rw-r--r-- | base/message_loop.cc | 34 | ||||
-rw-r--r-- | base/message_loop.h | 95 | ||||
-rw-r--r-- | base/thread_local_storage.h | 10 | ||||
-rw-r--r-- | base/timer.cc | 4 | ||||
-rw-r--r-- | base/timer.h | 13 |
6 files changed, 85 insertions, 81 deletions
diff --git a/base/id_map.h b/base/id_map.h index e945f6a..7335b02 100644 --- a/base/id_map.h +++ b/base/id_map.h @@ -30,14 +30,8 @@ #ifndef BASE_ID_MAP_H__ #define BASE_ID_MAP_H__ -// hash map is common (GCC4 and Dinkumware also support it, for example), but -// is not strictly part of the C++ standard. MS puts it into a funny namespace, -// although most other vendors seem to use std. This may have to change if -// other platforms are supported. -#include <hash_map> -using stdext::hash_map; - #include "base/basictypes.h" +#include "base/hash_tables.h" #include "base/logging.h" // This object maintains a list of IDs that can be quickly converted to @@ -51,7 +45,7 @@ using stdext::hash_map; template<class T> class IDMap { private: - typedef hash_map<int32, T*> HashTable; + typedef base::hash_map<int32, T*> HashTable; public: IDMap() : next_id_(1) { diff --git a/base/message_loop.cc b/base/message_loop.cc index 78f820c..37b6f36 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -70,22 +70,6 @@ static const int kNumberOfDistinctMessagesDisplayed = 1100; //------------------------------------------------------------------------------ -static LRESULT CALLBACK MessageLoopWndProc(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) { - switch (message) { - case kMsgQuit: - case kMsgPumpATask: { - UINT_PTR message_loop_id = static_cast<UINT_PTR>(wparam); - MessageLoop* current_message_loop = - reinterpret_cast<MessageLoop*>(message_loop_id); - DCHECK(MessageLoop::current() == current_message_loop); - return current_message_loop->MessageWndProc(hwnd, message, wparam, - lparam); - } - } - return ::DefWindowProc(hwnd, message, wparam, lparam); -} - #ifndef NDEBUG // Force exercise of polling model. #define CHROME_MAXIMUM_WAIT_OBJECTS 8 @@ -385,7 +369,7 @@ void MessageLoop::PostTaskInternal(Task* task) { // Do not invoke non-static methods, or members in any way! // PostMessage may fail, as the hwnd may have vanished due to kMsgQuit. - PostMessage(message_hwnd, kMsgPumpATask, reinterpret_cast<UINT_PTR>(this), 0); + PostMessage(message_hwnd, kMsgPumpATask, 0, 0); } void MessageLoop::InitMessageWnd() { @@ -393,7 +377,7 @@ void MessageLoop::InitMessageWnd() { WNDCLASSEX wc = {0}; wc.cbSize = sizeof(wc); - wc.lpfnWndProc = MessageLoopWndProc; + wc.lpfnWndProc = WndProcThunk; wc.hInstance = hinst; wc.lpszClassName = kWndClass; RegisterClassEx(&wc); @@ -403,8 +387,15 @@ void MessageLoop::InitMessageWnd() { DCHECK(message_hwnd_); } -LRESULT MessageLoop::MessageWndProc(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) { +// static +LRESULT CALLBACK MessageLoop::WndProcThunk( + HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { + DCHECK(MessageLoop::current()); + return MessageLoop::current()->WndProc(hwnd, message, wparam, lparam); +} + +LRESULT MessageLoop::WndProc( + HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { DCHECK(hwnd == message_hwnd_); switch (message) { case kMsgPumpATask: { @@ -773,8 +764,7 @@ void MessageLoop::EnsureMessageGetsPosted(int message) const { for (int i = 0; i < kRetryCount; ++i) { // Posting to our own windows should always succeed. If it doesn't we're in // big trouble. - if (PostMessage(message_hwnd_, message, - reinterpret_cast<UINT_PTR>(this), 0)) + if (PostMessage(message_hwnd_, message, 0, 0)) return; Sleep(kSleepDurationWhenFailing); } diff --git a/base/message_loop.h b/base/message_loop.h index cd7b1c5..9ce0b8a 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -30,7 +30,6 @@ #ifndef BASE_MESSAGE_LOOP_H__ #define BASE_MESSAGE_LOOP_H__ -#include <windows.h> #include <deque> #include <queue> #include <string> @@ -141,6 +140,7 @@ class MessageLoop { static void SetStrategy(int strategy); static void EnableHistogrammer(bool enable_histogrammer); +#ifdef OS_WIN // Used with WatchObject to asynchronously monitor the signaled state of a // HANDLE object. class Watcher { @@ -154,6 +154,36 @@ class MessageLoop { // Pass a null watcher to stop watching the object. bool WatchObject(HANDLE, Watcher*); + // An Observer is an object that receives global notifications from the + // MessageLoop. + // + // NOTE: An Observer implementation should be extremely fast! + // + class Observer { + public: + virtual ~Observer() {} + + // This method is called before processing a message. + // The message may be undefined in which case msg.message is 0 + virtual void WillProcessMessage(const MSG& msg) = 0; + + // This method is called when control returns from processing a UI message. + // The message may be undefined in which case msg.message is 0 + virtual void DidProcessMessage(const MSG& msg) = 0; + }; + + // Add an Observer, which will start receiving notifications immediately. + void AddObserver(Observer* observer); + + // Remove an Observer. It is safe to call this method while an Observer is + // receiving a notification callback. + void RemoveObserver(Observer* observer); + + // Give a chance to code processing additional messages to notify the + // message loop observers that another message has been processed. + void WillProcessMessage(const MSG& msg); + void DidProcessMessage(const MSG& msg); + // Dispatcher is used during a nested invocation of Run to dispatch events. // If Run is invoked with a non-NULL Dispatcher, MessageLoop does not // dispatch events (or invoke TranslateMessage), rather every message is @@ -175,6 +205,12 @@ class MessageLoop { // normal. If false is returned, the nested loop exits immediately. virtual bool Dispatch(const MSG& msg) = 0; }; +#else // !OS_WIN + // On non-Windows platforms, the Dispatcher does not exist, but we allow the + // typename to exist for convenience. On non-Windows platforms, a Dispatcher + // pointer should always be NULL. + class Dispatcher; +#endif // OS_* // A DestructionObserver is notified when the current MessageLoop is being // destroyed. These obsevers are notified prior to MessageLoop::current() @@ -198,31 +234,6 @@ class MessageLoop { // DestructionObserver is receiving a notification callback. void RemoveDestructionObserver(DestructionObserver* destruction_observer); - // An Observer is an object that receives global notifications from the - // MessageLoop. - // - // NOTE: An Observer implementation should be extremely fast! - // - class Observer { - public: - virtual ~Observer() {} - - // This method is called before processing a message. - // The message may be undefined in which case msg.message is 0 - virtual void WillProcessMessage(const MSG& msg) = 0; - - // This method is called when control returns from processing a UI message. - // The message may be undefined in which case msg.message is 0 - virtual void DidProcessMessage(const MSG& msg) = 0; - }; - - // Add an Observer, which will start receiving notifications immediately. - void AddObserver(Observer* observer); - - // Remove an Observer. It is safe to call this method while an Observer is - // receiving a notification callback. - void RemoveObserver(Observer* observer); - // Call the task's Run method asynchronously from within a message loop at // some point in the future. With the PostTask variant, tasks are invoked in // FIFO order, inter-mixed with normal UI event processing. With the @@ -299,9 +310,6 @@ class MessageLoop { } }; - // Wnd Proc for message_hwnd_. - LRESULT MessageWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); - // Normally, it is not necessary to instantiate a MessageLoop. Instead, it // is typical to make use of the current thread's MessageLoop instance. MessageLoop(); @@ -309,7 +317,7 @@ class MessageLoop { // Optional call to connect the thread name with this loop. void SetThreadName(const std::string& thread_name); - std::string thread_name() const { return thread_name_; } + const std::string& thread_name() const { return thread_name_; } // Returns the MessageLoop object for the current thread, or null if none. static MessageLoop* current() { @@ -319,11 +327,6 @@ class MessageLoop { // Returns the TimerManager object for the current thread. TimerManager* timer_manager() { return &timer_manager_; } - // Give a chance to code processing additional messages to notify the - // message loop delegates that another message has been processed. - void WillProcessMessage(const MSG& msg); - void DidProcessMessage(const MSG& msg); - // Enables or disables the recursive task processing. This happens in the case // of recursive message loops. Some unwanted message loop may occurs when // using common controls or printer functions. By default, recursive task @@ -413,7 +416,7 @@ class MessageLoop { : task_(task), sequence_number_(sequence_number), priority_(task->priority()) {} - Task* task() { return task_; } + Task* task() const { return task_; } bool operator < (PrioritizedTask const & right) const ; private: @@ -459,8 +462,15 @@ class MessageLoop { DISALLOW_EVIL_CONSTRUCTORS(OptionallyPrioritizedTaskQueue); }; +#ifdef OS_WIN void InitMessageWnd(); + // Windows procedure for message_hwnd_. + static LRESULT CALLBACK WndProcThunk( + HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); + LRESULT WndProc( + HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); +#endif // OS_WIN // A function to encapsulate all the exception handling capability in the // stacks around the running of a main message loop. @@ -490,8 +500,7 @@ class MessageLoop { bool ProcessSomeTimers(); //---------------------------------------------------------------------------- - // Process some pending messages. - // Returns true if a message was processed. + // Process some pending messages. Returns true if a message was processed. bool ProcessNextWindowsMessage(); // Wait until either an object is signaled, a message is available, a timer @@ -499,12 +508,14 @@ class MessageLoop { // Handle (without returning) any APCs (only IO thread currently has APCs.) void WaitForWork(); +#ifdef OS_WIN // Helper function for processing window messages. This includes handling // WM_QUIT, message translation and dispatch, etc. // // If dispatcher_ is non-NULL this method does NOT dispatch the event, instead // it invokes Dispatch on the dispatcher_. bool ProcessMessageHelper(const MSG& msg); +#endif // OS_WIN // When we encounter a kMsgPumpATask, the following helper can be called to // peek and process a replacement message, such as a WM_PAINT or WM_TIMER. @@ -566,7 +577,7 @@ class MessageLoop { void EnsureMessageGetsPosted(int message) const; // Post a task to our incomming queue. - void MessageLoop::PostTaskInternal(Task* task); + void PostTaskInternal(Task* task); // Start recording histogram info about events and action IF it was enabled // and IF the statistics recorder can accept a registration of our histogram. @@ -593,14 +604,18 @@ class MessageLoop { // there was no real prioritization. OptionallyPrioritizedTaskQueue work_queue_; +#ifdef OS_WIN + HWND message_hwnd_; + // A vector of objects (and corresponding watchers) that are routinely // serviced by this message loop's pump. std::vector<HANDLE> objects_; std::vector<Watcher*> watchers_; ObserverList<Observer> observers_; +#endif // OS_WIN + ObserverList<DestructionObserver> destruction_observers_; - HWND message_hwnd_; IDMap<Task> timed_tasks_; // A recursion block that prevents accidentally running additonal tasks when // insider a (accidentally induced?) nested message pump. diff --git a/base/thread_local_storage.h b/base/thread_local_storage.h index e27edb8..51536f3 100644 --- a/base/thread_local_storage.h +++ b/base/thread_local_storage.h @@ -32,11 +32,11 @@ #include "base/basictypes.h" -#ifdef WIN32 +#if defined(OS_WIN) typedef int TLSSlot; -#else +#elif defined(OS_POSIX) typedef pthread_key_t TLSSlot; -#endif +#endif // OS_* // Wrapper for thread local storage. This class doesn't // do much except provide an API for portability later. @@ -69,7 +69,7 @@ class ThreadLocalStorage { // value 'value'. static void Set(TLSSlot slot, void* value); -#ifdef WIN32 +#if defined(OS_WIN) // Function called when on thread exit to call TLS // destructor functions. This function is used internally. static void ThreadExit(); @@ -87,7 +87,7 @@ class ThreadLocalStorage { static long tls_key_; static long tls_max_; static TLSDestructorFunc tls_destructors_[kThreadLocalStorageSize]; -#endif +#endif // OS_WIN DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); }; diff --git a/base/timer.cc b/base/timer.cc index a1d401d..7c3a636 100644 --- a/base/timer.cc +++ b/base/timer.cc @@ -116,8 +116,8 @@ bool TimerPQueue::ContainsTimer(const Timer* timer) const { // TimerManager TimerManager::TimerManager() - : use_broken_delay_(false), - message_hwnd_(NULL), + : message_hwnd_(NULL), + use_broken_delay_(false), use_native_timers_(true), message_loop_(NULL) { // We've experimented with all sorts of timers, and initially tried diff --git a/base/timer.h b/base/timer.h index 4374971..de22b64 100644 --- a/base/timer.h +++ b/base/timer.h @@ -31,7 +31,6 @@ #define BASE_TIMER_H_ #include <math.h> -#include <windows.h> #include <queue> #include <vector> @@ -39,6 +38,10 @@ #include "base/basictypes.h" #include "base/time.h" +#ifdef OS_WIN +#include <windows.h> +#endif // OS_WIN + // Timer/TimerManager are objects designed to help setting timers. // Goals of TimerManager: // - have only one Windows system timer for all app timer functionality @@ -202,7 +205,7 @@ class TimerManager { void set_use_broken_delay(bool use_broken_delay) { use_broken_delay_ = use_broken_delay; } -#endif +#endif // UNIT_TEST protected: // Peek at the timer which will fire soonest. @@ -212,16 +215,18 @@ class TimerManager { // Update our Windows WM_TIMER to match our most immediately pending timer. void UpdateWindowsWmTimer(); +#ifdef OS_WIN // Retrieve the Message Window that handles WM_TIMER messages from the // system. HWND GetMessageHWND(); + HWND message_hwnd_; +#endif // OS_WIN + TimerPQueue timers_; bool use_broken_delay_; - HWND message_hwnd_; - // Flag to enable/disable use of native timers. bool use_native_timers_; |