OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/message_pump_default.h" | 12 #include "base/message_pump_default.h" |
12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
13 #include "base/thread_local_storage.h" | 14 #include "base/thread_local.h" |
14 | 15 |
15 // a TLS index to the message loop for the current thread | 16 // A lazily created thread local storage for quick access to a thread's message |
16 // Note that if we start doing complex stuff in other static initializers | 17 // loop, if one exists. This should be safe and free of static constructors. |
17 // this could cause problems. | 18 static base::LazyInstance<base::ThreadLocalPointer<MessageLoop> > lazy_tls_ptr( |
18 // TODO(evanm): this shouldn't rely on static initialization. | 19 base::LINKER_INITIALIZED); |
19 // static | |
20 TLSSlot MessageLoop::tls_index_; | |
21 | 20 |
22 //------------------------------------------------------------------------------ | 21 //------------------------------------------------------------------------------ |
23 | 22 |
24 // Logical events for Histogram profiling. Run with -message-loop-histogrammer | 23 // Logical events for Histogram profiling. Run with -message-loop-histogrammer |
25 // to get an accounting of messages and actions taken on each thread. | 24 // to get an accounting of messages and actions taken on each thread. |
26 static const int kTaskRunEvent = 0x1; | 25 static const int kTaskRunEvent = 0x1; |
27 static const int kTimerEvent = 0x2; | 26 static const int kTimerEvent = 0x2; |
28 | 27 |
29 // Provide range of message IDs for use in histogramming and debug display. | 28 // Provide range of message IDs for use in histogramming and debug display. |
30 static const int kLeastNonZeroMessageId = 1; | 29 static const int kLeastNonZeroMessageId = 1; |
(...skipping 17 matching lines...) Expand all Loading... |
48 LPTOP_LEVEL_EXCEPTION_FILTER top_filter = NULL; | 47 LPTOP_LEVEL_EXCEPTION_FILTER top_filter = NULL; |
49 top_filter = ::SetUnhandledExceptionFilter(0); | 48 top_filter = ::SetUnhandledExceptionFilter(0); |
50 ::SetUnhandledExceptionFilter(top_filter); | 49 ::SetUnhandledExceptionFilter(top_filter); |
51 return top_filter; | 50 return top_filter; |
52 } | 51 } |
53 | 52 |
54 #endif // defined(OS_WIN) | 53 #endif // defined(OS_WIN) |
55 | 54 |
56 //------------------------------------------------------------------------------ | 55 //------------------------------------------------------------------------------ |
57 | 56 |
| 57 // static |
| 58 MessageLoop* MessageLoop::current() { |
| 59 // TODO(darin): sadly, we cannot enable this yet since people call us even |
| 60 // when they have no intention of using us. |
| 61 //DCHECK(loop) << "Ouch, did you forget to initialize me?"; |
| 62 return lazy_tls_ptr.Pointer()->Get(); |
| 63 } |
| 64 |
58 MessageLoop::MessageLoop(Type type) | 65 MessageLoop::MessageLoop(Type type) |
59 : type_(type), | 66 : type_(type), |
60 nestable_tasks_allowed_(true), | 67 nestable_tasks_allowed_(true), |
61 exception_restoration_(false), | 68 exception_restoration_(false), |
62 state_(NULL), | 69 state_(NULL), |
63 next_sequence_num_(0) { | 70 next_sequence_num_(0) { |
64 DCHECK(!tls_index_.Get()) << "should only have one message loop per thread"; | 71 DCHECK(!current()) << "should only have one message loop per thread"; |
65 tls_index_.Set(this); | 72 lazy_tls_ptr.Pointer()->Set(this); |
66 | 73 |
67 // TODO(darin): Choose the pump based on the requested type. | 74 // TODO(darin): Choose the pump based on the requested type. |
68 #if defined(OS_WIN) | 75 #if defined(OS_WIN) |
69 if (type_ == TYPE_DEFAULT) { | 76 if (type_ == TYPE_DEFAULT) { |
70 pump_ = new base::MessagePumpDefault(); | 77 pump_ = new base::MessagePumpDefault(); |
71 } else { | 78 } else { |
72 pump_ = new base::MessagePumpWin(); | 79 pump_ = new base::MessagePumpWin(); |
73 } | 80 } |
74 #else | 81 #else |
75 pump_ = new base::MessagePumpDefault(); | 82 pump_ = new base::MessagePumpDefault(); |
76 #endif | 83 #endif |
77 } | 84 } |
78 | 85 |
79 MessageLoop::~MessageLoop() { | 86 MessageLoop::~MessageLoop() { |
80 DCHECK(this == current()); | 87 DCHECK(this == current()); |
81 | 88 |
82 // Let interested parties have one last shot at accessing this. | 89 // Let interested parties have one last shot at accessing this. |
83 FOR_EACH_OBSERVER(DestructionObserver, destruction_observers_, | 90 FOR_EACH_OBSERVER(DestructionObserver, destruction_observers_, |
84 WillDestroyCurrentMessageLoop()); | 91 WillDestroyCurrentMessageLoop()); |
85 | 92 |
86 // OK, now make it so that no one can find us. | 93 // OK, now make it so that no one can find us. |
87 tls_index_.Set(NULL); | 94 lazy_tls_ptr.Pointer()->Set(NULL); |
88 | 95 |
89 DCHECK(!state_); | 96 DCHECK(!state_); |
90 | 97 |
91 // Most tasks that have not been Run() are deleted in the |timer_manager_| | 98 // Most tasks that have not been Run() are deleted in the |timer_manager_| |
92 // destructor after we remove our tls index. We delete the tasks in our | 99 // destructor after we remove our tls index. We delete the tasks in our |
93 // queues here so their destuction is similar to the tasks in the | 100 // queues here so their destuction is similar to the tasks in the |
94 // |timer_manager_|. | 101 // |timer_manager_|. |
95 DeletePendingTasks(); | 102 DeletePendingTasks(); |
96 ReloadWorkQueue(); | 103 ReloadWorkQueue(); |
97 DeletePendingTasks(); | 104 DeletePendingTasks(); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 //------------------------------------------------------------------------------ | 535 //------------------------------------------------------------------------------ |
529 // MessageLoopForIO | 536 // MessageLoopForIO |
530 | 537 |
531 #if defined(OS_WIN) | 538 #if defined(OS_WIN) |
532 | 539 |
533 void MessageLoopForIO::WatchObject(HANDLE object, Watcher* watcher) { | 540 void MessageLoopForIO::WatchObject(HANDLE object, Watcher* watcher) { |
534 pump_win()->WatchObject(object, watcher); | 541 pump_win()->WatchObject(object, watcher); |
535 } | 542 } |
536 | 543 |
537 #endif // defined(OS_WIN) | 544 #endif // defined(OS_WIN) |
OLD | NEW |