summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-19 18:36:23 +0000
committerdarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-19 18:36:23 +0000
commitb16ef312cb28582a1d324d20e4328afeef2c7538 (patch)
treebcbc40bbe3950501c888eab655f5070619ad1ac7
parent4880adb3346faa91feea9d8ecfecc4ef499bf7fc (diff)
downloadchromium_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
-rw-r--r--base/base.xcodeproj/project.pbxproj30
-rw-r--r--base/histogram.cc3
-rw-r--r--base/histogram.h3
-rw-r--r--base/histogram_test.cc30
-rw-r--r--base/logging.cc8
-rw-r--r--base/message_loop.cc8
-rw-r--r--base/message_loop_unittest.cc36
-rw-r--r--base/message_pump.h2
-rw-r--r--base/message_pump_default.cc100
-rw-r--r--base/message_pump_default.h122
-rw-r--r--base/task.h16
-rw-r--r--base/test_suite.h16
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_