diff options
author | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-19 18:36:23 +0000 |
---|---|---|
committer | darin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-19 18:36:23 +0000 |
commit | b16ef312cb28582a1d324d20e4328afeef2c7538 (patch) | |
tree | bcbc40bbe3950501c888eab655f5070619ad1ac7 /base | |
parent | 4880adb3346faa91feea9d8ecfecc4ef499bf7fc (diff) | |
download | chromium_src-b16ef312cb28582a1d324d20e4328afeef2c7538.zip chromium_src-b16ef312cb28582a1d324d20e4328afeef2c7538.tar.gz chromium_src-b16ef312cb28582a1d324d20e4328afeef2c7538.tar.bz2 |
Define MessagePumpDefault and use it to implement MessageLoop on non-Windows
platforms. This is actually just a first-step toward the real fix which is to
use MessagePumpDefault on all platforms on non-UI and non-IO threads.
This CL also fixes some GCC compilation errors. I renamed MessageLoopOwnable
to TaskBase, which seems more appropriate since a MessageLoopOwnable has a
next Task pointer and clearly is only meaningful in the context of Task. (I
wonder why it is even a separate class, but that is another issue.) I had to
make the next_task / set_next_task methods public since they are used by an
inner class of MessageLoop. Perhaps those inner classes should be made into
top-level classes, but that seemed like too much to change at this time.
R=jar,mmentovai
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1045 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.xcodeproj/project.pbxproj | 30 | ||||
-rw-r--r-- | base/histogram.cc | 3 | ||||
-rw-r--r-- | base/histogram.h | 3 | ||||
-rw-r--r-- | base/histogram_test.cc | 30 | ||||
-rw-r--r-- | base/logging.cc | 8 | ||||
-rw-r--r-- | base/message_loop.cc | 8 | ||||
-rw-r--r-- | base/message_loop_unittest.cc | 36 | ||||
-rw-r--r-- | base/message_pump.h | 2 | ||||
-rw-r--r-- | base/message_pump_default.cc | 100 | ||||
-rw-r--r-- | base/message_pump_default.h | 122 | ||||
-rw-r--r-- | base/task.h | 16 | ||||
-rw-r--r-- | base/test_suite.h | 16 |
12 files changed, 321 insertions, 53 deletions
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj index 71b20ba..773600f 100644 --- a/base/base.xcodeproj/project.pbxproj +++ b/base/base.xcodeproj/project.pbxproj @@ -99,6 +99,12 @@ 829E365F0DC0FB1C00819EBF /* stats_table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403790D92D2CF0006B936 /* stats_table.cc */; }; 829E36730DC0FBAD00819EBF /* thread_local_storage_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 829E36720DC0FBAD00819EBF /* thread_local_storage_posix.cc */; }; 9301C03B0E54C839001EF103 /* waitable_event_generic.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9301C0390E54C839001EF103 /* waitable_event_generic.cc */; }; + 93611ADF0E5A7FC500F9405D /* message_pump_default.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93611ADC0E5A7FC500F9405D /* message_pump_default.cc */; }; + 93611AE10E5A7FE200F9405D /* message_loop.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93611AE00E5A7FE200F9405D /* message_loop.cc */; }; + 93611AE80E5A803700F9405D /* message_loop_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93611ADA0E5A7FC500F9405D /* message_loop_unittest.cc */; }; + 93611AE90E5A804800F9405D /* message_pump_default.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93611ADC0E5A7FC500F9405D /* message_pump_default.cc */; }; + 93611B180E5A875D00F9405D /* histogram.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93611B160E5A875D00F9405D /* histogram.cc */; }; + 93611B1A0E5A878400F9405D /* histogram_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93611B190E5A878400F9405D /* histogram_test.cc */; }; A5A026550E4A214600498DA9 /* file_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5A026540E4A214600498DA9 /* file_util.cc */; }; A5A0268E0E4A2BDC00498DA9 /* file_util_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5A0268D0E4A2BDC00498DA9 /* file_util_posix.cc */; }; A5A0270B0E4A630D00498DA9 /* file_util_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5A0270A0E4A630D00498DA9 /* file_util_mac.mm */; }; @@ -307,7 +313,6 @@ 820EB5030E3A61A1009668FC /* watchdog.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = watchdog.cc; sourceTree = "<group>"; }; 820EB5040E3A61A1009668FC /* watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = watchdog.h; sourceTree = "<group>"; }; 821B91680DAABD7F00F350D7 /* string16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string16.h; sourceTree = "<group>"; }; - 822BDC710DF739F000034F4C /* message_loop_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = message_loop_mac.mm; sourceTree = "<group>"; }; 824652C00DC12044007C2BAA /* hash_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hash_tables.h; sourceTree = "<group>"; }; 824653670DC12CEC007C2BAA /* condition_variable_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = condition_variable_posix.cc; sourceTree = "<group>"; }; 824653730DC12D0E007C2BAA /* shared_memory_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shared_memory_posix.cc; sourceTree = "<group>"; }; @@ -438,6 +443,14 @@ 82E23FCC0D9C219600F8B40A /* platform_thread.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_thread.cc; sourceTree = "<group>"; }; 9301C0390E54C839001EF103 /* waitable_event_generic.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = waitable_event_generic.cc; sourceTree = "<group>"; }; 9301C03A0E54C839001EF103 /* waitable_event_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = waitable_event_unittest.cc; sourceTree = "<group>"; }; + 93611ADA0E5A7FC500F9405D /* message_loop_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message_loop_unittest.cc; sourceTree = "<group>"; }; + 93611ADB0E5A7FC500F9405D /* message_pump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = message_pump.h; sourceTree = "<group>"; }; + 93611ADC0E5A7FC500F9405D /* message_pump_default.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message_pump_default.cc; sourceTree = "<group>"; }; + 93611ADD0E5A7FC500F9405D /* message_pump_default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = message_pump_default.h; sourceTree = "<group>"; }; + 93611AE00E5A7FE200F9405D /* message_loop.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message_loop.cc; sourceTree = "<group>"; }; + 93611B160E5A875D00F9405D /* histogram.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = histogram.cc; sourceTree = "<group>"; }; + 93611B170E5A875D00F9405D /* histogram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = histogram.h; sourceTree = "<group>"; }; + 93611B190E5A878400F9405D /* histogram_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = histogram_test.cc; sourceTree = "<group>"; }; A5A026180E48FE1500498DA9 /* base_paths_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base_paths_mac.h; sourceTree = "<group>"; }; A5A026540E4A214600498DA9 /* file_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_util.cc; sourceTree = "<group>"; }; A5A0268D0E4A2BDC00498DA9 /* file_util_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_util_posix.cc; sourceTree = "<group>"; }; @@ -651,6 +664,9 @@ 8254030B0D92D1D10006B936 /* fix_wp64.h */, 7B4C5D880E4915D800679E8F /* float_util.h */, 824652C00DC12044007C2BAA /* hash_tables.h */, + 93611B160E5A875D00F9405D /* histogram.cc */, + 93611B170E5A875D00F9405D /* histogram.h */, + 93611B190E5A878400F9405D /* histogram_test.cc */, 8254030F0D92D1E80006B936 /* iat_patch.cc */, 825403100D92D1E80006B936 /* iat_patch.h */, 825403110D92D1E80006B936 /* icu_util.cc */, @@ -679,7 +695,11 @@ 8254032B0D92D2090006B936 /* memory_debug.cc */, 8254032C0D92D2090006B936 /* memory_debug.h */, 825403360D92D2110006B936 /* message_loop.h */, - 822BDC710DF739F000034F4C /* message_loop_mac.mm */, + 93611AE00E5A7FE200F9405D /* message_loop.cc */, + 93611ADA0E5A7FC500F9405D /* message_loop_unittest.cc */, + 93611ADB0E5A7FC500F9405D /* message_pump.h */, + 93611ADC0E5A7FC500F9405D /* message_pump_default.cc */, + 93611ADD0E5A7FC500F9405D /* message_pump_default.h */, 7BAF4F0A0E50A2FD00CA8A07 /* notimplemented.h */, 825403390D92D2210006B936 /* observer_list.h */, E4562C580E2802AC005E4685 /* observer_list_unittest.cc */, @@ -1056,6 +1076,7 @@ A5A0270B0E4A630D00498DA9 /* file_util_mac.mm in Sources */, A5A0268E0E4A2BDC00498DA9 /* file_util_posix.cc in Sources */, 7BAF50760E50B8F100CA8A07 /* file_version_info_mac.mm in Sources */, + 93611B180E5A875D00F9405D /* histogram.cc in Sources */, 8216A5060E34DBDD00EE374C /* icu_util.cc in Sources */, ABF4B9AF0DC2BC6200A6E319 /* json_reader.cc in Sources */, ABF4B9B00DC2BC6500A6E319 /* json_writer.cc in Sources */, @@ -1064,6 +1085,8 @@ 829E35D50DC0DC9400819EBF /* logging.cc in Sources */, ABFBD3E60DC793C600E164CB /* md5.cc in Sources */, ABF4B9B20DC2BC8300A6E319 /* memory_debug.cc in Sources */, + 93611AE10E5A7FE200F9405D /* message_loop.cc in Sources */, + 93611ADF0E5A7FC500F9405D /* message_pump_default.cc in Sources */, ABF4B9B50DC2BC9F00A6E319 /* path_service.cc in Sources */, 824654A60DC25CD7007C2BAA /* pickle.cc in Sources */, ABF4B9B90DC2BCE300A6E319 /* platform_thread.cc in Sources */, @@ -1118,9 +1141,12 @@ 7B78D38F0E54FE0100609465 /* command_line_unittest.cc in Sources */, A5CE1D2B0E55F4D800AD0606 /* file_util_unittest.cc in Sources */, 7B78D3910E54FE0100609465 /* file_version_info_unittest.cc in Sources */, + 93611B1A0E5A878400F9405D /* histogram_test.cc in Sources */, 7B78D3920E54FE0100609465 /* json_reader_unittest.cc in Sources */, 7B78D3930E54FE0100609465 /* json_writer_unittest.cc in Sources */, 7B78D3940E54FE0100609465 /* linked_ptr_unittest.cc in Sources */, + 93611AE80E5A803700F9405D /* message_loop_unittest.cc in Sources */, + 93611AE90E5A804800F9405D /* message_pump_default.cc in Sources */, 7B78D3950E54FE0100609465 /* observer_list_unittest.cc in Sources */, 7B78D3960E54FE0100609465 /* path_service_unittest.cc in Sources */, 7B78D3970E54FE0100609465 /* pickle_unittest.cc in Sources */, diff --git a/base/histogram.cc b/base/histogram.cc index fc72f8f..28ba23c 100644 --- a/base/histogram.cc +++ b/base/histogram.cc @@ -43,6 +43,9 @@ typedef Histogram::Count Count; +// static +const int Histogram::kHexRangePrintingFlag = 0x8000; + Histogram::Histogram(const wchar_t* name, Sample minimum, Sample maximum, size_t bucket_count) : StatsRate(name), diff --git a/base/histogram.h b/base/histogram.h index 5714bd7..140bdd2 100644 --- a/base/histogram.h +++ b/base/histogram.h @@ -177,7 +177,8 @@ class Histogram : public StatsRate { typedef std::vector<Count> Counts; typedef std::vector<Sample> Ranges; - static const int kHexRangePrintingFlag = 0x8000; + static const int kHexRangePrintingFlag; + //---------------------------------------------------------------------------- // Statistic values, developed over the life of the histogram. diff --git a/base/histogram_test.cc b/base/histogram_test.cc index 9830392..29172e3 100644 --- a/base/histogram_test.cc +++ b/base/histogram_test.cc @@ -76,46 +76,46 @@ TEST(HistogramTest, RecordedStartupTest) { StatisticsRecorder recorder; // This initializes the global state. StatisticsRecorder::Histograms histograms; - EXPECT_EQ(0, histograms.size()); + EXPECT_EQ(0U, histograms.size()); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(0, histograms.size()); + EXPECT_EQ(0U, histograms.size()); // Try basic construction Histogram histogram(L"TestHistogram", 1, 1000, 10); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(1, histograms.size()); + EXPECT_EQ(1U, histograms.size()); Histogram histogram1(L"Test1Histogram", 1, 1000, 10); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(2, histograms.size()); + EXPECT_EQ(2U, histograms.size()); LinearHistogram linear_histogram(L"TestLinearHistogram", 1, 1000, 10); LinearHistogram linear_histogram1(L"Test1LinearHistogram", 1, 1000, 10); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(4, histograms.size()); + EXPECT_EQ(4U, histograms.size()); // Use standard macros (but with fixed samples) HISTOGRAM_TIMES(L"Test2Histogram", TimeDelta::FromDays(1)); HISTOGRAM_COUNTS(L"Test3Histogram", 30); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(6, histograms.size()); + EXPECT_EQ(6U, histograms.size()); ASSET_HISTOGRAM_COUNTS(L"TestAssetHistogram", 1000); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists - EXPECT_EQ(7, histograms.size()); + EXPECT_EQ(7U, histograms.size()); DHISTOGRAM_TIMES(L"Test4Histogram", TimeDelta::FromDays(1)); DHISTOGRAM_COUNTS(L"Test5Histogram", 30); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists #ifndef NDEBUG - EXPECT_EQ(9, histograms.size()); + EXPECT_EQ(9U, histograms.size()); #else - EXPECT_EQ(7, histograms.size()); + EXPECT_EQ(7U, histograms.size()); #endif } @@ -124,7 +124,7 @@ TEST(HistogramTest, RangeTest) { StatisticsRecorder::Histograms histograms; recorder.GetHistograms(&histograms); - EXPECT_EQ(0, histograms.size()); + EXPECT_EQ(0U, histograms.size()); Histogram histogram(L"Histogram", 1, 64, 8); // As mentioned in header file. // Check that we got a nice exponential when there was enough rooom. @@ -177,12 +177,12 @@ TEST(HistogramTest, RangeTest) { EXPECT_EQ(INT_MAX, threadsafe_histogram.ranges(15)); recorder.GetHistograms(&histograms); - EXPECT_EQ(5, histograms.size()); + EXPECT_EQ(5U, histograms.size()); } // Make sure histogram handles out-of-bounds data gracefully. TEST(HistogramTest, BoundsTest) { - const int kBucketCount = 50; + const size_t kBucketCount = 50; Histogram histogram(L"Bounded", 10, 100, kBucketCount); // Put two samples "out of bounds" above and below. @@ -251,7 +251,7 @@ TEST(HistogramTest, AssetCountTest) { // Find the histogram. StatisticsRecorder::Histograms histogram_list; StatisticsRecorder::GetHistograms(&histogram_list); - ASSERT_GT(histogram_list.size(), 0u); + ASSERT_NE(0U, histogram_list.size()); std::string ascii_name = WideToASCII(kAssetTestHistogramName); std::string debug_ascii_name = WideToASCII(kAssetTestDebugHistogramName); const Histogram* our_histogram = NULL; @@ -280,7 +280,7 @@ TEST(HistogramTest, AssetCountTest) { EXPECT_LT(++match_count, 2) << "extra count in bucket " << i; } } - EXPECT_EQ(1u, match_count); + EXPECT_EQ(1, match_count); // Remove our sample. AssetCountFunction(-100); // Remove a sample from the bucket for 100. @@ -304,7 +304,7 @@ TEST(HistogramTest, AssetCountTest) { EXPECT_LT(++match_count, 2) << "extra count in bucket " << i; } } - EXPECT_EQ(1u, match_count); + EXPECT_EQ(1, match_count); // Remove our sample. AssetCountFunction(-100); // Remove a sample from the bucket for 100. diff --git a/base/logging.cc b/base/logging.cc index 27781ae0..54418be 100644 --- a/base/logging.cc +++ b/base/logging.cc @@ -27,10 +27,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "base/notimplemented.h" -#include "build/build_config.h" +#include "base/logging.h" -#if defined(WIN32) +#if defined(OS_WIN) #include <windows.h> typedef HANDLE FileHandle; typedef HANDLE MutexHandle; @@ -57,11 +56,12 @@ typedef pthread_mutex_t* MutexHandle; #include <iomanip> #include <cstring> #include <algorithm> + #include "base/base_switches.h" #include "base/command_line.h" #include "base/debug_util.h" #include "base/lock_impl.h" -#include "base/logging.h" +#include "base/notimplemented.h" #include "base/string_piece.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" diff --git a/base/message_loop.cc b/base/message_loop.cc index 4d61b6a..c82c3ee 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -32,6 +32,7 @@ #include <algorithm> #include "base/logging.h" +#include "base/message_pump_default.h" #include "base/string_util.h" #include "base/thread_local_storage.h" @@ -79,14 +80,17 @@ static LPTOP_LEVEL_EXCEPTION_FILTER GetTopSEHFilter() { MessageLoop::MessageLoop() #pragma warning(suppress: 4355) // OK, to use |this| in the initializer list. : timer_manager_(this), - exception_restoration_(false), nestable_tasks_allowed_(true), + exception_restoration_(false), state_(NULL) { DCHECK(tls_index_) << "static initializer failed"; DCHECK(!current()) << "should only have one message loop per thread"; ThreadLocalStorage::Set(tls_index_, this); + // TODO(darin): Generalize this to support instantiating different pumps. #if defined(OS_WIN) pump_ = new base::MessagePumpWin(); +#else + pump_ = new base::MessagePumpDefault(); #endif } @@ -453,7 +457,7 @@ void MessageLoop::PrioritizedTaskQueue::push(Task * task) { bool MessageLoop::PrioritizedTaskQueue::PrioritizedTask::operator < ( PrioritizedTask const & right) const { - int compare = task_->priority_ - right.task_->priority_; + int compare = task_->priority() - right.task_->priority(); if (compare) return compare < 0; // Don't compare directly, but rather subtract. This handles overflow diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc index fdd36ea..4cc003a 100644 --- a/base/message_loop_unittest.cc +++ b/base/message_loop_unittest.cc @@ -29,15 +29,25 @@ #include "base/logging.h" #include "base/message_loop.h" -#include "base/scoped_handle.h" -#include "base/thread.h" +#include "base/platform_thread.h" #include "base/ref_counted.h" +#include "base/thread.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_WIN) #include "base/message_pump_win.h" +#include "base/scoped_handle.h" #endif +// +// TODO(darin): This file needs to be re-organized into acceptance tests that +// apply to a MessageLoop configured to use any MessagePump. Then, those tests +// need to be run against all MessagePump types supported by a platform. +// +// Finally, platform-specific MessageLoop tests should be grouped together to +// avoid the chopping this file up with so many #ifdefs. +// + namespace { class MessageLoopTest : public testing::Test { @@ -184,6 +194,8 @@ class NestingTest : public Task { int* depth_; }; +#if defined(OS_WIN) + LONG WINAPI BadExceptionHandler(EXCEPTION_POINTERS *ex_info) { ADD_FAILURE() << "bad exception handler"; ::ExitProcess(ex_info->ExceptionRecord->ExceptionCode); @@ -200,7 +212,7 @@ class CrasherTask : public Task { : trash_SEH_handler_(trash_SEH_handler) { } void Run() { - Sleep(1); + PlatformThread::Sleep(1); if (trash_SEH_handler_) ::SetUnhandledExceptionFilter(&BadExceptionHandler); // Generate a SEH fault. We do it in asm to make sure we know how to undo @@ -217,8 +229,8 @@ class CrasherTask : public Task { bad_array_[0] = 66; -#elif - +#else +#error "needs architecture support" #endif MessageLoop::current()->Quit(); @@ -259,6 +271,8 @@ LONG WINAPI HandleCrasherTaskException(EXCEPTION_POINTERS *ex_info) { return EXCEPTION_CONTINUE_EXECUTION; } +#endif // defined(OS_WIN) + } // namespace @@ -406,6 +420,8 @@ class OrderedTasks : public Task { int cookie_; }; +#if defined(OS_WIN) + // MessageLoop implicitly start a "modal message loop". Modal dialog boxes, // common controls (like OpenFile) and StartDoc printing function can cause // implicit message loops. @@ -447,6 +463,8 @@ class EndDialogTask : public OrderedTasks { } }; +#endif // defined(OS_WIN) + class RecursiveTask : public OrderedTasks { public: RecursiveTask(int depth, TaskList* order, int cookie, bool is_reentrant) @@ -563,7 +581,7 @@ TEST(MessageLoop, RecursiveDenial1) { MessageLoop::current()->Run(); // FIFO order. - ASSERT_EQ(order.size(), 14); + ASSERT_EQ(14U, order.size()); EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true)); @@ -593,7 +611,7 @@ TEST(MessageLoop, RecursiveSupport1) { MessageLoop::current()->Run(); // FIFO order. - ASSERT_EQ(order.size(), 14); + ASSERT_EQ(14U, order.size()); EXPECT_EQ(order[ 0], TaskItem(RECURSIVE, 1, true)); EXPECT_EQ(order[ 1], TaskItem(RECURSIVE, 1, false)); EXPECT_EQ(order[ 2], TaskItem(RECURSIVE, 2, true)); @@ -728,7 +746,7 @@ TEST(MessageLoop, NonNestableWithNoNesting) { MessageLoop::current()->Run(); // FIFO order. - ASSERT_EQ(order.size(), 6); + ASSERT_EQ(6U, order.size()); EXPECT_EQ(order[ 0], TaskItem(ORDERERD, 1, true)); EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 1, false)); EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 2, true)); @@ -756,7 +774,7 @@ TEST(MessageLoop, NonNestableInNestedLoop) { MessageLoop::current()->Run(); // FIFO order. - ASSERT_EQ(order.size(), 10); + ASSERT_EQ(10U, order.size()); EXPECT_EQ(order[ 0], TaskItem(PUMPS, 1, true)); EXPECT_EQ(order[ 1], TaskItem(ORDERERD, 3, true)); EXPECT_EQ(order[ 2], TaskItem(ORDERERD, 3, false)); diff --git a/base/message_pump.h b/base/message_pump.h index 90336df..a06a435 100644 --- a/base/message_pump.h +++ b/base/message_pump.h @@ -42,6 +42,8 @@ class MessagePump : public RefCountedThreadSafe<MessagePump> { // these delegate methods are used. class Delegate { public: + virtual ~Delegate() {} + // Called from within Run in response to ScheduleWork or when the message // pump would otherwise call DoDelayedWork. Returns true to indicate that // work was done. DoDelayedWork will not be called if DoWork returns true. diff --git a/base/message_pump_default.cc b/base/message_pump_default.cc new file mode 100644 index 0000000..916d035 --- /dev/null +++ b/base/message_pump_default.cc @@ -0,0 +1,100 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "base/message_pump_default.h" + +#include "base/logging.h" +#include "base/time.h" + +namespace base { + +MessagePumpDefault::MessagePumpDefault() + : keep_running_(true), + event_(false, false) { +} + +void MessagePumpDefault::Run(Delegate* delegate) { + DCHECK(keep_running_) << "Quit must have been called outside of Run!"; + + for (;;) { + bool did_work = delegate->DoWork(); + if (!keep_running_) + break; + if (did_work) + continue; + + // TODO(darin): Delayed work will be starved if DoWork continues to return + // true. We should devise a better strategy. + + TimeDelta delay; + did_work = delegate->DoDelayedWork(&delay); + if (!keep_running_) + break; + if (did_work) + continue; + + did_work = delegate->DoIdleWork(); + if (!keep_running_) + break; + if (did_work) + continue; + // When DoIdleWork does not work, we also assume that it ran very quickly + // such that |delay| still properly indicates how long we are to sleep. + + if (delay < TimeDelta::FromMilliseconds(0)) { + event_.Wait(); + } else { + event_.TimedWait(delay); + } + // Since event_ is auto-reset, we don't need to do anything special here + // other than service each delegate method. + } + + keep_running_ = true; +} + +void MessagePumpDefault::Quit() { + keep_running_ = false; +} + +void MessagePumpDefault::ScheduleWork() { + // Since this can be called on any thread, we need to ensure that our Run + // loop wakes up. + event_.Signal(); +} + +void MessagePumpDefault::ScheduleDelayedWork(const TimeDelta& delay) { + // We know that we can't be blocked on Wait right now since this method can + // only be called on the same thread as Run, but to ensure that when we do + // sleep, we sleep for the right time, we signal the event to cause the Run + // loop to do one more iteration. + event_.Signal(); +} + +} // namespace base diff --git a/base/message_pump_default.h b/base/message_pump_default.h new file mode 100644 index 0000000..1c1af71 --- /dev/null +++ b/base/message_pump_default.h @@ -0,0 +1,122 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef BASE_MESSAGE_PUMP_DEFAULT_H_ +#define BASE_MESSAGE_PUMP_DEFAULT_H_ + +#include "base/message_pump.h" +#include "base/waitable_event.h" + +namespace base { + +class MessagePumpDefault : public MessagePump { + public: + MessagePumpDefault(); + ~MessagePumpDefault() {} + + // MessagePump methods: + virtual void Run(Delegate* delegate); + virtual void Quit(); + virtual void ScheduleWork(); + virtual void ScheduleDelayedWork(const TimeDelta& delay); + + private: + // This flag is set to false when Run should return. + bool keep_running_; + + // Used to sleep until there is more work to do. + WaitableEvent event_; + + DISALLOW_COPY_AND_ASSIGN(MessagePumpDefault); +}; + +} // namespace base + +#endif // BASE_MESSAGE_PUMP_DEFAULT_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef BASE_MESSAGE_PUMP_DEFAULT_H_ +#define BASE_MESSAGE_PUMP_DEFAULT_H_ + +#include "base/message_pump.h" +#include "base/waitable_event.h" + +namespace base { + +class MessagePumpDefault : public MessagePump { + public: + MessagePumpDefault(); + ~MessagePumpDefault() {} + + // MessagePump methods: + virtual void Run(Delegate* delegate); + virtual void Quit(); + virtual void ScheduleWork(); + virtual void ScheduleDelayedWork(const TimeDelta& delay); + + private: + // This flag is set to false when Run should return. + bool keep_running_; + + // Used to sleep until there is more work to do. + WaitableEvent event_; + + DISALLOW_COPY_AND_ASSIGN(MessagePumpDefault); +}; + +} // namespace base + +#endif // BASE_MESSAGE_PUMP_DEFAULT_H_ diff --git a/base/task.h b/base/task.h index 3a5c3cf..0988be5 100644 --- a/base/task.h +++ b/base/task.h @@ -45,10 +45,10 @@ class Task; -class MessageLoopOwnable : public tracked_objects::Tracked { +class TaskBase : public tracked_objects::Tracked { public: - MessageLoopOwnable() { Reset(); } - virtual ~MessageLoopOwnable() {} + TaskBase() { Reset(); } + virtual ~TaskBase() {} // Use this method to adjust the priority given to a task by MessageLoop. void set_priority(int priority) { priority_ = priority; } @@ -58,6 +58,9 @@ class MessageLoopOwnable : public tracked_objects::Tracked { void set_nestable(bool nestable) { nestable_ = nestable; } bool nestable() { return nestable_; } + // Used to manage a linked-list of tasks. + Task* next_task() const { return next_task_; } + void set_next_task(Task* next) { next_task_ = next; } protected: // If a derived class wishes to re-use this instance, then it should override @@ -86,9 +89,6 @@ class MessageLoopOwnable : public tracked_objects::Tracked { bool is_owned_by_message_loop() const { return 0 <= posted_task_delay_; } void set_posted_task_delay(int delay) { posted_task_delay_ = delay; } - Task* next_task() const { return next_task_; } - void set_next_task(Task* next) { next_task_ = next; } - // Priority for execution by MessageLoop. 0 is default. Higher means run // sooner, and lower (including negative) means run less soon. int priority_; @@ -105,7 +105,7 @@ class MessageLoopOwnable : public tracked_objects::Tracked { // only in the top level message loop. bool nestable_; - DISALLOW_EVIL_CONSTRUCTORS(MessageLoopOwnable); + DISALLOW_COPY_AND_ASSIGN(TaskBase); }; @@ -114,7 +114,7 @@ class MessageLoopOwnable : public tracked_objects::Tracked { // A task is a generic runnable thingy, usually used for running code on a // different thread or for scheduling future tasks off of the message loop. -class Task : public MessageLoopOwnable { +class Task : public TaskBase { public: Task() {} virtual ~Task() {} diff --git a/base/test_suite.h b/base/test_suite.h index 2362f03..ccac5c5 100644 --- a/base/test_suite.h +++ b/base/test_suite.h @@ -36,21 +36,17 @@ #include "build/build_config.h" -#if defined(OS_WIN) -#include <windows.h> -#endif - #include "base/command_line.h" #include "base/debug_on_start.h" #include "base/icu_util.h" #include "base/logging.h" -#if defined(OS_WIN) -// TODO(pinkerton): re-enable this when MessageLoop can be included by -// non-windows platforms. #include "base/message_loop.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_WIN) +#include <windows.h> #include "base/multiprocess_test.h" #endif -#include "testing/gtest/include/gtest/gtest.h" class TestSuite { public: @@ -59,12 +55,10 @@ class TestSuite { } virtual ~TestSuite() { -#if defined(OS_WIN) // Flush any remaining messages. This ensures that any accumulated Task // objects get destroyed before we exit, which avoids noise in purify // leak-test results. message_loop_.RunAllPending(); -#endif } int Run() { @@ -125,9 +119,7 @@ class TestSuite { } CommandLine parsed_command_line_; -#if defined(OS_WIN) MessageLoop message_loop_; -#endif }; #endif // BASE_TEST_SUITE_H_ |