Merge from Chromium at DEPS revision r213057
This commit was generated by merge_to_master.py.
Change-Id: I3e2e2506eb9b0080157e9c5f133559df3e600388
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp
index 4febed2..ef98d09 100644
--- a/base/allocator/allocator.gyp
+++ b/base/allocator/allocator.gyp
@@ -429,6 +429,11 @@
'-Wl,-u_ZN15HeapLeakChecker12IgnoreObjectEPKv,-u_ZN15HeapLeakChecker14UnIgnoreObjectEPKv',
]},
}],
+ # Need to distinguish a non-SDK build for Android WebView
+ # due to differences in C include files.
+ ['OS=="android" and android_webview_build==1', {
+ 'defines': ['ANDROID_NON_SDK_BUILD'],
+ }],
[ 'use_vtable_verify==1', {
'cflags': [
'-fvtable-verify=preinit',
diff --git a/base/base.gyp b/base/base.gyp
index e4db68d..58543eb 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -556,11 +556,11 @@
'prefs/pref_service_unittest.cc',
'prefs/pref_value_map_unittest.cc',
'prefs/pref_value_store_unittest.cc',
- 'process_util_unittest.cc',
- 'process_util_unittest_ios.cc',
'process/memory_unittest.cc',
'process/memory_unittest_mac.h',
'process/memory_unittest_mac.mm',
+ 'process/process_util_unittest.cc',
+ 'process/process_util_unittest_ios.cc',
'profiler/tracked_time_unittest.cc',
'rand_util_unittest.cc',
'safe_numerics_unittest.cc',
@@ -570,6 +570,7 @@
'scoped_observer.h',
'security_unittest.cc',
'sequence_checker_unittest.cc',
+ 'sequence_checker_impl_unittest.cc',
'sha1_unittest.cc',
'stl_util_unittest.cc',
'strings/nullable_string16_unittest.cc',
@@ -618,6 +619,7 @@
'tools_sanity_unittest.cc',
'tracked_objects_unittest.cc',
'tuple_unittest.cc',
+ 'upload_list_unittest.cc',
'values_unittest.cc',
'version_unittest.cc',
'vlog_unittest.cc',
@@ -683,9 +685,9 @@
['OS == "ios" and _toolset != "host"', {
'sources/': [
# Only test the iOS-meaningful portion of process_utils.
- ['exclude', '^process_util_unittest\\.cc$'],
['exclude', '^process/memory_unittest'],
- ['include', '^process_util_unittest_ios\\.cc$'],
+ ['exclude', '^process/process_util_unittest\\.cc$'],
+ ['include', '^process/process_util_unittest_ios\\.cc$'],
# Requires spawning processes.
['exclude', '^metrics/stats_table_unittest\\.cc$'],
# iOS does not use message_pump_libevent.
diff --git a/base/base.gypi b/base/base.gypi
index 63c2b93..7381bea 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -300,6 +300,8 @@
'memory/singleton.h',
'memory/weak_ptr.cc',
'memory/weak_ptr.h',
+ 'message_loop/incoming_task_queue.cc',
+ 'message_loop/incoming_task_queue.h',
'message_loop/message_loop.cc',
'message_loop/message_loop.h',
'message_loop/message_loop_proxy.cc',
@@ -379,14 +381,6 @@
'power_monitor/power_monitor_posix.cc',
'power_monitor/power_monitor_win.cc',
'power_monitor/power_observer.h',
- 'process.h',
- 'process_info.h',
- 'process_info_mac.cc',
- 'process_info_win.cc',
- 'process_linux.cc',
- 'process_posix.cc',
- 'process_util.h',
- 'process_win.cc',
'process/internal_linux.cc',
'process/internal_linux.h',
'process/kill.cc',
@@ -403,12 +397,16 @@
'process/memory_linux.cc',
'process/memory_mac.mm',
'process/memory_win.cc',
+ 'process/process.h',
'process/process_handle_freebsd.cc',
'process/process_handle_linux.cc',
'process/process_handle_mac.cc',
'process/process_handle_openbsd.cc',
'process/process_handle_posix.cc',
'process/process_handle_win.cc',
+ 'process/process_info.h',
+ 'process/process_info_mac.cc',
+ 'process/process_info_win.cc',
'process/process_iterator.cc',
'process/process_iterator.h',
'process/process_iterator_freebsd.cc',
@@ -416,6 +414,7 @@
'process/process_iterator_mac.cc',
'process/process_iterator_openbsd.cc',
'process/process_iterator_win.cc',
+ 'process/process_linux.cc',
'process/process_metrics.h',
'process/process_metrics_freebsd.cc',
'process/process_metrics_ios.cc',
@@ -424,6 +423,8 @@
'process/process_metrics_openbsd.cc',
'process/process_metrics_posix.cc',
'process/process_metrics_win.cc',
+ 'process/process_posix.cc',
+ 'process/process_win.cc',
'profiler/scoped_profile.cc',
'profiler/scoped_profile.h',
'profiler/alternate_timer.cc',
@@ -585,6 +586,8 @@
'tracking_info.cc',
'tracking_info.h',
'tuple.h',
+ 'upload_list.cc',
+ 'upload_list.h',
'values.cc',
'values.h',
'value_conversions.cc',
@@ -701,9 +704,9 @@
'path_service.cc',
'posix/unix_domain_socket_linux.cc',
'process/kill_posix.cc',
- 'process/process_metrics_posix.cc',
'process/launch_posix.cc',
- 'process_posix.cc',
+ 'process/process_metrics_posix.cc',
+ 'process/process_posix.cc',
'rand_util_posix.cc',
'scoped_native_library.cc',
'files/scoped_temp_dir.cc',
@@ -726,7 +729,6 @@
'sources/': [
['include', '^debug/proc_maps_linux\\.cc$'],
['include', '^files/file_path_watcher_linux\\.cc$'],
- ['include', '^process_util_linux\\.cc$'],
['include', '^process/memory_linux\\.cc$'],
['include', '^process/internal_linux\\.cc$'],
['include', '^process/process_handle_linux\\.cc$'],
@@ -766,14 +768,12 @@
['include', '^threading/platform_thread_mac\\.'],
['include', '^time/time_mac\\.'],
['include', '^worker_pool_mac\\.'],
- # Exclude all process_util except the minimal implementation
+ # Exclude all process/ except the minimal implementation
# needed on iOS (mostly for unit tests).
- ['exclude', '^process_util'],
- ['include', '^process_util_ios\\.mm$'],
- ['exclude', '^process/launch_posix\\.cc$'],
- ['exclude', '^process/launch_mac\\.cc$'],
- ['exclude', '^process/memory_mac\\.mm$'],
- ['include', '^process/process_handle_posix\\.cc$'],
+ ['exclude', '^process/.*'],
+ ['include', '^process/.*_ios\.(cc|mm)$'],
+ ['include', '^process/memory_stubs\.cc$'],
+ ['include', '^process/process_handle_posix\.cc$'],
],
'sources': [
'process/memory_stubs.cc',
@@ -858,8 +858,7 @@
['exclude', '^files/file_path_watcher_linux\\.cc$'],
['exclude', '^files/file_path_watcher_stub\\.cc$'],
['exclude', '^file_util_linux\\.cc$'],
- ['exclude', '^process_linux\\.cc$'],
- ['exclude', '^process_util_linux\\.cc$'],
+ ['exclude', '^process/process_linux\\.cc$'],
['exclude', '^sys_info_linux\\.cc$'],
],
}],
diff --git a/base/base.target.darwin-arm.mk b/base/base.target.darwin-arm.mk
index 41fc09f..5cba75a 100644
--- a/base/base.target.darwin-arm.mk
+++ b/base/base.target.darwin-arm.mk
@@ -115,6 +115,7 @@
base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/incoming_task_queue.cc \
base/message_loop/message_loop.cc \
base/message_loop/message_loop_proxy.cc \
base/message_loop/message_loop_proxy_impl.cc \
@@ -142,7 +143,6 @@
base/posix/unix_domain_socket_linux.cc \
base/power_monitor/power_monitor.cc \
base/power_monitor/power_monitor_android.cc \
- base/process_posix.cc \
base/process/internal_linux.cc \
base/process/kill.cc \
base/process/kill_posix.cc \
@@ -154,6 +154,7 @@
base/process/process_iterator_linux.cc \
base/process/process_metrics_linux.cc \
base/process/process_metrics_posix.cc \
+ base/process/process_posix.cc \
base/profiler/scoped_profile.cc \
base/profiler/alternate_timer.cc \
base/profiler/tracked_time.cc \
@@ -218,6 +219,7 @@
base/timer/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
+ base/upload_list.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
diff --git a/base/base.target.darwin-mips.mk b/base/base.target.darwin-mips.mk
index 31b6412..ad8477e 100644
--- a/base/base.target.darwin-mips.mk
+++ b/base/base.target.darwin-mips.mk
@@ -115,6 +115,7 @@
base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/incoming_task_queue.cc \
base/message_loop/message_loop.cc \
base/message_loop/message_loop_proxy.cc \
base/message_loop/message_loop_proxy_impl.cc \
@@ -142,7 +143,6 @@
base/posix/unix_domain_socket_linux.cc \
base/power_monitor/power_monitor.cc \
base/power_monitor/power_monitor_android.cc \
- base/process_posix.cc \
base/process/internal_linux.cc \
base/process/kill.cc \
base/process/kill_posix.cc \
@@ -154,6 +154,7 @@
base/process/process_iterator_linux.cc \
base/process/process_metrics_linux.cc \
base/process/process_metrics_posix.cc \
+ base/process/process_posix.cc \
base/profiler/scoped_profile.cc \
base/profiler/alternate_timer.cc \
base/profiler/tracked_time.cc \
@@ -218,6 +219,7 @@
base/timer/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
+ base/upload_list.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
diff --git a/base/base.target.darwin-x86.mk b/base/base.target.darwin-x86.mk
index f1adb45..d274224 100644
--- a/base/base.target.darwin-x86.mk
+++ b/base/base.target.darwin-x86.mk
@@ -116,6 +116,7 @@
base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/incoming_task_queue.cc \
base/message_loop/message_loop.cc \
base/message_loop/message_loop_proxy.cc \
base/message_loop/message_loop_proxy_impl.cc \
@@ -143,7 +144,6 @@
base/posix/unix_domain_socket_linux.cc \
base/power_monitor/power_monitor.cc \
base/power_monitor/power_monitor_android.cc \
- base/process_posix.cc \
base/process/internal_linux.cc \
base/process/kill.cc \
base/process/kill_posix.cc \
@@ -155,6 +155,7 @@
base/process/process_iterator_linux.cc \
base/process/process_metrics_linux.cc \
base/process/process_metrics_posix.cc \
+ base/process/process_posix.cc \
base/profiler/scoped_profile.cc \
base/profiler/alternate_timer.cc \
base/profiler/tracked_time.cc \
@@ -219,6 +220,7 @@
base/timer/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
+ base/upload_list.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
diff --git a/base/base.target.linux-arm.mk b/base/base.target.linux-arm.mk
index 41fc09f..5cba75a 100644
--- a/base/base.target.linux-arm.mk
+++ b/base/base.target.linux-arm.mk
@@ -115,6 +115,7 @@
base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/incoming_task_queue.cc \
base/message_loop/message_loop.cc \
base/message_loop/message_loop_proxy.cc \
base/message_loop/message_loop_proxy_impl.cc \
@@ -142,7 +143,6 @@
base/posix/unix_domain_socket_linux.cc \
base/power_monitor/power_monitor.cc \
base/power_monitor/power_monitor_android.cc \
- base/process_posix.cc \
base/process/internal_linux.cc \
base/process/kill.cc \
base/process/kill_posix.cc \
@@ -154,6 +154,7 @@
base/process/process_iterator_linux.cc \
base/process/process_metrics_linux.cc \
base/process/process_metrics_posix.cc \
+ base/process/process_posix.cc \
base/profiler/scoped_profile.cc \
base/profiler/alternate_timer.cc \
base/profiler/tracked_time.cc \
@@ -218,6 +219,7 @@
base/timer/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
+ base/upload_list.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
diff --git a/base/base.target.linux-mips.mk b/base/base.target.linux-mips.mk
index 31b6412..ad8477e 100644
--- a/base/base.target.linux-mips.mk
+++ b/base/base.target.linux-mips.mk
@@ -115,6 +115,7 @@
base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/incoming_task_queue.cc \
base/message_loop/message_loop.cc \
base/message_loop/message_loop_proxy.cc \
base/message_loop/message_loop_proxy_impl.cc \
@@ -142,7 +143,6 @@
base/posix/unix_domain_socket_linux.cc \
base/power_monitor/power_monitor.cc \
base/power_monitor/power_monitor_android.cc \
- base/process_posix.cc \
base/process/internal_linux.cc \
base/process/kill.cc \
base/process/kill_posix.cc \
@@ -154,6 +154,7 @@
base/process/process_iterator_linux.cc \
base/process/process_metrics_linux.cc \
base/process/process_metrics_posix.cc \
+ base/process/process_posix.cc \
base/profiler/scoped_profile.cc \
base/profiler/alternate_timer.cc \
base/profiler/tracked_time.cc \
@@ -218,6 +219,7 @@
base/timer/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
+ base/upload_list.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
diff --git a/base/base.target.linux-x86.mk b/base/base.target.linux-x86.mk
index f1adb45..d274224 100644
--- a/base/base.target.linux-x86.mk
+++ b/base/base.target.linux-x86.mk
@@ -116,6 +116,7 @@
base/memory/shared_memory_posix.cc \
base/memory/singleton.cc \
base/memory/weak_ptr.cc \
+ base/message_loop/incoming_task_queue.cc \
base/message_loop/message_loop.cc \
base/message_loop/message_loop_proxy.cc \
base/message_loop/message_loop_proxy_impl.cc \
@@ -143,7 +144,6 @@
base/posix/unix_domain_socket_linux.cc \
base/power_monitor/power_monitor.cc \
base/power_monitor/power_monitor_android.cc \
- base/process_posix.cc \
base/process/internal_linux.cc \
base/process/kill.cc \
base/process/kill_posix.cc \
@@ -155,6 +155,7 @@
base/process/process_iterator_linux.cc \
base/process/process_metrics_linux.cc \
base/process/process_metrics_posix.cc \
+ base/process/process_posix.cc \
base/profiler/scoped_profile.cc \
base/profiler/alternate_timer.cc \
base/profiler/tracked_time.cc \
@@ -219,6 +220,7 @@
base/timer/timer.cc \
base/tracked_objects.cc \
base/tracking_info.cc \
+ base/upload_list.cc \
base/values.cc \
base/value_conversions.cc \
base/version.cc \
diff --git a/base/base_switches.cc b/base/base_switches.cc
index f0ac32b..bdd7b62 100644
--- a/base/base_switches.cc
+++ b/base/base_switches.cc
@@ -49,4 +49,12 @@
// Sends a pretty-printed version of tracing info to the console.
const char kTraceToConsole[] = "trace-to-console";
+#if defined(OS_POSIX)
+// A flag, generated internally for renderer and other helper process command
+// lines on Linux and Mac. It tells the helper process to enable crash dumping
+// and reporting, because helpers cannot access the files needed to make this
+// decision.
+const char kEnableCrashReporter[] = "enable-crash-reporter";
+#endif
+
} // namespace switches
diff --git a/base/base_switches.h b/base/base_switches.h
index 464493a..7686e76 100644
--- a/base/base_switches.h
+++ b/base/base_switches.h
@@ -7,6 +7,8 @@
#ifndef BASE_BASE_SWITCHES_H_
#define BASE_BASE_SWITCHES_H_
+#include "build/build_config.h"
+
namespace switches {
extern const char kDebugOnStart[];
@@ -20,6 +22,10 @@
extern const char kWaitForDebugger[];
extern const char kTraceToConsole[];
+#if defined(OS_POSIX)
+extern const char kEnableCrashReporter[];
+#endif
+
} // namespace switches
#endif // BASE_BASE_SWITCHES_H_
diff --git a/base/cancelable_callback.h b/base/cancelable_callback.h
index 1cfcf2b..8ef0199 100644
--- a/base/cancelable_callback.h
+++ b/base/cancelable_callback.h
@@ -195,6 +195,76 @@
DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
};
+template <typename A1, typename A2>
+class CancelableCallback<void(A1, A2)> {
+ public:
+ CancelableCallback() : weak_factory_(this) {}
+
+ // |callback| must not be null.
+ explicit CancelableCallback(const base::Callback<void(A1, A2)>& callback)
+ : weak_factory_(this),
+ callback_(callback) {
+ DCHECK(!callback.is_null());
+ InitializeForwarder();
+ }
+
+ ~CancelableCallback() {}
+
+ // Cancels and drops the reference to the wrapped callback.
+ void Cancel() {
+ weak_factory_.InvalidateWeakPtrs();
+ forwarder_.Reset();
+ callback_.Reset();
+ }
+
+ // Returns true if the wrapped callback has been cancelled.
+ bool IsCancelled() const {
+ return callback_.is_null();
+ }
+
+ // Sets |callback| as the closure that may be cancelled. |callback| may not
+ // be null. Outstanding and any previously wrapped callbacks are cancelled.
+ void Reset(const base::Callback<void(A1, A2)>& callback) {
+ DCHECK(!callback.is_null());
+
+ // Outstanding tasks (e.g., posted to a message loop) must not be called.
+ Cancel();
+
+ // |forwarder_| is no longer valid after Cancel(), so re-bind.
+ InitializeForwarder();
+
+ callback_ = callback;
+ }
+
+ // Returns a callback that can be disabled by calling Cancel().
+ const base::Callback<void(A1, A2)>& callback() const {
+ return forwarder_;
+ }
+
+ private:
+ void Forward(A1 a1, A2 a2) const {
+ callback_.Run(a1, a2);
+ }
+
+ // Helper method to bind |forwarder_| using a weak pointer from
+ // |weak_factory_|.
+ void InitializeForwarder() {
+ forwarder_ = base::Bind(&CancelableCallback<void(A1, A2)>::Forward,
+ weak_factory_.GetWeakPtr());
+ }
+
+ // Used to ensure Forward() is not run when this object is destroyed.
+ base::WeakPtrFactory<CancelableCallback<void(A1, A2)> > weak_factory_;
+
+ // The wrapper closure.
+ base::Callback<void(A1, A2)> forwarder_;
+
+ // The stored closure that may be cancelled.
+ base::Callback<void(A1, A2)> callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
+};
+
typedef CancelableCallback<void(void)> CancelableClosure;
} // namespace base
diff --git a/base/cancelable_callback_unittest.cc b/base/cancelable_callback_unittest.cc
index 9a2ba65..89c603c 100644
--- a/base/cancelable_callback_unittest.cc
+++ b/base/cancelable_callback_unittest.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/cpu.cc b/base/cpu.cc
index 4a94af0..1761529 100644
--- a/base/cpu.cc
+++ b/base/cpu.cc
@@ -19,7 +19,8 @@
namespace base {
CPU::CPU()
- : type_(0),
+ : signature_(0),
+ type_(0),
family_(0),
model_(0),
stepping_(0),
@@ -105,6 +106,7 @@
// Interpret CPU feature information.
if (num_ids > 0) {
__cpuid(cpu_info, 1);
+ signature_ = cpu_info[0];
stepping_ = cpu_info[0] & 0xf;
model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0);
family_ = (cpu_info[0] >> 8) & 0xf;
diff --git a/base/cpu.h b/base/cpu.h
index 1d45258..509763e 100644
--- a/base/cpu.h
+++ b/base/cpu.h
@@ -31,6 +31,7 @@
// Accessors for CPU information.
const std::string& vendor_name() const { return cpu_vendor_; }
+ int signature() const { return signature_; }
int stepping() const { return stepping_; }
int model() const { return model_; }
int family() const { return family_; }
@@ -55,6 +56,7 @@
// Query the processor for CPUID information.
void Initialize();
+ int signature_; // raw form of type, family, model, and stepping
int type_; // process type
int family_; // family of the processor
int model_; // model of processor
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h
index 619b0ab..c17c008 100644
--- a/base/debug/trace_event.h
+++ b/base/debug/trace_event.h
@@ -788,8 +788,6 @@
// Defines visibility for classes in trace_event.h
#define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT
-// Not supported in split-dll build. http://crbug.com/256965
-#if !defined(CHROME_SPLIT_DLL)
// The thread buckets for the sampling profiler.
TRACE_EVENT_API_CLASS_EXPORT extern \
TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3];
@@ -797,8 +795,6 @@
#define TRACE_EVENT_API_THREAD_BUCKET(thread_bucket) \
g_trace_state[thread_bucket]
-#endif
-
////////////////////////////////////////////////////////////////////////////////
// Implementation detail: trace event macros create temporary variables
@@ -1489,23 +1485,15 @@
}
static inline const char* Current() {
-// Not supported in split-dll build. http://crbug.com/256965
-#if !defined(CHROME_SPLIT_DLL)
return reinterpret_cast<const char*>(TRACE_EVENT_API_ATOMIC_LOAD(
g_trace_state[BucketNumber]));
-#else
- return NULL;
-#endif
}
static inline void Set(const char* category_and_name) {
-// Not supported in split-dll build. http://crbug.com/256965
-#if !defined(CHROME_SPLIT_DLL)
TRACE_EVENT_API_ATOMIC_STORE(
g_trace_state[BucketNumber],
reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(
const_cast<char*>(category_and_name)));
-#endif
}
private:
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc
index 4d637cd..e061ea1 100644
--- a/base/debug/trace_event_impl.cc
+++ b/base/debug/trace_event_impl.cc
@@ -42,11 +42,8 @@
}
};
-// Not supported in split-dll build. http://crbug.com/237249
-#if !defined(CHROME_SPLIT_DLL)
// The thread buckets for the sampling profiler.
BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3];
-#endif
namespace base {
namespace debug {
@@ -981,8 +978,6 @@
category_filter_ = CategoryFilter(category_filter);
EnableIncludedCategoryGroups();
- // Not supported in split-dll build. http://crbug.com/237249
- #if !defined(CHROME_SPLIT_DLL)
if (options & ENABLE_SAMPLING) {
sampling_thread_.reset(new TraceSamplingThread);
sampling_thread_->RegisterSampleBucket(
@@ -1002,7 +997,6 @@
DCHECK(false) << "failed to create thread";
}
}
- #endif
dispatching_to_observer_list_ = true;
observer_list = enabled_state_observer_list_;
diff --git a/base/debug/trace_event_unittest.cc b/base/debug/trace_event_unittest.cc
index ff0ab63..348c1d0 100644
--- a/base/debug/trace_event_unittest.cc
+++ b/base/debug/trace_event_unittest.cc
@@ -1677,8 +1677,6 @@
"record-continuously,enable-sampling"));
}
-// Not supported in split dll build. http://crbug.com/256965
-#if !defined(CHROME_SPLIT_DLL)
TEST_F(TraceEventTestFixture, TraceSampling) {
event_watch_notification_ = 0;
TraceLog::GetInstance()->SetEnabled(
@@ -1738,7 +1736,6 @@
EndTraceAndFlush();
}
-#endif // !CHROME_SPLIT_DLL
class MyData : public base::debug::ConvertableToTraceFormat {
public:
diff --git a/base/deferred_sequenced_task_runner_unittest.cc b/base/deferred_sequenced_task_runner_unittest.cc
index e0139b6..81f2a0a 100644
--- a/base/deferred_sequenced_task_runner_unittest.cc
+++ b/base/deferred_sequenced_task_runner_unittest.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/non_thread_safe.h"
#include "base/threading/thread.h"
diff --git a/base/files/file_path_watcher.cc b/base/files/file_path_watcher.cc
index f1a6cbb..49e0a23 100644
--- a/base/files/file_path_watcher.cc
+++ b/base/files/file_path_watcher.cc
@@ -8,7 +8,7 @@
#include "base/files/file_path_watcher.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
namespace base {
diff --git a/base/files/file_path_watcher_browsertest.cc b/base/files/file_path_watcher_browsertest.cc
index da95909..69ff806 100644
--- a/base/files/file_path_watcher_browsertest.cc
+++ b/base/files/file_path_watcher_browsertest.cc
@@ -20,7 +20,7 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
diff --git a/base/files/file_path_watcher_kqueue.cc b/base/files/file_path_watcher_kqueue.cc
index be29fa8..2ffb836 100644
--- a/base/files/file_path_watcher_kqueue.cc
+++ b/base/files/file_path_watcher_kqueue.cc
@@ -13,7 +13,7 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/stringprintf.h"
diff --git a/base/files/file_path_watcher_linux.cc b/base/files/file_path_watcher_linux.cc
index b9270ee..86a4226 100644
--- a/base/files/file_path_watcher_linux.cc
+++ b/base/files/file_path_watcher_linux.cc
@@ -24,7 +24,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/posix/eintr_wrapper.h"
#include "base/synchronization/lock.h"
diff --git a/base/files/file_util_proxy_unittest.cc b/base/files/file_util_proxy_unittest.cc
index a454c57..3c67075 100644
--- a/base/files/file_util_proxy_unittest.cc
+++ b/base/files/file_util_proxy_unittest.cc
@@ -11,7 +11,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/platform_file.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/files/important_file_writer_unittest.cc b/base/files/important_file_writer_unittest.cc
index 3f24d10..e8f3d12 100644
--- a/base/files/important_file_writer_unittest.cc
+++ b/base/files/important_file_writer_unittest.cc
@@ -9,7 +9,7 @@
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
diff --git a/base/float_util.h b/base/float_util.h
index 458e859..9027310 100644
--- a/base/float_util.h
+++ b/base/float_util.h
@@ -13,7 +13,8 @@
namespace base {
-inline bool IsFinite(const double& number) {
+template <typename Float>
+inline bool IsFinite(const Float& number) {
#if defined(OS_POSIX)
return std::isfinite(number) != 0;
#elif defined(OS_WIN)
@@ -21,6 +22,15 @@
#endif
}
+template <typename Float>
+inline bool IsNaN(const Float& number) {
+#if defined(OS_POSIX)
+ return std::isnan(number) != 0;
+#elif defined(OS_WIN)
+ return _isnan(number) != 0;
+#endif
+}
+
} // namespace base
#endif // BASE_FLOAT_UTIL_H_
diff --git a/base/i18n/bidi_line_iterator.h b/base/i18n/bidi_line_iterator.h
index e632d5e..d5a2a07 100644
--- a/base/i18n/bidi_line_iterator.h
+++ b/base/i18n/bidi_line_iterator.h
@@ -8,7 +8,7 @@
#include "base/basictypes.h"
#include "base/i18n/base_i18n_export.h"
#include "base/strings/string16.h"
-#include "third_party/icu/public/common/unicode/ubidi.h"
+#include "third_party/icu/source/common/unicode/ubidi.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/break_iterator.cc b/base/i18n/break_iterator.cc
index c4ea52c..2c4d466 100644
--- a/base/i18n/break_iterator.cc
+++ b/base/i18n/break_iterator.cc
@@ -5,9 +5,9 @@
#include "base/i18n/break_iterator.h"
#include "base/logging.h"
-#include "third_party/icu/public/common/unicode/ubrk.h"
-#include "third_party/icu/public/common/unicode/uchar.h"
-#include "third_party/icu/public/common/unicode/ustring.h"
+#include "third_party/icu/source/common/unicode/ubrk.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/ustring.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/case_conversion.cc b/base/i18n/case_conversion.cc
index dcd7a55..5debc2e 100644
--- a/base/i18n/case_conversion.cc
+++ b/base/i18n/case_conversion.cc
@@ -5,7 +5,7 @@
#include "base/i18n/case_conversion.h"
#include "base/strings/string16.h"
-#include "third_party/icu/public/common/unicode/unistr.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/char_iterator.cc b/base/i18n/char_iterator.cc
index 0d5c3de..25efc51 100644
--- a/base/i18n/char_iterator.cc
+++ b/base/i18n/char_iterator.cc
@@ -4,8 +4,8 @@
#include "base/i18n/char_iterator.h"
-#include "third_party/icu/public/common/unicode/utf8.h"
-#include "third_party/icu/public/common/unicode/utf16.h"
+#include "third_party/icu/source/common/unicode/utf8.h"
+#include "third_party/icu/source/common/unicode/utf16.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/file_util_icu.cc b/base/i18n/file_util_icu.cc
index ebb7e01..4b2ca3a 100644
--- a/base/i18n/file_util_icu.cc
+++ b/base/i18n/file_util_icu.cc
@@ -16,8 +16,8 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
-#include "third_party/icu/public/common/unicode/uniset.h"
-#include "third_party/icu/public/i18n/unicode/coll.h"
+#include "third_party/icu/source/common/unicode/uniset.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
namespace {
diff --git a/base/i18n/icu_encoding_detection.cc b/base/i18n/icu_encoding_detection.cc
index 257d839..ccd5cde 100644
--- a/base/i18n/icu_encoding_detection.cc
+++ b/base/i18n/icu_encoding_detection.cc
@@ -7,7 +7,7 @@
#include <set>
#include "base/strings/string_util.h"
-#include "third_party/icu/public/i18n/unicode/ucsdet.h"
+#include "third_party/icu/source/i18n/unicode/ucsdet.h"
namespace base {
diff --git a/base/i18n/icu_string_conversions.cc b/base/i18n/icu_string_conversions.cc
index 1517399..1530117 100644
--- a/base/i18n/icu_string_conversions.cc
+++ b/base/i18n/icu_string_conversions.cc
@@ -11,11 +11,11 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "third_party/icu/public/common/unicode/ucnv.h"
-#include "third_party/icu/public/common/unicode/ucnv_cb.h"
-#include "third_party/icu/public/common/unicode/ucnv_err.h"
-#include "third_party/icu/public/common/unicode/unorm.h"
-#include "third_party/icu/public/common/unicode/ustring.h"
+#include "third_party/icu/source/common/unicode/ucnv.h"
+#include "third_party/icu/source/common/unicode/ucnv_cb.h"
+#include "third_party/icu/source/common/unicode/ucnv_err.h"
+#include "third_party/icu/source/common/unicode/unorm.h"
+#include "third_party/icu/source/common/unicode/ustring.h"
namespace base {
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc
index d6feb1e..76016d0 100644
--- a/base/i18n/icu_util.cc
+++ b/base/i18n/icu_util.cc
@@ -18,8 +18,8 @@
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
-#include "third_party/icu/public/common/unicode/putil.h"
-#include "third_party/icu/public/common/unicode/udata.h"
+#include "third_party/icu/source/common/unicode/putil.h"
+#include "third_party/icu/source/common/unicode/udata.h"
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
diff --git a/base/i18n/number_formatting.cc b/base/i18n/number_formatting.cc
index 11044d8..47aa14c 100644
--- a/base/i18n/number_formatting.cc
+++ b/base/i18n/number_formatting.cc
@@ -11,8 +11,8 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "third_party/icu/public/common/unicode/ustring.h"
-#include "third_party/icu/public/i18n/unicode/numfmt.h"
+#include "third_party/icu/source/common/unicode/ustring.h"
+#include "third_party/icu/source/i18n/unicode/numfmt.h"
namespace base {
diff --git a/base/i18n/rtl.cc b/base/i18n/rtl.cc
index 92b5433..d9818e8 100644
--- a/base/i18n/rtl.cc
+++ b/base/i18n/rtl.cc
@@ -9,10 +9,10 @@
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "third_party/icu/public/common/unicode/locid.h"
-#include "third_party/icu/public/common/unicode/uchar.h"
-#include "third_party/icu/public/common/unicode/uscript.h"
-#include "third_party/icu/public/i18n/unicode/coll.h"
+#include "third_party/icu/source/common/unicode/locid.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/uscript.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
diff --git a/base/i18n/rtl_unittest.cc b/base/i18n/rtl_unittest.cc
index e947847..58772b0 100644
--- a/base/i18n/rtl_unittest.cc
+++ b/base/i18n/rtl_unittest.cc
@@ -12,7 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
-#include "third_party/icu/public/i18n/unicode/usearch.h"
+#include "third_party/icu/source/i18n/unicode/usearch.h"
#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
diff --git a/base/i18n/string_compare.h b/base/i18n/string_compare.h
index 307ffdb..f0f3e29 100644
--- a/base/i18n/string_compare.h
+++ b/base/i18n/string_compare.h
@@ -11,7 +11,7 @@
#include "base/i18n/base_i18n_export.h"
#include "base/strings/string16.h"
-#include "third_party/icu/public/i18n/unicode/coll.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/string_search.cc b/base/i18n/string_search.cc
index 17304b3..121dfce 100644
--- a/base/i18n/string_search.cc
+++ b/base/i18n/string_search.cc
@@ -5,7 +5,7 @@
#include "base/i18n/string_search.h"
#include "base/logging.h"
-#include "third_party/icu/public/i18n/unicode/usearch.h"
+#include "third_party/icu/source/i18n/unicode/usearch.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/string_search_unittest.cc b/base/i18n/string_search_unittest.cc
index d2bd53a..9419b26 100644
--- a/base/i18n/string_search_unittest.cc
+++ b/base/i18n/string_search_unittest.cc
@@ -9,7 +9,7 @@
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/public/i18n/unicode/usearch.h"
+#include "third_party/icu/source/i18n/unicode/usearch.h"
namespace base {
namespace i18n {
diff --git a/base/i18n/time_formatting.cc b/base/i18n/time_formatting.cc
index ca94ead..3973dd2 100644
--- a/base/i18n/time_formatting.cc
+++ b/base/i18n/time_formatting.cc
@@ -8,9 +8,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
-#include "third_party/icu/public/i18n/unicode/datefmt.h"
-#include "third_party/icu/public/i18n/unicode/dtptngen.h"
-#include "third_party/icu/public/i18n/unicode/smpdtfmt.h"
+#include "third_party/icu/source/i18n/unicode/datefmt.h"
+#include "third_party/icu/source/i18n/unicode/dtptngen.h"
+#include "third_party/icu/source/i18n/unicode/smpdtfmt.h"
using base::Time;
diff --git a/base/i18n/time_formatting_unittest.cc b/base/i18n/time_formatting_unittest.cc
index b6992eb..03a3aa3 100644
--- a/base/i18n/time_formatting_unittest.cc
+++ b/base/i18n/time_formatting_unittest.cc
@@ -8,7 +8,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/public/common/unicode/uversion.h"
+#include "third_party/icu/source/common/unicode/uversion.h"
namespace base {
namespace {
diff --git a/base/mac/libdispatch_task_runner_unittest.cc b/base/mac/libdispatch_task_runner_unittest.cc
index 4c0a2b6..a4f3202 100644
--- a/base/mac/libdispatch_task_runner_unittest.cc
+++ b/base/mac/libdispatch_task_runner_unittest.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/mac/bind_objc_block.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc
index d9ce86a..a22f61a 100644
--- a/base/memory/weak_ptr.cc
+++ b/base/memory/weak_ptr.cc
@@ -10,21 +10,21 @@
WeakReference::Flag::Flag() : is_valid_(true) {
// Flags only become bound when checked for validity, or invalidated,
// so that we can check that later validity/invalidation operations on
- // the same Flag take place on the same sequenced thread.
- sequence_checker_.DetachFromSequence();
+ // the same Flag take place on the same thread.
+ thread_checker_.DetachFromThread();
}
void WeakReference::Flag::Invalidate() {
// The flag being invalidated with a single ref implies that there are no
// weak pointers in existence. Allow deletion on other thread in this case.
- DCHECK(sequence_checker_.CalledOnValidSequencedThread() || HasOneRef())
- << "WeakPtrs must be invalidated on the same sequenced thread.";
+ DCHECK(thread_checker_.CalledOnValidThread() || HasOneRef())
+ << "WeakPtrs must be checked and invalidated on the same thread.";
is_valid_ = false;
}
bool WeakReference::Flag::IsValid() const {
- DCHECK(sequence_checker_.CalledOnValidSequencedThread())
- << "WeakPtrs must be checked on the same sequenced thread.";
+ DCHECK(thread_checker_.CalledOnValidThread())
+ << "WeakPtrs must be checked and invalidated on the same thread.";
return is_valid_;
}
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h
index b4120a1..621c0fa 100644
--- a/base/memory/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -67,8 +67,8 @@
#include "base/base_export.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
-#include "base/sequence_checker.h"
#include "base/template_util.h"
+#include "base/threading/thread_checker.h"
namespace base {
@@ -91,14 +91,14 @@
bool IsValid() const;
// Remove this when crbug.com/234964 is addressed.
- void DetachFromThreadHack() { sequence_checker_.DetachFromSequence(); }
+ void DetachFromThreadHack() { thread_checker_.DetachFromThread(); }
private:
friend class base::RefCountedThreadSafe<Flag>;
~Flag();
- SequenceChecker sequence_checker_;
+ ThreadChecker thread_checker_;
bool is_valid_;
};
diff --git a/base/memory/weak_ptr_unittest.cc b/base/memory/weak_ptr_unittest.cc
index 515df69..be3b6db 100644
--- a/base/memory/weak_ptr_unittest.cc
+++ b/base/memory/weak_ptr_unittest.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/debug/leak_annotations.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/message_loop.h b/base/message_loop.h
deleted file mode 100644
index 04e7e79..0000000
--- a/base/message_loop.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(brettw) remove this forwarding header when all callers have been
-// updatded.
-#include "base/message_loop/message_loop.h"
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc
new file mode 100644
index 0000000..db99d87
--- /dev/null
+++ b/base/message_loop/incoming_task_queue.cc
@@ -0,0 +1,169 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/message_loop/incoming_task_queue.h"
+
+#include "base/debug/trace_event.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop.h"
+#include "base/synchronization/waitable_event.h"
+
+namespace base {
+namespace internal {
+
+IncomingTaskQueue::IncomingTaskQueue(MessageLoop* message_loop)
+ : message_loop_(message_loop),
+ next_sequence_num_(0) {
+}
+
+bool IncomingTaskQueue::AddToIncomingQueue(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay,
+ bool nestable) {
+ AutoLock locked(incoming_queue_lock_);
+ PendingTask pending_task(
+ from_here, task, CalculateDelayedRuntime(delay), nestable);
+ return PostPendingTask(&pending_task);
+}
+
+bool IncomingTaskQueue::TryAddToIncomingQueue(
+ const tracked_objects::Location& from_here,
+ const Closure& task) {
+ if (!incoming_queue_lock_.Try()) {
+ // Reset |task|.
+ Closure local_task = task;
+ return false;
+ }
+
+ AutoLock locked(incoming_queue_lock_, AutoLock::AlreadyAcquired());
+ PendingTask pending_task(
+ from_here, task, CalculateDelayedRuntime(TimeDelta()), true);
+ return PostPendingTask(&pending_task);
+}
+
+bool IncomingTaskQueue::IsHighResolutionTimerEnabledForTesting() {
+#if defined(OS_WIN)
+ return !high_resolution_timer_expiration_.is_null();
+#else
+ return true;
+#endif
+}
+
+bool IncomingTaskQueue::IsIdleForTesting() {
+ AutoLock lock(incoming_queue_lock_);
+ return incoming_queue_.empty();
+}
+
+void IncomingTaskQueue::LockWaitUnLockForTesting(WaitableEvent* caller_wait,
+ WaitableEvent* caller_signal) {
+ AutoLock lock(incoming_queue_lock_);
+ caller_wait->Signal();
+ caller_signal->Wait();
+}
+
+void IncomingTaskQueue::ReloadWorkQueue(TaskQueue* work_queue) {
+ // Make sure no tasks are lost.
+ DCHECK(work_queue->empty());
+
+ // Acquire all we can from the inter-thread queue with one lock acquisition.
+ AutoLock lock(incoming_queue_lock_);
+ if (!incoming_queue_.empty())
+ incoming_queue_.Swap(work_queue); // Constant time
+
+ DCHECK(incoming_queue_.empty());
+}
+
+void IncomingTaskQueue::WillDestroyCurrentMessageLoop() {
+#if defined(OS_WIN)
+ // If we left the high-resolution timer activated, deactivate it now.
+ // Doing this is not-critical, it is mainly to make sure we track
+ // the high resolution timer activations properly in our unit tests.
+ if (!high_resolution_timer_expiration_.is_null()) {
+ Time::ActivateHighResolutionTimer(false);
+ high_resolution_timer_expiration_ = TimeTicks();
+ }
+#endif
+
+ AutoLock lock(incoming_queue_lock_);
+ message_loop_ = NULL;
+}
+
+IncomingTaskQueue::~IncomingTaskQueue() {
+ // Verify that WillDestroyCurrentMessageLoop() has been called.
+ DCHECK(!message_loop_);
+}
+
+TimeTicks IncomingTaskQueue::CalculateDelayedRuntime(TimeDelta delay) {
+ TimeTicks delayed_run_time;
+ if (delay > TimeDelta()) {
+ delayed_run_time = TimeTicks::Now() + delay;
+
+#if defined(OS_WIN)
+ if (high_resolution_timer_expiration_.is_null()) {
+ // Windows timers are granular to 15.6ms. If we only set high-res
+ // timers for those under 15.6ms, then a 18ms timer ticks at ~32ms,
+ // which as a percentage is pretty inaccurate. So enable high
+ // res timers for any timer which is within 2x of the granularity.
+ // This is a tradeoff between accuracy and power management.
+ bool needs_high_res_timers = delay.InMilliseconds() <
+ (2 * Time::kMinLowResolutionThresholdMs);
+ if (needs_high_res_timers) {
+ if (Time::ActivateHighResolutionTimer(true)) {
+ high_resolution_timer_expiration_ = TimeTicks::Now() +
+ TimeDelta::FromMilliseconds(
+ MessageLoop::kHighResolutionTimerModeLeaseTimeMs);
+ }
+ }
+ }
+#endif
+ } else {
+ DCHECK_EQ(delay.InMilliseconds(), 0) << "delay should not be negative";
+ }
+
+#if defined(OS_WIN)
+ if (!high_resolution_timer_expiration_.is_null()) {
+ if (TimeTicks::Now() > high_resolution_timer_expiration_) {
+ Time::ActivateHighResolutionTimer(false);
+ high_resolution_timer_expiration_ = TimeTicks();
+ }
+ }
+#endif
+
+ return delayed_run_time;
+}
+
+bool IncomingTaskQueue::PostPendingTask(PendingTask* pending_task) {
+ // Warning: Don't try to short-circuit, and handle this thread's tasks more
+ // directly, as it could starve handling of foreign threads. Put every task
+ // into this queue.
+
+ // This should only be called while the lock is taken.
+ incoming_queue_lock_.AssertAcquired();
+
+ if (!message_loop_) {
+ pending_task->task.Reset();
+ return false;
+ }
+
+ // Initialize the sequence number. The sequence number is used for delayed
+ // tasks (to faciliate FIFO sorting when two tasks have the same
+ // delayed_run_time value) and for identifying the task in about:tracing.
+ pending_task->sequence_num = next_sequence_num_++;
+
+ TRACE_EVENT_FLOW_BEGIN0("task", "MessageLoop::PostTask",
+ TRACE_ID_MANGLE(message_loop_->GetTaskTraceID(*pending_task)));
+
+ bool was_empty = incoming_queue_.empty();
+ incoming_queue_.push(*pending_task);
+ pending_task->task.Reset();
+
+ // Wake up the pump.
+ message_loop_->ScheduleWork(was_empty);
+
+ return true;
+}
+
+} // namespace internal
+} // namespace base
diff --git a/base/message_loop/incoming_task_queue.h b/base/message_loop/incoming_task_queue.h
new file mode 100644
index 0000000..d831a71
--- /dev/null
+++ b/base/message_loop/incoming_task_queue.h
@@ -0,0 +1,104 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MESSAGE_LOOP_INCOMING_TASK_QUEUE_H_
+#define BASE_MESSAGE_LOOP_INCOMING_TASK_QUEUE_H_
+
+#include "base/base_export.h"
+#include "base/memory/ref_counted.h"
+#include "base/pending_task.h"
+#include "base/synchronization/lock.h"
+#include "base/time/time.h"
+
+namespace base {
+
+class MessageLoop;
+class WaitableEvent;
+
+namespace internal {
+
+// Implements a queue of tasks posted to the message loop running on the current
+// thread. This class takes care of synchronizing posting tasks from different
+// threads and together with MessageLoop ensures clean shutdown.
+class BASE_EXPORT IncomingTaskQueue
+ : public RefCountedThreadSafe<IncomingTaskQueue> {
+ public:
+ explicit IncomingTaskQueue(MessageLoop* message_loop);
+
+ // Appends a task to the incoming queue. Posting of all tasks is routed though
+ // AddToIncomingQueue() or TryAddToIncomingQueue() to make sure that posting
+ // task is properly synchronized between different threads.
+ //
+ // Returns true if the task was successfully added to the queue, otherwise
+ // returns false. In all cases, the ownership of |task| is transferred to the
+ // called method.
+ bool AddToIncomingQueue(const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay,
+ bool nestable);
+
+ // Same as AddToIncomingQueue() except that it will avoid blocking if the lock
+ // is already held, and will in that case (when the lock is contended) fail to
+ // add the task, and will return false.
+ bool TryAddToIncomingQueue(const tracked_objects::Location& from_here,
+ const Closure& task);
+
+ // Returns true if the message loop has high resolution timers enabled.
+ // Provided for testing.
+ bool IsHighResolutionTimerEnabledForTesting();
+
+ // Returns true if the message loop is "idle". Provided for testing.
+ bool IsIdleForTesting();
+
+ // Takes the incoming queue lock, signals |caller_wait| and waits until
+ // |caller_signal| is signalled.
+ void LockWaitUnLockForTesting(WaitableEvent* caller_wait,
+ WaitableEvent* caller_signal);
+
+ // Loads tasks from the |incoming_queue_| into |*work_queue|. Must be called
+ // from the thread that is running the loop.
+ void ReloadWorkQueue(TaskQueue* work_queue);
+
+ // Disconnects |this| from the parent message loop.
+ void WillDestroyCurrentMessageLoop();
+
+ private:
+ friend class RefCountedThreadSafe<IncomingTaskQueue>;
+ virtual ~IncomingTaskQueue();
+
+ // Calculates the time at which a PendingTask should run.
+ TimeTicks CalculateDelayedRuntime(TimeDelta delay);
+
+ // Adds a task to |incoming_queue_|. The caller retains ownership of
+ // |pending_task|, but this function will reset the value of
+ // |pending_task->task|. This is needed to ensure that the posting call stack
+ // does not retain |pending_task->task| beyond this function call.
+ bool PostPendingTask(PendingTask* pending_task);
+
+#if defined(OS_WIN)
+ TimeTicks high_resolution_timer_expiration_;
+#endif
+
+ // The lock that protects access to |incoming_queue_|, |message_loop_| and
+ // |next_sequence_num_|.
+ base::Lock incoming_queue_lock_;
+
+ // An incoming queue of tasks that are acquired under a mutex for processing
+ // on this instance's thread. These tasks have not yet been been pushed to
+ // |message_loop_|.
+ TaskQueue incoming_queue_;
+
+ // Points to the message loop that owns |this|.
+ MessageLoop* message_loop_;
+
+ // The next sequence number to use for delayed tasks.
+ int next_sequence_num_;
+
+ DISALLOW_COPY_AND_ASSIGN(IncomingTaskQueue);
+};
+
+} // namespace internal
+} // namespace base
+
+#endif // BASE_MESSAGE_LOOP_INCOMING_TASK_QUEUE_H_
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index bd3542a..d2eafbd 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -13,7 +13,6 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/message_loop/message_pump_default.h"
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
@@ -89,14 +88,6 @@
MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL;
-// Create a process-wide unique ID to represent this task in trace events. This
-// will be mangled with a Process ID hash to reduce the likelyhood of colliding
-// with MessageLoop pointers on other processes.
-uint64 GetTaskTraceID(const PendingTask& task, MessageLoop* loop) {
- return (static_cast<uint64>(task.sequence_num) << 32) |
- static_cast<uint64>(reinterpret_cast<intptr_t>(loop));
-}
-
// Returns true if MessagePump::ScheduleWork() must be called one
// time for every task that is added to the MessageLoop incoming queue.
bool AlwaysNotifyPump(MessageLoop::Type type) {
@@ -146,18 +137,19 @@
MessageLoop::MessageLoop(Type type)
: type_(type),
- nestable_tasks_allowed_(true),
exception_restoration_(false),
- message_histogram_(NULL),
- run_loop_(NULL),
+ nestable_tasks_allowed_(true),
#if defined(OS_WIN)
os_modal_loop_(false),
#endif // OS_WIN
- next_sequence_num_(0) {
+ message_histogram_(NULL),
+ run_loop_(NULL) {
DCHECK(!current()) << "should only have one message loop per thread";
lazy_tls_ptr.Pointer()->Set(this);
- message_loop_proxy_ = new MessageLoopProxyImpl();
+ incoming_task_queue_ = new internal::IncomingTaskQueue(this);
+ message_loop_proxy_ =
+ new internal::MessageLoopProxyImpl(incoming_task_queue_);
thread_task_runner_handle_.reset(
new ThreadTaskRunnerHandle(message_loop_proxy_));
@@ -177,7 +169,7 @@
#define MESSAGE_PUMP_UI NULL
// ipc_channel_nacl.cc uses a worker thread to do socket reads currently, and
// doesn't require extra support for watching file descriptors.
-#define MESSAGE_PUMP_IO new MessagePumpDefault();
+#define MESSAGE_PUMP_IO new MessagePumpDefault()
#elif defined(OS_POSIX) // POSIX but not MACOSX.
#define MESSAGE_PUMP_UI new MessagePumpForUI()
#define MESSAGE_PUMP_IO new MessagePumpLibevent()
@@ -187,14 +179,14 @@
if (type_ == TYPE_UI) {
if (message_pump_for_ui_factory_)
- pump_ = message_pump_for_ui_factory_();
+ pump_.reset(message_pump_for_ui_factory_());
else
- pump_ = MESSAGE_PUMP_UI;
+ pump_.reset(MESSAGE_PUMP_UI);
} else if (type_ == TYPE_IO) {
- pump_ = MESSAGE_PUMP_IO;
+ pump_.reset(MESSAGE_PUMP_IO);
} else {
DCHECK_EQ(TYPE_DEFAULT, type_);
- pump_ = new MessagePumpDefault();
+ pump_.reset(new MessagePumpDefault());
}
}
@@ -226,23 +218,13 @@
thread_task_runner_handle_.reset();
- // Tell the message_loop_proxy that we are dying.
- static_cast<MessageLoopProxyImpl*>(message_loop_proxy_.get())->
- WillDestroyCurrentMessageLoop();
+ // Tell the incoming queue that we are dying.
+ incoming_task_queue_->WillDestroyCurrentMessageLoop();
+ incoming_task_queue_ = NULL;
message_loop_proxy_ = NULL;
// OK, now make it so that no one can find us.
lazy_tls_ptr.Pointer()->Set(NULL);
-
-#if defined(OS_WIN)
- // If we left the high-resolution timer activated, deactivate it now.
- // Doing this is not-critical, it is mainly to make sure we track
- // the high resolution timer activations properly in our unit tests.
- if (!high_resolution_timer_expiration_.is_null()) {
- Time::ActivateHighResolutionTimer(false);
- high_resolution_timer_expiration_ = TimeTicks();
- }
-#endif
}
// static
@@ -283,18 +265,14 @@
const tracked_objects::Location& from_here,
const Closure& task) {
DCHECK(!task.is_null()) << from_here.ToString();
- PendingTask pending_task(
- from_here, task, CalculateDelayedRuntime(TimeDelta()), true);
- AddToIncomingQueue(&pending_task, false);
+ incoming_task_queue_->AddToIncomingQueue(from_here, task, TimeDelta(), true);
}
bool MessageLoop::TryPostTask(
const tracked_objects::Location& from_here,
const Closure& task) {
DCHECK(!task.is_null()) << from_here.ToString();
- PendingTask pending_task(
- from_here, task, CalculateDelayedRuntime(TimeDelta()), true);
- return AddToIncomingQueue(&pending_task, true);
+ return incoming_task_queue_->TryAddToIncomingQueue(from_here, task);
}
void MessageLoop::PostDelayedTask(
@@ -302,18 +280,14 @@
const Closure& task,
TimeDelta delay) {
DCHECK(!task.is_null()) << from_here.ToString();
- PendingTask pending_task(
- from_here, task, CalculateDelayedRuntime(delay), true);
- AddToIncomingQueue(&pending_task, false);
+ incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, true);
}
void MessageLoop::PostNonNestableTask(
const tracked_objects::Location& from_here,
const Closure& task) {
DCHECK(!task.is_null()) << from_here.ToString();
- PendingTask pending_task(
- from_here, task, CalculateDelayedRuntime(TimeDelta()), false);
- AddToIncomingQueue(&pending_task, false);
+ incoming_task_queue_->AddToIncomingQueue(from_here, task, TimeDelta(), false);
}
void MessageLoop::PostNonNestableDelayedTask(
@@ -321,9 +295,7 @@
const Closure& task,
TimeDelta delay) {
DCHECK(!task.is_null()) << from_here.ToString();
- PendingTask pending_task(
- from_here, task, CalculateDelayedRuntime(delay), false);
- AddToIncomingQueue(&pending_task, false);
+ incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false);
}
void MessageLoop::Run() {
@@ -395,17 +367,26 @@
task_observers_.RemoveObserver(task_observer);
}
-void MessageLoop::AssertIdle() const {
- // We only check |incoming_queue_|, since we don't want to lock |work_queue_|.
- AutoLock lock(incoming_queue_lock_);
- DCHECK(incoming_queue_.empty());
-}
-
bool MessageLoop::is_running() const {
DCHECK_EQ(this, current());
return run_loop_ != NULL;
}
+bool MessageLoop::IsHighResolutionTimerEnabledForTesting() {
+ return incoming_task_queue_->IsHighResolutionTimerEnabledForTesting();
+}
+
+bool MessageLoop::IsIdleForTesting() {
+ // We only check the imcoming queue|, since we don't want to lock the work
+ // queue.
+ return incoming_task_queue_->IsIdleForTesting();
+}
+
+void MessageLoop::LockWaitUnLockForTesting(WaitableEvent* caller_wait,
+ WaitableEvent* caller_signal) {
+ incoming_task_queue_->LockWaitUnLockForTesting(caller_wait, caller_signal);
+}
+
//------------------------------------------------------------------------------
// Runs the loop in two different SEH modes:
@@ -470,7 +451,7 @@
tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally);
TRACE_EVENT_FLOW_END1("task", "MessageLoop::PostTask",
- TRACE_ID_MANGLE(GetTaskTraceID(pending_task, this)),
+ TRACE_ID_MANGLE(GetTaskTraceID(pending_task)),
"queue_duration",
(start_time - pending_task.EffectiveTimePosted()).InMilliseconds());
TRACE_EVENT2("task", "MessageLoop::RunTask",
@@ -523,24 +504,6 @@
delayed_work_queue_.push(pending_task);
}
-void MessageLoop::ReloadWorkQueue() {
- // We can improve performance of our loading tasks from incoming_queue_ to
- // work_queue_ by waiting until the last minute (work_queue_ is empty) to
- // load. That reduces the number of locks-per-task significantly when our
- // queues get large.
- if (!work_queue_.empty())
- return; // Wait till we *really* need to lock and load.
-
- // Acquire all we can from the inter-thread queue with one lock acquisition.
- {
- AutoLock lock(incoming_queue_lock_);
- if (incoming_queue_.empty())
- return;
- incoming_queue_.Swap(&work_queue_); // Constant time
- DCHECK(incoming_queue_.empty());
- }
-}
-
bool MessageLoop::DeletePendingTasks() {
bool did_work = !work_queue_.empty();
while (!work_queue_.empty()) {
@@ -570,87 +533,25 @@
return did_work;
}
-TimeTicks MessageLoop::CalculateDelayedRuntime(TimeDelta delay) {
- TimeTicks delayed_run_time;
- if (delay > TimeDelta()) {
- delayed_run_time = TimeTicks::Now() + delay;
-
-#if defined(OS_WIN)
- if (high_resolution_timer_expiration_.is_null()) {
- // Windows timers are granular to 15.6ms. If we only set high-res
- // timers for those under 15.6ms, then a 18ms timer ticks at ~32ms,
- // which as a percentage is pretty inaccurate. So enable high
- // res timers for any timer which is within 2x of the granularity.
- // This is a tradeoff between accuracy and power management.
- bool needs_high_res_timers = delay.InMilliseconds() <
- (2 * Time::kMinLowResolutionThresholdMs);
- if (needs_high_res_timers) {
- if (Time::ActivateHighResolutionTimer(true)) {
- high_resolution_timer_expiration_ = TimeTicks::Now() +
- TimeDelta::FromMilliseconds(kHighResolutionTimerModeLeaseTimeMs);
- }
- }
- }
-#endif
- } else {
- DCHECK_EQ(delay.InMilliseconds(), 0) << "delay should not be negative";
- }
-
-#if defined(OS_WIN)
- if (!high_resolution_timer_expiration_.is_null()) {
- if (TimeTicks::Now() > high_resolution_timer_expiration_) {
- Time::ActivateHighResolutionTimer(false);
- high_resolution_timer_expiration_ = TimeTicks();
- }
- }
-#endif
-
- return delayed_run_time;
+uint64 MessageLoop::GetTaskTraceID(const PendingTask& task) {
+ return (static_cast<uint64>(task.sequence_num) << 32) |
+ static_cast<uint64>(reinterpret_cast<intptr_t>(this));
}
-// Possibly called on a background thread!
-bool MessageLoop::AddToIncomingQueue(PendingTask* pending_task,
- bool use_try_lock) {
- // Warning: Don't try to short-circuit, and handle this thread's tasks more
- // directly, as it could starve handling of foreign threads. Put every task
- // into this queue.
+void MessageLoop::ReloadWorkQueue() {
+ // We can improve performance of our loading tasks from the incoming queue to
+ // |*work_queue| by waiting until the last minute (|*work_queue| is empty) to
+ // load. That reduces the number of locks-per-task significantly when our
+ // queues get large.
+ if (work_queue_.empty())
+ incoming_task_queue_->ReloadWorkQueue(&work_queue_);
+}
- scoped_refptr<MessagePump> pump;
- {
- if (use_try_lock) {
- if (!incoming_queue_lock_.Try()) {
- pending_task->task.Reset();
- return false;
- }
- } else {
- incoming_queue_lock_.Acquire();
- }
- AutoLock locked(incoming_queue_lock_, AutoLock::AlreadyAcquired());
- // Initialize the sequence number. The sequence number is used for delayed
- // tasks (to faciliate FIFO sorting when two tasks have the same
- // delayed_run_time value) and for identifying the task in about:tracing.
- pending_task->sequence_num = next_sequence_num_++;
-
- TRACE_EVENT_FLOW_BEGIN0("task", "MessageLoop::PostTask",
- TRACE_ID_MANGLE(GetTaskTraceID(*pending_task, this)));
-
- bool was_empty = incoming_queue_.empty();
- incoming_queue_.push(*pending_task);
- pending_task->task.Reset();
- // The Android UI message loop needs to get notified each time
- // a task is added to the incoming queue.
- if (!was_empty && !AlwaysNotifyPump(type_))
- return true; // Someone else should have started the sub-pump.
-
- pump = pump_;
- }
- // Since the incoming_queue_ may contain a task that destroys this message
- // loop, we cannot exit incoming_queue_lock_ until we are done with |this|.
- // We use a stack-based reference to the message pump so that we can call
- // ScheduleWork outside of incoming_queue_lock_.
-
- pump->ScheduleWork();
- return true;
+void MessageLoop::ScheduleWork(bool was_empty) {
+ // The Android UI message loop needs to get notified each time
+ // a task is added to the incoming queue.
+ if (was_empty || AlwaysNotifyPump(type_))
+ pump_->ScheduleWork();
}
//------------------------------------------------------------------------------
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index 846cc8d..6f71a85 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -13,7 +13,10 @@
#include "base/callback_forward.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/incoming_task_queue.h"
#include "base/message_loop/message_loop_proxy.h"
+#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/message_loop/message_pump.h"
#include "base/observer_list.h"
#include "base/pending_task.h"
@@ -46,12 +49,12 @@
namespace base {
class HistogramBase;
-class MessageLoopLockTest;
class RunLoop;
class ThreadTaskRunnerHandle;
#if defined(OS_ANDROID)
class MessagePumpForUI;
#endif
+class WaitableEvent;
// A MessageLoop is used to process events for a particular thread. There is
// at most one MessageLoop instance per thread.
@@ -283,7 +286,7 @@
// Gets the message loop proxy associated with this message loop.
scoped_refptr<MessageLoopProxy> message_loop_proxy() {
- return message_loop_proxy_.get();
+ return message_loop_proxy_;
}
// Enables or disables the recursive task processing. This happens in the case
@@ -359,23 +362,10 @@
void AddTaskObserver(TaskObserver* task_observer);
void RemoveTaskObserver(TaskObserver* task_observer);
- // Returns true if the message loop has high resolution timers enabled.
- // Provided for testing.
- bool high_resolution_timers_enabled() {
-#if defined(OS_WIN)
- return !high_resolution_timer_expiration_.is_null();
-#else
- return true;
-#endif
- }
-
// When we go into high resolution timer mode, we will stay in hi-res mode
// for at least 1s.
static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
- // Asserts that the MessageLoop is "idle".
- void AssertIdle() const;
-
#if defined(OS_WIN)
void set_os_modal_loop(bool os_modal_loop) {
os_modal_loop_ = os_modal_loop;
@@ -389,6 +379,18 @@
// Can only be called from the thread that owns the MessageLoop.
bool is_running() const;
+ // Returns true if the message loop has high resolution timers enabled.
+ // Provided for testing.
+ bool IsHighResolutionTimerEnabledForTesting();
+
+ // Returns true if the message loop is "idle". Provided for testing.
+ bool IsIdleForTesting();
+
+ // Takes the incoming queue lock, signals |caller_wait| and waits until
+ // |caller_signal| is signalled.
+ void LockWaitUnLockForTesting(WaitableEvent* caller_wait,
+ WaitableEvent* caller_signal);
+
//----------------------------------------------------------------------------
protected:
@@ -402,11 +404,11 @@
}
#endif
- scoped_refptr<MessagePump> pump_;
+ scoped_ptr<MessagePump> pump_;
private:
+ friend class internal::IncomingTaskQueue;
friend class RunLoop;
- friend class MessageLoopLockTest;
// A function to encapsulate all the exception handling capability in the
// stacks around the running of a main message loop. It will run the message
@@ -436,34 +438,23 @@
// Adds the pending task to delayed_work_queue_.
void AddToDelayedWorkQueue(const PendingTask& pending_task);
- // This function attempts to add pending task to our incoming_queue_.
- // The append can only possibly fail when |use_try_lock| is true.
- //
- // When |use_try_lock| is true, then this call will avoid blocking if
- // the related lock is already held, and will in that case (when the
- // lock is contended) fail to perform the append, and will return false.
- //
- // If the call succeeds to append to the queue, then this call
- // will return true.
- //
- // In all cases, the caller retains ownership of |pending_task|, but this
- // function will reset the value of pending_task->task. This is needed to
- // ensure that the posting call stack does not retain pending_task->task
- // beyond this function call.
- bool AddToIncomingQueue(PendingTask* pending_task, bool use_try_lock);
-
- // Load tasks from the incoming_queue_ into work_queue_ if the latter is
- // empty. The former requires a lock to access, while the latter is directly
- // accessible on this thread.
- void ReloadWorkQueue();
-
// Delete tasks that haven't run yet without running them. Used in the
// destructor to make sure all the task's destructors get called. Returns
// true if some work was done.
bool DeletePendingTasks();
- // Calculates the time at which a PendingTask should run.
- TimeTicks CalculateDelayedRuntime(TimeDelta delay);
+ // Creates a process-wide unique ID to represent this task in trace events.
+ // This will be mangled with a Process ID hash to reduce the likelyhood of
+ // colliding with MessageLoop pointers on other processes.
+ uint64 GetTaskTraceID(const PendingTask& task);
+
+ // Loads tasks from the incoming queue to |work_queue_| if the latter is
+ // empty.
+ void ReloadWorkQueue();
+
+ // Wakes up the message pump. Can be called on any thread. The caller is
+ // responsible for synchronizing ScheduleWork() calls.
+ void ScheduleWork(bool was_empty);
// Start recording histogram info about events and action IF it was enabled
// and IF the statistics recorder can accept a registration of our histogram.
@@ -498,40 +489,30 @@
ObserverList<DestructionObserver> destruction_observers_;
+ bool exception_restoration_;
+
// A recursion block that prevents accidentally running additional tasks when
// insider a (accidentally induced?) nested message pump.
bool nestable_tasks_allowed_;
- bool exception_restoration_;
-
- std::string thread_name_;
- // A profiling histogram showing the counts of various messages and events.
- HistogramBase* message_histogram_;
-
- // An incoming queue of tasks that are acquired under a mutex for processing
- // on this instance's thread. These tasks have not yet been sorted out into
- // items for our work_queue_ vs delayed_work_queue_.
- TaskQueue incoming_queue_;
- // Protect access to incoming_queue_.
- mutable Lock incoming_queue_lock_;
-
- RunLoop* run_loop_;
-
#if defined(OS_WIN)
- TimeTicks high_resolution_timer_expiration_;
// Should be set to true before calling Windows APIs like TrackPopupMenu, etc
// which enter a modal message loop.
bool os_modal_loop_;
#endif
- // The next sequence number to use for delayed tasks. Updating this counter is
- // protected by incoming_queue_lock_.
- int next_sequence_num_;
+ std::string thread_name_;
+ // A profiling histogram showing the counts of various messages and events.
+ HistogramBase* message_histogram_;
+
+ RunLoop* run_loop_;
ObserverList<TaskObserver> task_observers_;
- // The message loop proxy associated with this message loop, if one exists.
- scoped_refptr<MessageLoopProxy> message_loop_proxy_;
+ scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
+
+ // The message loop proxy associated with this message loop.
+ scoped_refptr<internal::MessageLoopProxyImpl> message_loop_proxy_;
scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
template <class T, class R> friend class base::subtle::DeleteHelperInternal;
diff --git a/base/message_loop/message_loop_proxy_impl.cc b/base/message_loop/message_loop_proxy_impl.cc
index 7dc8caa..b7abca3 100644
--- a/base/message_loop/message_loop_proxy_impl.cc
+++ b/base/message_loop/message_loop_proxy_impl.cc
@@ -5,81 +5,43 @@
#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/location.h"
-#include "base/threading/thread_restrictions.h"
+#include "base/logging.h"
+#include "base/message_loop/incoming_task_queue.h"
+#include "base/message_loop/message_loop.h"
namespace base {
+namespace internal {
-MessageLoopProxyImpl::~MessageLoopProxyImpl() {
+MessageLoopProxyImpl::MessageLoopProxyImpl(
+ scoped_refptr<IncomingTaskQueue> incoming_queue)
+ : incoming_queue_(incoming_queue),
+ valid_thread_id_(PlatformThread::CurrentId()) {
}
bool MessageLoopProxyImpl::PostDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
- return PostTaskHelper(from_here, task, delay, true);
+ DCHECK(!task.is_null()) << from_here.ToString();
+ return incoming_queue_->AddToIncomingQueue(from_here, task, delay, true);
}
bool MessageLoopProxyImpl::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
- return PostTaskHelper(from_here, task, delay, false);
+ DCHECK(!task.is_null()) << from_here.ToString();
+ return incoming_queue_->AddToIncomingQueue(from_here, task, delay, false);
}
bool MessageLoopProxyImpl::RunsTasksOnCurrentThread() const {
- // We shouldn't use MessageLoop::current() since it uses LazyInstance which
- // may be deleted by ~AtExitManager when a WorkerPool thread calls this
- // function.
- // http://crbug.com/63678
- base::ThreadRestrictions::ScopedAllowSingleton allow_singleton;
- AutoLock lock(message_loop_lock_);
- return (target_message_loop_ &&
- (MessageLoop::current() == target_message_loop_));
+ return valid_thread_id_ == PlatformThread::CurrentId();
}
-// MessageLoop::DestructionObserver implementation
-void MessageLoopProxyImpl::WillDestroyCurrentMessageLoop() {
- AutoLock lock(message_loop_lock_);
- target_message_loop_ = NULL;
+MessageLoopProxyImpl::~MessageLoopProxyImpl() {
}
-void MessageLoopProxyImpl::OnDestruct() const {
- // We shouldn't use MessageLoop::current() since it uses LazyInstance which
- // may be deleted by ~AtExitManager when a WorkerPool thread calls this
- // function.
- // http://crbug.com/63678
- base::ThreadRestrictions::ScopedAllowSingleton allow_singleton;
- bool delete_later = false;
- {
- AutoLock lock(message_loop_lock_);
- if (target_message_loop_ &&
- (MessageLoop::current() != target_message_loop_)) {
- target_message_loop_->DeleteSoon(FROM_HERE, this);
- delete_later = true;
- }
- }
- if (!delete_later)
- delete this;
-}
-
-MessageLoopProxyImpl::MessageLoopProxyImpl()
- : target_message_loop_(MessageLoop::current()) {
-}
-
-bool MessageLoopProxyImpl::PostTaskHelper(
- const tracked_objects::Location& from_here, const base::Closure& task,
- base::TimeDelta delay, bool nestable) {
- AutoLock lock(message_loop_lock_);
- if (target_message_loop_) {
- if (nestable) {
- target_message_loop_->PostDelayedTask(from_here, task, delay);
- } else {
- target_message_loop_->PostNonNestableDelayedTask(from_here, task, delay);
- }
- return true;
- }
- return false;
-}
+} // namespace internal
scoped_refptr<MessageLoopProxy>
MessageLoopProxy::current() {
diff --git a/base/message_loop/message_loop_proxy_impl.h b/base/message_loop/message_loop_proxy_impl.h
index 2269023..b7f62b9 100644
--- a/base/message_loop/message_loop_proxy_impl.h
+++ b/base/message_loop/message_loop_proxy_impl.h
@@ -6,17 +6,24 @@
#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
#include "base/base_export.h"
-#include "base/message_loop.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop_proxy.h"
-#include "base/synchronization/lock.h"
+#include "base/pending_task.h"
+#include "base/threading/platform_thread.h"
namespace base {
+namespace internal {
+
+class IncomingTaskQueue;
// A stock implementation of MessageLoopProxy that is created and managed by a
// MessageLoop. For now a MessageLoopProxyImpl can only be created as part of a
// MessageLoop.
class BASE_EXPORT MessageLoopProxyImpl : public MessageLoopProxy {
public:
+ explicit MessageLoopProxyImpl(
+ scoped_refptr<IncomingTaskQueue> incoming_queue);
+
// MessageLoopProxy implementation
virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
@@ -27,36 +34,20 @@
base::TimeDelta delay) OVERRIDE;
virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
- protected:
+ private:
+ friend class RefCountedThreadSafe<MessageLoopProxyImpl>;
virtual ~MessageLoopProxyImpl();
- // Override OnDestruct so that we can delete the object on the target message
- // loop if it still exists.
- virtual void OnDestruct() const OVERRIDE;
+ // THe incoming queue receiving all posted tasks.
+ scoped_refptr<IncomingTaskQueue> incoming_queue_;
- private:
- // Allow the MessageLoop to create a MessageLoopProxyImpl.
- friend class MessageLoop;
- friend class DeleteHelper<MessageLoopProxyImpl>;
-
- MessageLoopProxyImpl();
-
- // Called directly by MessageLoop::~MessageLoop.
- virtual void WillDestroyCurrentMessageLoop();
-
-
- bool PostTaskHelper(const tracked_objects::Location& from_here,
- const base::Closure& task,
- base::TimeDelta delay,
- bool nestable);
-
- // The lock that protects access to target_message_loop_.
- mutable base::Lock message_loop_lock_;
- MessageLoop* target_message_loop_;
+ // ID of the thread |this| was created on.
+ PlatformThreadId valid_thread_id_;
DISALLOW_COPY_AND_ASSIGN(MessageLoopProxyImpl);
};
+} // namespace internal
} // namespace base
#endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
diff --git a/base/message_loop/message_loop_proxy_impl_unittest.cc b/base/message_loop/message_loop_proxy_impl_unittest.cc
index 4c88887..81c9b0c 100644
--- a/base/message_loop/message_loop_proxy_impl_unittest.cc
+++ b/base/message_loop/message_loop_proxy_impl_unittest.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/message_loop/message_loop_proxy_unittest.cc b/base/message_loop/message_loop_proxy_unittest.cc
index e373059..ada9080 100644
--- a/base/message_loop/message_loop_proxy_unittest.cc
+++ b/base/message_loop/message_loop_proxy_unittest.cc
@@ -9,7 +9,7 @@
#include "base/debug/leak_annotations.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index 504c8e3..ab05b3c 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy_impl.h"
#include "base/pending_task.h"
#include "base/posix/eintr_wrapper.h"
#include "base/run_loop.h"
@@ -26,19 +27,6 @@
namespace base {
-class MessageLoopLockTest {
- public:
- static void LockWaitUnLock(MessageLoop* loop,
- WaitableEvent* caller_wait,
- WaitableEvent* caller_signal) {
-
- loop->incoming_queue_lock_.Acquire();
- caller_wait->Signal();
- caller_signal->Wait();
- loop->incoming_queue_lock_.Release();
- }
-};
-
// TODO(darin): Platform-specific MessageLoop tests should be grouped together
// to avoid chopping this file up with so many #ifdefs.
@@ -121,10 +109,10 @@
thread.Start();
thread.message_loop()->PostTask(
FROM_HERE,
- Bind(&MessageLoopLockTest::LockWaitUnLock,
- MessageLoop::current(),
- &wait,
- &signal));
+ Bind(&MessageLoop::LockWaitUnLockForTesting,
+ base::Unretained(MessageLoop::current()),
+ &wait,
+ &signal));
wait.Wait();
EXPECT_FALSE(MessageLoop::current()->TryPostTask(FROM_HERE, Bind(
@@ -1895,20 +1883,20 @@
const TimeDelta kFastTimer = TimeDelta::FromMilliseconds(5);
const TimeDelta kSlowTimer = TimeDelta::FromMilliseconds(100);
- EXPECT_FALSE(loop.high_resolution_timers_enabled());
+ EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting());
// Post a fast task to enable the high resolution timers.
loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
kFastTimer);
loop.Run();
- EXPECT_TRUE(loop.high_resolution_timers_enabled());
+ EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting());
// Post a slow task and verify high resolution timers
// are still enabled.
loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
kSlowTimer);
loop.Run();
- EXPECT_TRUE(loop.high_resolution_timers_enabled());
+ EXPECT_TRUE(loop.IsHighResolutionTimerEnabledForTesting());
// Wait for a while so that high-resolution mode elapses.
PlatformThread::Sleep(TimeDelta::FromMilliseconds(
@@ -1918,7 +1906,7 @@
loop.PostDelayedTask(FROM_HERE, Bind(&PostNTasksThenQuit, 1),
kSlowTimer);
loop.Run();
- EXPECT_FALSE(loop.high_resolution_timers_enabled());
+ EXPECT_FALSE(loop.IsHighResolutionTimerEnabledForTesting());
}
#endif // defined(OS_WIN)
diff --git a/base/message_loop/message_pump.h b/base/message_loop/message_pump.h
index 5b72232..0ebba3a 100644
--- a/base/message_loop/message_pump.h
+++ b/base/message_loop/message_pump.h
@@ -6,13 +6,13 @@
#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
#include "base/base_export.h"
-#include "base/memory/ref_counted.h"
+#include "base/threading/non_thread_safe.h"
namespace base {
class TimeTicks;
-class BASE_EXPORT MessagePump : public RefCountedThreadSafe<MessagePump> {
+class BASE_EXPORT MessagePump : public NonThreadSafe {
public:
// Please see the comments above the Run method for an illustration of how
// these delegate methods are used.
@@ -42,6 +42,7 @@
};
MessagePump();
+ virtual ~MessagePump();
// The Run method is called to enter the message pump's run loop.
//
@@ -118,10 +119,6 @@
// cancelling any pending DoDelayedWork callback. This method may only be
// used on the thread that called Run.
virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
-
- protected:
- virtual ~MessagePump();
- friend class RefCountedThreadSafe<MessagePump>;
};
} // namespace base
diff --git a/base/message_loop/message_pump_android.h b/base/message_loop/message_pump_android.h
index f3a8ded..8a07a0f 100644
--- a/base/message_loop/message_pump_android.h
+++ b/base/message_loop/message_pump_android.h
@@ -22,6 +22,7 @@
class BASE_EXPORT MessagePumpForUI : public MessagePump {
public:
MessagePumpForUI();
+ virtual ~MessagePumpForUI();
virtual void Run(Delegate* delegate) OVERRIDE;
virtual void Quit() OVERRIDE;
@@ -32,9 +33,6 @@
static bool RegisterBindings(JNIEnv* env);
- protected:
- virtual ~MessagePumpForUI();
-
private:
RunLoop* run_loop_;
base::android::ScopedJavaGlobalRef<jobject> system_message_handler_obj_;
diff --git a/base/message_loop/message_pump_aurax11.cc b/base/message_loop/message_pump_aurax11.cc
index 70cae64..1f91a0e 100644
--- a/base/message_loop/message_pump_aurax11.cc
+++ b/base/message_loop/message_pump_aurax11.cc
@@ -10,7 +10,7 @@
#include <X11/XKBlib.h>
#include "base/basictypes.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
namespace base {
@@ -139,6 +139,13 @@
x_root_window_ = DefaultRootWindow(g_xdisplay);
}
+MessagePumpAuraX11::~MessagePumpAuraX11() {
+ g_source_destroy(x_source_);
+ g_source_unref(x_source_);
+ XCloseDisplay(g_xdisplay);
+ g_xdisplay = NULL;
+}
+
// static
Display* MessagePumpAuraX11::GetDefaultXDisplay() {
if (!g_xdisplay)
@@ -211,13 +218,6 @@
} while (event.type != MapNotify);
}
-MessagePumpAuraX11::~MessagePumpAuraX11() {
- g_source_destroy(x_source_);
- g_source_unref(x_source_);
- XCloseDisplay(g_xdisplay);
- g_xdisplay = NULL;
-}
-
void MessagePumpAuraX11::InitXSource() {
// CHECKs are to help track down crbug.com/113106.
CHECK(!x_source_);
diff --git a/base/message_loop/message_pump_aurax11.h b/base/message_loop/message_pump_aurax11.h
index cec6934..89089ad 100644
--- a/base/message_loop/message_pump_aurax11.h
+++ b/base/message_loop/message_pump_aurax11.h
@@ -17,8 +17,8 @@
// It would be nice to include the X11 headers here so that we use Window
// instead of its typedef of unsigned long, but we can't because everything in
-// chrome includes us through base/message_loop.h, and X11's crappy #define
-// heavy headers muck up half of chrome.
+// chrome includes us through base/message_loop/message_loop.h, and X11's crappy
+// #define heavy headers muck up half of chrome.
typedef struct _GPollFD GPollFD;
typedef struct _GSource GSource;
@@ -35,6 +35,7 @@
public MessagePumpDispatcher {
public:
MessagePumpAuraX11();
+ virtual ~MessagePumpAuraX11();
// Returns default X Display.
static Display* GetDefaultXDisplay();
@@ -72,9 +73,6 @@
// functions which require a mapped window.
void BlockUntilWindowMapped(unsigned long xid);
- protected:
- virtual ~MessagePumpAuraX11();
-
private:
typedef std::map<unsigned long, MessagePumpDispatcher*> DispatchersMap;
diff --git a/base/message_loop/message_pump_default.cc b/base/message_loop/message_pump_default.cc
index b36ff21..27c19e0 100644
--- a/base/message_loop/message_pump_default.cc
+++ b/base/message_loop/message_pump_default.cc
@@ -18,6 +18,9 @@
event_(false, false) {
}
+MessagePumpDefault::~MessagePumpDefault() {
+}
+
void MessagePumpDefault::Run(Delegate* delegate) {
DCHECK(keep_running_) << "Quit must have been called outside of Run!";
diff --git a/base/message_loop/message_pump_default.h b/base/message_loop/message_pump_default.h
index 07a6c70..a9b83e8 100644
--- a/base/message_loop/message_pump_default.h
+++ b/base/message_loop/message_pump_default.h
@@ -14,6 +14,7 @@
class MessagePumpDefault : public MessagePump {
public:
MessagePumpDefault();
+ virtual ~MessagePumpDefault();
// MessagePump methods:
virtual void Run(Delegate* delegate) OVERRIDE;
@@ -21,9 +22,6 @@
virtual void ScheduleWork() OVERRIDE;
virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
- protected:
- virtual ~MessagePumpDefault() {}
-
private:
// This flag is set to false when Run should return.
bool keep_running_;
diff --git a/base/message_loop/message_pump_glib.cc b/base/message_loop/message_pump_glib.cc
index de012fd..cfacb7b 100644
--- a/base/message_loop/message_pump_glib.cc
+++ b/base/message_loop/message_pump_glib.cc
@@ -160,6 +160,13 @@
g_source_attach(work_source_, context_);
}
+MessagePumpGlib::~MessagePumpGlib() {
+ g_source_destroy(work_source_);
+ g_source_unref(work_source_);
+ close(wakeup_pipe_read_);
+ close(wakeup_pipe_write_);
+}
+
void MessagePumpGlib::RunWithDispatcher(Delegate* delegate,
MessagePumpDispatcher* dispatcher) {
#ifndef NDEBUG
@@ -320,13 +327,6 @@
ScheduleWork();
}
-MessagePumpGlib::~MessagePumpGlib() {
- g_source_destroy(work_source_);
- g_source_unref(work_source_);
- close(wakeup_pipe_read_);
- close(wakeup_pipe_write_);
-}
-
MessagePumpDispatcher* MessagePumpGlib::GetDispatcher() {
return state_ ? state_->dispatcher : NULL;
}
diff --git a/base/message_loop/message_pump_glib.h b/base/message_loop/message_pump_glib.h
index 775470e..33690d0 100644
--- a/base/message_loop/message_pump_glib.h
+++ b/base/message_loop/message_pump_glib.h
@@ -35,6 +35,7 @@
class BASE_EXPORT MessagePumpGlib : public MessagePump {
public:
MessagePumpGlib();
+ virtual ~MessagePumpGlib();
// Like MessagePump::Run, but events are routed through dispatcher.
virtual void RunWithDispatcher(Delegate* delegate,
@@ -64,8 +65,6 @@
virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
protected:
- virtual ~MessagePumpGlib();
-
// Returns the dispatcher for the current run state (|state_->dispatcher|).
MessagePumpDispatcher* GetDispatcher();
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc
index cb30bb0..033e6cd 100644
--- a/base/message_loop/message_pump_glib_unittest.cc
+++ b/base/message_loop/message_pump_glib_unittest.cc
@@ -14,7 +14,7 @@
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/message_loop/message_pump_gtk.cc b/base/message_loop/message_pump_gtk.cc
index 8fa8cf2..ad65113 100644
--- a/base/message_loop/message_pump_gtk.cc
+++ b/base/message_loop/message_pump_gtk.cc
@@ -65,6 +65,11 @@
gdk_event_handler_set(&EventDispatcher, this, NULL);
}
+MessagePumpGtk::~MessagePumpGtk() {
+ gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event),
+ this, NULL);
+}
+
void MessagePumpGtk::DispatchEvents(GdkEvent* event) {
UNSHIPPED_TRACE_EVENT1("task", "MessagePumpGtk::DispatchEvents",
"type", EventToTypeString(event));
@@ -92,11 +97,6 @@
return GDK_DISPLAY_XDISPLAY(display);
}
-MessagePumpGtk::~MessagePumpGtk() {
- gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event),
- this, NULL);
-}
-
void MessagePumpGtk::WillProcessEvent(GdkEvent* event) {
FOR_EACH_OBSERVER(MessagePumpObserver, observers(), WillProcessEvent(event));
}
diff --git a/base/message_loop/message_pump_gtk.h b/base/message_loop/message_pump_gtk.h
index e22e04f..947ab88 100644
--- a/base/message_loop/message_pump_gtk.h
+++ b/base/message_loop/message_pump_gtk.h
@@ -43,6 +43,7 @@
class BASE_EXPORT MessagePumpGtk : public MessagePumpGlib {
public:
MessagePumpGtk();
+ virtual ~MessagePumpGtk();
// Dispatch an available GdkEvent. Essentially this allows a subclass to do
// some task before/after calling the default handler (EventDispatcher).
@@ -51,9 +52,6 @@
// Returns default X Display.
static Display* GetDefaultXDisplay();
- protected:
- virtual ~MessagePumpGtk();
-
private:
// Invoked from EventDispatcher. Notifies all observers we're about to
// process an event.
diff --git a/base/message_loop/message_pump_io_ios.cc b/base/message_loop/message_pump_io_ios.cc
index 0dd6930..cd5ffed 100644
--- a/base/message_loop/message_pump_io_ios.cc
+++ b/base/message_loop/message_pump_io_ios.cc
@@ -11,7 +11,6 @@
fdref_(NULL),
callback_types_(0),
fd_source_(NULL),
- pump_(NULL),
watcher_(NULL) {
}
@@ -24,11 +23,12 @@
return true;
CFFileDescriptorDisableCallBacks(fdref_, callback_types_);
- pump_->RemoveRunLoopSource(fd_source_);
+ if (pump_)
+ pump_->RemoveRunLoopSource(fd_source_);
fd_source_.reset();
fdref_.reset();
callback_types_ = 0;
- pump_ = NULL;
+ pump_.reset();
watcher_ = NULL;
return true;
}
@@ -65,7 +65,7 @@
pump->DidProcessIOEvent();
}
-MessagePumpIOSForIO::MessagePumpIOSForIO() {
+MessagePumpIOSForIO::MessagePumpIOSForIO() : weak_factory_(this) {
}
MessagePumpIOSForIO::~MessagePumpIOSForIO() {
@@ -143,7 +143,7 @@
}
controller->set_watcher(delegate);
- controller->set_pump(this);
+ controller->set_pump(weak_factory_.GetWeakPtr());
return true;
}
@@ -183,7 +183,8 @@
fdref, base::scoped_policy::RETAIN);
int fd = CFFileDescriptorGetNativeDescriptor(fdref);
- MessagePumpIOSForIO* pump = controller->pump();
+ MessagePumpIOSForIO* pump = controller->pump().get();
+ DCHECK(pump);
if (callback_types & kCFFileDescriptorWriteCallBack)
controller->OnFileCanWriteWithoutBlocking(fd, pump);
diff --git a/base/message_loop/message_pump_io_ios.h b/base/message_loop/message_pump_io_ios.h
index 6779aab..52de9fd 100644
--- a/base/message_loop/message_pump_io_ios.h
+++ b/base/message_loop/message_pump_io_ios.h
@@ -9,9 +9,9 @@
#include "base/mac/scoped_cffiledescriptorref.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_pump_mac.h"
#include "base/observer_list.h"
-#include "base/threading/thread_checker.h"
namespace base {
@@ -71,8 +71,8 @@
CFRunLoopSourceRef fd_source,
bool is_persistent);
- void set_pump(MessagePumpIOSForIO* pump) { pump_ = pump; }
- MessagePumpIOSForIO* pump() const { return pump_; }
+ void set_pump(base::WeakPtr<MessagePumpIOSForIO> pump) { pump_ = pump; }
+ const base::WeakPtr<MessagePumpIOSForIO>& pump() const { return pump_; }
void set_watcher(Watcher* watcher) { watcher_ = watcher; }
@@ -83,7 +83,7 @@
base::mac::ScopedCFFileDescriptorRef fdref_;
CFOptionFlags callback_types_;
base::ScopedCFTypeRef<CFRunLoopSourceRef> fd_source_;
- scoped_refptr<MessagePumpIOSForIO> pump_;
+ base::WeakPtr<MessagePumpIOSForIO> pump_;
Watcher* watcher_;
DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
@@ -96,6 +96,7 @@
};
MessagePumpIOSForIO();
+ virtual ~MessagePumpIOSForIO();
// Have the current thread's message loop watch for a a situation in which
// reading/writing to the FD can be performed without blocking.
@@ -119,9 +120,6 @@
void AddIOObserver(IOObserver* obs);
void RemoveIOObserver(IOObserver* obs);
- protected:
- virtual ~MessagePumpIOSForIO();
-
private:
friend class MessagePumpIOSForIOTest;
@@ -135,6 +133,8 @@
ObserverList<IOObserver> io_observers_;
ThreadChecker watch_file_descriptor_caller_checker_;
+ base::WeakPtrFactory<MessagePumpIOSForIO> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(MessagePumpIOSForIO);
};
diff --git a/base/message_loop/message_pump_io_ios_unittest.cc b/base/message_loop/message_pump_io_ios_unittest.cc
index 9e94c6b..9c7a8fb 100644
--- a/base/message_loop/message_pump_io_ios_unittest.cc
+++ b/base/message_loop/message_pump_io_ios_unittest.cc
@@ -6,7 +6,7 @@
#include <unistd.h>
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -126,7 +126,7 @@
};
TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
- scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
+ scoped_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
MessagePumpIOSForIO::FileDescriptorWatcher* watcher =
new MessagePumpIOSForIO::FileDescriptorWatcher;
DeleteWatcher delegate(watcher);
@@ -162,9 +162,9 @@
};
TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
- scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
+ scoped_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
MessagePumpIOSForIO::FileDescriptorWatcher watcher;
- StopWatcher delegate(&watcher, pump);
+ StopWatcher delegate(&watcher, pump.get());
pump->WatchFileDescriptor(pipefds_[1],
false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
@@ -173,9 +173,9 @@
}
TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
- scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
+ scoped_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
MessagePumpIOSForIO::FileDescriptorWatcher watcher;
- StopWatcher delegate(&watcher, pump, alternate_pipefds_[1]);
+ StopWatcher delegate(&watcher, pump.get(), alternate_pipefds_[1]);
pump->WatchFileDescriptor(pipefds_[1],
false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
diff --git a/base/message_loop/message_pump_libevent.h b/base/message_loop/message_pump_libevent.h
index 3b1d26d..f3a48a9 100644
--- a/base/message_loop/message_pump_libevent.h
+++ b/base/message_loop/message_pump_libevent.h
@@ -98,6 +98,7 @@
};
MessagePumpLibevent();
+ virtual ~MessagePumpLibevent();
// Have the current thread's message loop watch for a a situation in which
// reading/writing to the FD can be performed without blocking.
@@ -126,9 +127,6 @@
virtual void ScheduleWork() OVERRIDE;
virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
- protected:
- virtual ~MessagePumpLibevent();
-
private:
friend class MessagePumpLibeventTest;
diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc
index 657ac7d..52ca95b 100644
--- a/base/message_loop/message_pump_libevent_unittest.cc
+++ b/base/message_loop/message_pump_libevent_unittest.cc
@@ -122,7 +122,7 @@
};
TEST_F(MessagePumpLibeventTest, DeleteWatcher) {
- scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
+ scoped_ptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
MessagePumpLibevent::FileDescriptorWatcher* watcher =
new MessagePumpLibevent::FileDescriptorWatcher;
DeleteWatcher delegate(watcher);
@@ -147,7 +147,7 @@
};
TEST_F(MessagePumpLibeventTest, StopWatcher) {
- scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
+ scoped_ptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
MessagePumpLibevent::FileDescriptorWatcher watcher;
StopWatcher delegate(&watcher);
pump->WatchFileDescriptor(pipefds_[1],
diff --git a/base/message_loop/message_pump_mac.h b/base/message_loop/message_pump_mac.h
index 68c2a3d..748b265 100644
--- a/base/message_loop/message_pump_mac.h
+++ b/base/message_loop/message_pump_mac.h
@@ -32,6 +32,8 @@
#include "base/message_loop/message_pump.h"
+#include "base/basictypes.h"
+
#include <CoreFoundation/CoreFoundation.h>
#if !defined(__OBJC__)
@@ -63,6 +65,7 @@
friend class MessagePumpScopedAutoreleasePool;
public:
MessagePumpCFRunLoopBase();
+ virtual ~MessagePumpCFRunLoopBase();
// Subclasses should implement the work they need to do in MessagePump::Run
// in the DoRun method. MessagePumpCFRunLoopBase::Run calls DoRun directly.
@@ -75,8 +78,6 @@
virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
protected:
- virtual ~MessagePumpCFRunLoopBase();
-
// Accessors for private data members to be used by subclasses.
CFRunLoopRef run_loop() const { return run_loop_; }
int nesting_level() const { return nesting_level_; }
@@ -199,13 +200,11 @@
class MessagePumpCFRunLoop : public MessagePumpCFRunLoopBase {
public:
MessagePumpCFRunLoop();
+ virtual ~MessagePumpCFRunLoop();
virtual void DoRun(Delegate* delegate) OVERRIDE;
virtual void Quit() OVERRIDE;
- protected:
- virtual ~MessagePumpCFRunLoop();
-
private:
virtual void EnterExitRunLoop(CFRunLoopActivity activity) OVERRIDE;
@@ -220,13 +219,11 @@
class MessagePumpNSRunLoop : public MessagePumpCFRunLoopBase {
public:
BASE_EXPORT MessagePumpNSRunLoop();
+ virtual ~MessagePumpNSRunLoop();
virtual void DoRun(Delegate* delegate) OVERRIDE;
virtual void Quit() OVERRIDE;
- protected:
- virtual ~MessagePumpNSRunLoop();
-
private:
// A source that doesn't do anything but provide something signalable
// attached to the run loop. This source will be signalled when Quit
@@ -246,6 +243,7 @@
class MessagePumpUIApplication : public MessagePumpCFRunLoopBase {
public:
MessagePumpUIApplication();
+ virtual ~MessagePumpUIApplication();
virtual void DoRun(Delegate* delegate) OVERRIDE;
virtual void Quit() OVERRIDE;
@@ -253,9 +251,6 @@
// call |Attach()| to set up a delegate. It is an error to call |Run()|.
virtual void Attach(Delegate* delegate);
- protected:
- virtual ~MessagePumpUIApplication();
-
private:
RunLoop* run_loop_;
@@ -267,13 +262,11 @@
class MessagePumpNSApplication : public MessagePumpCFRunLoopBase {
public:
MessagePumpNSApplication();
+ virtual ~MessagePumpNSApplication();
virtual void DoRun(Delegate* delegate) OVERRIDE;
virtual void Quit() OVERRIDE;
- protected:
- virtual ~MessagePumpNSApplication();
-
private:
// False after Quit is called.
bool keep_running_;
@@ -290,10 +283,9 @@
class MessagePumpCrApplication : public MessagePumpNSApplication {
public:
MessagePumpCrApplication();
+ virtual ~MessagePumpCrApplication();
protected:
- virtual ~MessagePumpCrApplication() {}
-
// Returns nil if NSApp is currently in the middle of calling
// -sendEvent. Requires NSApp implementing CrAppProtocol.
virtual NSAutoreleasePool* CreateAutoreleasePool() OVERRIDE;
diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm
index f46d7a8..f885fbf 100644
--- a/base/message_loop/message_pump_mac.mm
+++ b/base/message_loop/message_pump_mac.mm
@@ -616,6 +616,9 @@
MessagePumpCrApplication::MessagePumpCrApplication() {
}
+MessagePumpCrApplication::~MessagePumpCrApplication() {
+}
+
// Prevents an autorelease pool from being created if the app is in the midst of
// handling a UI event because various parts of AppKit depend on objects that
// are created while handling a UI event to be autoreleased in the event loop.
diff --git a/base/message_loop/message_pump_ozone.cc b/base/message_loop/message_pump_ozone.cc
index 5c0bf83..f7bff6d 100644
--- a/base/message_loop/message_pump_ozone.cc
+++ b/base/message_loop/message_pump_ozone.cc
@@ -5,7 +5,7 @@
#include "base/message_loop/message_pump_ozone.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
namespace base {
diff --git a/base/message_loop/message_pump_ozone.h b/base/message_loop/message_pump_ozone.h
index de75ab4..edcdf2e 100644
--- a/base/message_loop/message_pump_ozone.h
+++ b/base/message_loop/message_pump_ozone.h
@@ -20,6 +20,7 @@
public MessagePumpDispatcher {
public:
MessagePumpOzone();
+ virtual ~MessagePumpOzone();
// Returns the UI message pump.
static MessagePumpOzone* Current();
@@ -39,7 +40,6 @@
virtual bool Dispatch(const NativeEvent& event) OVERRIDE;
private:
- virtual ~MessagePumpOzone();
std::vector<MessagePumpDispatcher*> dispatcher_;
DISALLOW_COPY_AND_ASSIGN(MessagePumpOzone);
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc
index d5bcd9c..2f70f09 100644
--- a/base/metrics/field_trial_unittest.cc
+++ b/base/metrics/field_trial_unittest.cc
@@ -4,7 +4,7 @@
#include "base/metrics/field_trial.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h
index 7617e2d..70b4f11 100644
--- a/base/observer_list_threadsafe.h
+++ b/base/observer_list_threadsafe.h
@@ -13,7 +13,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/observer_list.h"
#include "base/stl_util.h"
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc
index 8c6f9f6..57843f4 100644
--- a/base/observer_list_unittest.cc
+++ b/base/observer_list_unittest.cc
@@ -9,7 +9,7 @@
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/platform_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/power_monitor/power_monitor_unittest.cc b/base/power_monitor/power_monitor_unittest.cc
index af3ed41..90f36f0 100644
--- a/base/power_monitor/power_monitor_unittest.cc
+++ b/base/power_monitor/power_monitor_unittest.cc
@@ -4,7 +4,7 @@
#include "base/power_monitor/power_monitor.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
diff --git a/base/prefs/pref_member_unittest.cc b/base/prefs/pref_member_unittest.cc
index c276780..d4d7e02 100644
--- a/base/prefs/pref_member_unittest.cc
+++ b/base/prefs/pref_member_unittest.cc
@@ -5,7 +5,7 @@
#include "base/prefs/pref_member.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/testing_pref_service.h"
#include "base/synchronization/waitable_event.h"
diff --git a/base/prefs/pref_service.cc b/base/prefs/pref_service.cc
index 79158ea..046af91 100644
--- a/base/prefs/pref_service.cc
+++ b/base/prefs/pref_service.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/prefs/default_pref_store.h"
#include "base/prefs/pref_notifier_impl.h"
diff --git a/base/process.h b/base/process.h
index 57983cc..71f4391 100644
--- a/base/process.h
+++ b/base/process.h
@@ -1,70 +1,13 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Forwarding header until all include paths can be updated.
+// TODO(rsesek): Remove this file <http://crbug.com/242290>.
+
#ifndef BASE_PROCESS_H_
#define BASE_PROCESS_H_
-#include "base/base_export.h"
-#include "base/basictypes.h"
-#include "base/process/process_handle.h"
-#include "build/build_config.h"
-
-namespace base {
-
-class BASE_EXPORT Process {
- public:
- Process() : process_(kNullProcessHandle) {
- }
-
- explicit Process(ProcessHandle handle) : process_(handle) {
- }
-
- // A handle to the current process.
- static Process Current();
-
- static bool CanBackgroundProcesses();
-
- // Get/Set the handle for this process. The handle will be 0 if the process
- // is no longer running.
- ProcessHandle handle() const { return process_; }
- void set_handle(ProcessHandle handle) {
- process_ = handle;
- }
-
- // Get the PID for this process.
- ProcessId pid() const;
-
- // Is the this process the current process.
- bool is_current() const;
-
- // Close the process handle. This will not terminate the process.
- void Close();
-
- // Terminates the process with extreme prejudice. The given result code will
- // be the exit code of the process. If the process has already exited, this
- // will do nothing.
- void Terminate(int result_code);
-
- // A process is backgrounded when it's priority is lower than normal.
- // Return true if this process is backgrounded, false otherwise.
- bool IsProcessBackgrounded() const;
-
- // Set a process as backgrounded. If value is true, the priority
- // of the process will be lowered. If value is false, the priority
- // of the process will be made "normal" - equivalent to default
- // process priority.
- // Returns true if the priority was changed, false otherwise.
- bool SetProcessBackgrounded(bool value);
-
- // Returns an integer representing the priority of a process. The meaning
- // of this value is OS dependent.
- int GetPriority() const;
-
- private:
- ProcessHandle process_;
-};
-
-} // namespace base
+#include "base/process/process.h"
#endif // BASE_PROCESS_H_
diff --git a/base/process/kill_win.cc b/base/process/kill_win.cc
index 929ec4f..eb09254 100644
--- a/base/process/kill_win.cc
+++ b/base/process/kill_win.cc
@@ -10,7 +10,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/process/process_iterator.h"
#include "base/process_util.h"
#include "base/win/object_watcher.h"
diff --git a/base/process/launch_win.cc b/base/process/launch_win.cc
index 41477f7..c5126c5 100644
--- a/base/process/launch_win.cc
+++ b/base/process/launch_win.cc
@@ -18,7 +18,7 @@
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/process/kill.h"
#include "base/sys_info.h"
diff --git a/base/process/memory_unittest.cc b/base/process/memory_unittest.cc
index 8022301..a1f3052 100644
--- a/base/process/memory_unittest.cc
+++ b/base/process/memory_unittest.cc
@@ -131,7 +131,7 @@
TEST(ProcessMemoryTest, MacTerminateOnHeapCorruption) {
// Assert that freeing an unallocated pointer will crash the process.
- char buf[3];
+ char buf[9];
asm("" : "=r" (buf)); // Prevent clang from being too smart.
#if ARCH_CPU_64_BITS
// On 64 bit Macs, the malloc system automatically abort()s on heap corruption
diff --git a/base/process/process.h b/base/process/process.h
new file mode 100644
index 0000000..20e8884
--- /dev/null
+++ b/base/process/process.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_PROCESS_PROCESS_PROCESS_H_
+#define BASE_PROCESS_PROCESS_PROCESS_H_
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+#include "base/process/process_handle.h"
+#include "build/build_config.h"
+
+namespace base {
+
+class BASE_EXPORT Process {
+ public:
+ Process() : process_(kNullProcessHandle) {
+ }
+
+ explicit Process(ProcessHandle handle) : process_(handle) {
+ }
+
+ // A handle to the current process.
+ static Process Current();
+
+ static bool CanBackgroundProcesses();
+
+ // Get/Set the handle for this process. The handle will be 0 if the process
+ // is no longer running.
+ ProcessHandle handle() const { return process_; }
+ void set_handle(ProcessHandle handle) {
+ process_ = handle;
+ }
+
+ // Get the PID for this process.
+ ProcessId pid() const;
+
+ // Is the this process the current process.
+ bool is_current() const;
+
+ // Close the process handle. This will not terminate the process.
+ void Close();
+
+ // Terminates the process with extreme prejudice. The given result code will
+ // be the exit code of the process. If the process has already exited, this
+ // will do nothing.
+ void Terminate(int result_code);
+
+ // A process is backgrounded when it's priority is lower than normal.
+ // Return true if this process is backgrounded, false otherwise.
+ bool IsProcessBackgrounded() const;
+
+ // Set a process as backgrounded. If value is true, the priority
+ // of the process will be lowered. If value is false, the priority
+ // of the process will be made "normal" - equivalent to default
+ // process priority.
+ // Returns true if the priority was changed, false otherwise.
+ bool SetProcessBackgrounded(bool value);
+
+ // Returns an integer representing the priority of a process. The meaning
+ // of this value is OS dependent.
+ int GetPriority() const;
+
+ private:
+ ProcessHandle process_;
+};
+
+} // namespace base
+
+#endif // BASE_PROCESS_PROCESS_PROCESS_H_
diff --git a/base/process/process_info.h b/base/process/process_info.h
new file mode 100644
index 0000000..e72c56b
--- /dev/null
+++ b/base/process/process_info.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_PROCESS_PROCESS_PROCESS_INFO_H_
+#define BASE_PROCESS_PROCESS_PROCESS_INFO_H_
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+
+namespace base {
+
+class Time;
+
+// Vends information about the current process.
+class BASE_EXPORT CurrentProcessInfo {
+ public:
+ // Returns the time at which the process was launched or NULL if an error
+ // occurred retrieving the information.
+ static const Time* CreationTime();
+};
+
+} // namespace base
+
+#endif // BASE_PROCESS_PROCESS_PROCESS_INFO_H_
diff --git a/base/process_info_mac.cc b/base/process/process_info_mac.cc
similarity index 96%
rename from base/process_info_mac.cc
rename to base/process/process_info_mac.cc
index 99a21cc..d83acd1 100644
--- a/base/process_info_mac.cc
+++ b/base/process/process_info_mac.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/process_info.h"
+#include "base/process/process_info.h"
#include <sys/sysctl.h>
#include <sys/time.h>
diff --git a/base/process_info_win.cc b/base/process/process_info_win.cc
similarity index 95%
rename from base/process_info_win.cc
rename to base/process/process_info_win.cc
index 04c6c2f..5290b76 100644
--- a/base/process_info_win.cc
+++ b/base/process/process_info_win.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/process_info.h"
+#include "base/process/process_info.h"
#include <windows.h>
diff --git a/base/process_linux.cc b/base/process/process_linux.cc
similarity index 98%
rename from base/process_linux.cc
rename to base/process/process_linux.cc
index 9fd4a7d..93006aa 100644
--- a/base/process_linux.cc
+++ b/base/process/process_linux.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/process.h"
+#include "base/process/process.h"
#include <errno.h>
#include <sys/resource.h>
diff --git a/base/process_posix.cc b/base/process/process_posix.cc
similarity index 97%
rename from base/process_posix.cc
rename to base/process/process_posix.cc
index 20e623c..a446b98 100644
--- a/base/process_posix.cc
+++ b/base/process/process_posix.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/process.h"
+#include "base/process/process.h"
#include <sys/types.h>
#include <sys/time.h>
diff --git a/base/process_util_unittest.cc b/base/process/process_util_unittest.cc
similarity index 100%
rename from base/process_util_unittest.cc
rename to base/process/process_util_unittest.cc
diff --git a/base/process_util_unittest_ios.cc b/base/process/process_util_unittest_ios.cc
similarity index 100%
rename from base/process_util_unittest_ios.cc
rename to base/process/process_util_unittest_ios.cc
diff --git a/base/process_win.cc b/base/process/process_win.cc
similarity index 98%
rename from base/process_win.cc
rename to base/process/process_win.cc
index 3f683ab..30945f2 100644
--- a/base/process_win.cc
+++ b/base/process/process_win.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/process.h"
+#include "base/process/process.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
diff --git a/base/process_info.h b/base/process_info.h
index 429d4dc..17502b8 100644
--- a/base/process_info.h
+++ b/base/process_info.h
@@ -1,25 +1,13 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Forwarding header until all include paths can be updated.
+// TODO(rsesek): Remove this file <http://crbug.com/242290>.
+
#ifndef BASE_PROCESS_INFO_H_
#define BASE_PROCESS_INFO_H_
-#include "base/base_export.h"
-#include "base/basictypes.h"
-
-namespace base {
-
-class Time;
-
-// Vends information about the current process.
-class BASE_EXPORT CurrentProcessInfo {
- public:
- // Returns the time at which the process was launched or NULL if an error
- // occurred retrieving the information.
- static const Time* CreationTime();
-};
-
-} // namespace base
+#include "base/process/process_info.h"
#endif // BASE_PROCESS_INFO_H_
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
deleted file mode 100644
index b76f8c1..0000000
--- a/base/process_util_linux.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process_util.h"
-
-#include <dirent.h>
-#include <malloc.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/process/internal_linux.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/sys_info.h"
-#include "base/threading/thread_restrictions.h"
-
-namespace base {
-
-size_t g_oom_size = 0U;
-
-const char kProcSelfExe[] = "/proc/self/exe";
-
-ProcessId GetParentProcessId(ProcessHandle process) {
- ProcessId pid =
- internal::ReadProcStatsAndGetFieldAsInt(process, internal::VM_PPID);
- if (pid)
- return pid;
- return -1;
-}
-
-FilePath GetProcessExecutablePath(ProcessHandle process) {
- FilePath stat_file = internal::GetProcPidDir(process).Append("exe");
- FilePath exe_name;
- if (!file_util::ReadSymbolicLink(stat_file, &exe_name)) {
- // No such process. Happens frequently in e.g. TerminateAllChromeProcesses
- return FilePath();
- }
- return exe_name;
-}
-
-int GetNumberOfThreads(ProcessHandle process) {
- return internal::ReadProcStatsAndGetFieldAsInt(process,
- internal::VM_NUMTHREADS);
-}
-
-} // namespace base
diff --git a/base/run_loop.h b/base/run_loop.h
index 380c8bf..42a5160 100644
--- a/base/run_loop.h
+++ b/base/run_loop.h
@@ -8,7 +8,7 @@
#include "base/base_export.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
namespace base {
#if defined(OS_ANDROID)
diff --git a/base/sequence_checker.h b/base/sequence_checker.h
index 89bbd7e..fbf146a 100644
--- a/base/sequence_checker.h
+++ b/base/sequence_checker.h
@@ -28,11 +28,12 @@
// the right version for your build configuration.
class SequenceCheckerDoNothing {
public:
- bool CalledOnValidSequencedThread() const {
+ bool CalledOnValidSequence() const {
return true;
}
- void DetachFromSequence() {}
+ void ChangeSequence(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) {}
};
// SequenceChecker is a helper class used to help verify that some
@@ -43,6 +44,10 @@
// Example:
// class MyClass {
// public:
+// explicit MyClass(
+// const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner)
+// : sequence_checker_(sequenced_task_runner) {}
+//
// void Foo() {
// DCHECK(sequence_checker_.CalledOnValidSequence());
// ... (do stuff) ...
@@ -55,9 +60,16 @@
// In Release mode, CalledOnValidSequence will always return true.
#if ENABLE_SEQUENCE_CHECKER
class SequenceChecker : public SequenceCheckerImpl {
+ public:
+ explicit SequenceChecker(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner)
+ : SequenceCheckerImpl(sequenced_task_runner) {}
};
#else
class SequenceChecker : public SequenceCheckerDoNothing {
+ public:
+ explicit SequenceChecker(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) {}
};
#endif // ENABLE_SEQUENCE_CHECKER
diff --git a/base/sequence_checker_impl.cc b/base/sequence_checker_impl.cc
index e95b8ee..24d9ed9 100644
--- a/base/sequence_checker_impl.cc
+++ b/base/sequence_checker_impl.cc
@@ -4,43 +4,28 @@
#include "base/sequence_checker_impl.h"
+#include "base/sequenced_task_runner.h"
+
namespace base {
-SequenceCheckerImpl::SequenceCheckerImpl()
- : sequence_token_assigned_(false) {
- AutoLock auto_lock(lock_);
- EnsureSequenceTokenAssigned();
-}
+SequenceCheckerImpl::SequenceCheckerImpl(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner)
+ : sequenced_task_runner_(sequenced_task_runner) {}
SequenceCheckerImpl::~SequenceCheckerImpl() {}
-bool SequenceCheckerImpl::CalledOnValidSequencedThread() const {
+bool SequenceCheckerImpl::CalledOnValidSequence() const {
AutoLock auto_lock(lock_);
- EnsureSequenceTokenAssigned();
-
- // If this thread is not associated with a SequencedWorkerPool,
- // SequenceChecker behaves as a ThreadChecker. See header for details.
- if (!sequence_token_.IsValid())
- return thread_checker_.CalledOnValidThread();
-
- return sequence_token_.Equals(
- SequencedWorkerPool::GetSequenceTokenForCurrentThread());
+ return sequenced_task_runner_.get() ?
+ sequenced_task_runner_->RunsTasksOnCurrentThread() :
+ thread_checker_.CalledOnValidThread();
}
-void SequenceCheckerImpl::DetachFromSequence() {
+void SequenceCheckerImpl::ChangeSequence(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) {
AutoLock auto_lock(lock_);
+ sequenced_task_runner_ = sequenced_task_runner;
thread_checker_.DetachFromThread();
- sequence_token_assigned_ = false;
- sequence_token_ = SequencedWorkerPool::SequenceToken();
-}
-
-void SequenceCheckerImpl::EnsureSequenceTokenAssigned() const {
- lock_.AssertAcquired();
- if (sequence_token_assigned_)
- return;
-
- sequence_token_assigned_ = true;
- sequence_token_ = SequencedWorkerPool::GetSequenceTokenForCurrentThread();
}
} // namespace base
diff --git a/base/sequence_checker_impl.h b/base/sequence_checker_impl.h
index 741aafe..ccd1198 100644
--- a/base/sequence_checker_impl.h
+++ b/base/sequence_checker_impl.h
@@ -7,42 +7,48 @@
#include "base/base_export.h"
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_checker_impl.h"
namespace base {
+class SequencedTaskRunner;
+
// SequenceCheckerImpl is used to help verify that some methods of a
// class are called in sequence -- that is, called from the same
// SequencedTaskRunner. It is a generalization of ThreadChecker; in
-// particular, it behaves exactly like ThreadChecker if constructed
-// on a thread that is not part of a SequencedWorkerPool.
+// particular, it behaves exactly like ThreadChecker if its passed a
+// NULL SequencedTaskRunner.
class BASE_EXPORT SequenceCheckerImpl {
public:
- SequenceCheckerImpl();
+ // |sequenced_task_runner| can be NULL. In that case, this object
+ // behaves exactly like a ThreadChecker bound to the current thread,
+ // i.e. CalledOnValidSequence() behaves like CalledOnValidThread().
+ explicit SequenceCheckerImpl(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner);
~SequenceCheckerImpl();
- // Returns whether the we are being called on the same sequence token
- // as previous calls. If there is no associated sequence, then returns
- // whether we are being called on the underlying ThreadChecker's thread.
- bool CalledOnValidSequencedThread() const;
+ // Returns whether the we are being called on the underyling
+ // SequencedTaskRunner. If we're not bound to a
+ // |sequenced_task_runner|, returns whether we are being called on
+ // the underlying ThreadChecker's thread.
+ bool CalledOnValidSequence() const;
- // Unbinds the checker from the currently associated sequence. The
- // checker will be re-bound on the next call to CalledOnValidSequence().
- void DetachFromSequence();
+ // Changes the underyling SequencedTaskRunner.
+ // |sequenced_task_runner| can be NULL. In that case, this object
+ // behaves exactly like a ThreadChecker that has been detached from
+ // its thread, i.e. we will be bound to the thread on which we next
+ // call CalledOnValidSequence().
+ void ChangeSequence(
+ const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner);
private:
- void EnsureSequenceTokenAssigned() const;
-
// Guards all variables below.
mutable Lock lock_;
-
- // Used if |sequence_token_| is not valid.
+ scoped_refptr<SequencedTaskRunner> sequenced_task_runner_;
+ // Used if |sequenced_task_runner_| is NULL.
ThreadCheckerImpl thread_checker_;
- mutable bool sequence_token_assigned_;
-
- mutable SequencedWorkerPool::SequenceToken sequence_token_;
DISALLOW_COPY_AND_ASSIGN(SequenceCheckerImpl);
};
diff --git a/base/sequence_checker_impl_unittest.cc b/base/sequence_checker_impl_unittest.cc
new file mode 100644
index 0000000..b05da11
--- /dev/null
+++ b/base/sequence_checker_impl_unittest.cc
@@ -0,0 +1,218 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/sequence_checker_impl.h"
+
+#include <cstddef>
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/location.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+namespace {
+
+// Implementation of SequencedTaskRunner that lets us control what
+// RunsTasksOnCurrentThread() returns.
+class FakeTaskRunner : public SequencedTaskRunner {
+ public:
+ FakeTaskRunner() : runs_tasks_on_current_thread_(false) {}
+
+ void SetRunsTasksOnCurrentThread(bool runs_tasks_on_current_thread) {
+ runs_tasks_on_current_thread_ = runs_tasks_on_current_thread;
+ }
+
+ // SequencedTaskRunner implementation.
+ virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay) OVERRIDE {
+ ADD_FAILURE();
+ return false;
+ }
+
+ virtual bool PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ TimeDelta delay) OVERRIDE {
+ ADD_FAILURE();
+ return false;
+ }
+
+ virtual bool RunsTasksOnCurrentThread() const OVERRIDE {
+ return runs_tasks_on_current_thread_;
+ }
+
+ protected:
+ virtual ~FakeTaskRunner() {}
+
+ private:
+ bool runs_tasks_on_current_thread_;
+};
+
+class SequenceCheckerImplTest : public ::testing::Test {
+};
+
+// Create a SequenceCheckerImpl with a SequencedTaskRunner and make
+// sure that CalledOnValidSequence() returns what that SequencedTaskRunner
+// returns for RunsTasksOnCurrentThread().
+TEST_F(SequenceCheckerImplTest, CalledOnValidSequenceNonNull) {
+ const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner(
+ new FakeTaskRunner());
+
+ const SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner);
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+
+ fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(true);
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+
+ fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(false);
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+}
+
+void ExpectCalledOnValidSequence(
+ const tracked_objects::Location& location,
+ const SequenceCheckerImpl* sequence_checker_impl,
+ bool expected_value) {
+ EXPECT_EQ(expected_value, sequence_checker_impl->CalledOnValidSequence())
+ << location.ToString();
+}
+
+// Create a SequenceCheckerImpl with no SequencedTaskRunner and make
+// sure that CalledOnValidSequence() behaves like
+// ThreadChecker::CalledOnValidThread().
+TEST_F(SequenceCheckerImplTest, CalledOnValidSequenceNull) {
+ const SequenceCheckerImpl sequence_checker_impl(NULL);
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+
+ {
+ Thread thread("thread 1");
+ ASSERT_TRUE(thread.Start());
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&ExpectCalledOnValidSequence,
+ FROM_HERE,
+ Unretained(&sequence_checker_impl),
+ false));
+ }
+
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+}
+
+// Create a SequenceCheckerImpl with a SequencedTaskRunner and switch
+// it to another one. CalledOnValidSequence() should return what its
+// underlying SequencedTaskRunner returns for
+// RunsTasksOnCurrentThread().
+TEST_F(SequenceCheckerImplTest, ChangeSequenceNonNull) {
+ const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner1(
+ new FakeTaskRunner());
+
+ const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner2(
+ new FakeTaskRunner());
+
+ SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner1);
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+
+ fake_sequenced_task_runner2->SetRunsTasksOnCurrentThread(true);
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+
+ sequence_checker_impl.ChangeSequence(fake_sequenced_task_runner2);
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+
+ sequence_checker_impl.ChangeSequence(fake_sequenced_task_runner1);
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+}
+
+// Create a SequenceCheckerImpl with a SequencedTaskRunner and switch
+// it to a NULL one. CalledOnValidSequence() should then behave like
+// ThreadChecker::CalledOnValidThread().
+TEST_F(SequenceCheckerImplTest, ChangeSequenceNull) {
+ const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner(
+ new FakeTaskRunner());
+
+ SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner);
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+
+ sequence_checker_impl.ChangeSequence(NULL);
+ // Binds to current thread.
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+ {
+ Thread thread("thread 1");
+ ASSERT_TRUE(thread.Start());
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&ExpectCalledOnValidSequence,
+ FROM_HERE,
+ Unretained(&sequence_checker_impl),
+ false));
+ }
+
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+
+ sequence_checker_impl.ChangeSequence(NULL);
+ // Binds to worker thread.
+ {
+ Thread thread("thread 2");
+ ASSERT_TRUE(thread.Start());
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&ExpectCalledOnValidSequence,
+ FROM_HERE,
+ Unretained(&sequence_checker_impl),
+ true));
+ }
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+}
+
+// Create a SequenceCheckerImpl with the current thread's task runner
+// and switch it to other task runners. CalledOnValidSequence() should
+// return true only when it's on the correct thread.
+TEST_F(SequenceCheckerImplTest, MultipleThreads) {
+ MessageLoop loop;
+
+ SequenceCheckerImpl sequence_checker_impl(loop.message_loop_proxy());
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+
+ {
+ Thread thread("thread 1");
+ ASSERT_TRUE(thread.Start());
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&ExpectCalledOnValidSequence,
+ FROM_HERE,
+ Unretained(&sequence_checker_impl),
+ false));
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&SequenceCheckerImpl::ChangeSequence,
+ Unretained(&sequence_checker_impl),
+ thread.message_loop_proxy()));
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&ExpectCalledOnValidSequence,
+ FROM_HERE,
+ Unretained(&sequence_checker_impl),
+ true));
+ }
+
+ EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence());
+
+ sequence_checker_impl.ChangeSequence(loop.message_loop_proxy());
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+
+ {
+ Thread thread("thread 2");
+ ASSERT_TRUE(thread.Start());
+ thread.message_loop()->PostTask(
+ FROM_HERE, Bind(&ExpectCalledOnValidSequence,
+ FROM_HERE,
+ Unretained(&sequence_checker_impl),
+ false));
+ }
+
+ EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence());
+}
+
+} // namespace
+
+} // namespace base
diff --git a/base/sequence_checker_unittest.cc b/base/sequence_checker_unittest.cc
index e093fa8..4fc3027 100644
--- a/base/sequence_checker_unittest.cc
+++ b/base/sequence_checker_unittest.cc
@@ -1,329 +1,29 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
#include "base/sequence_checker.h"
-#include "base/test/sequenced_worker_pool_owner.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-// Duplicated from base/sequence_checker.h so that we can be good citizens
-// there and undef the macro.
-#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
-#define ENABLE_SEQUENCE_CHECKER 1
-#else
-#define ENABLE_SEQUENCE_CHECKER 0
-#endif
+#include <cstddef>
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/test/null_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
-const size_t kNumWorkerThreads = 3;
-
-// Simple class to exercise the basics of SequenceChecker.
-// DoStuff should verify that it's called on a valid sequenced thread.
-// SequenceCheckedObject can be destroyed on any thread (like WeakPtr).
-class SequenceCheckedObject {
- public:
- SequenceCheckedObject() {}
- ~SequenceCheckedObject() {}
-
- // Verifies that it was called on the same thread as the constructor.
- void DoStuff() {
- DCHECK(sequence_checker_.CalledOnValidSequencedThread());
- }
-
- void DetachFromSequence() {
- sequence_checker_.DetachFromSequence();
- }
-
- private:
- SequenceChecker sequence_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(SequenceCheckedObject);
-};
-
-class SequenceCheckerTest : public testing::Test {
- public:
- SequenceCheckerTest() : other_thread_("sequence_checker_test_other_thread") {}
-
- virtual ~SequenceCheckerTest() {}
-
- virtual void SetUp() OVERRIDE {
- other_thread_.Start();
- ResetPool();
- }
-
- virtual void TearDown() OVERRIDE {
- other_thread_.Stop();
- pool()->Shutdown();
- }
-
- protected:
- base::Thread* other_thread() { return &other_thread_; }
-
- const scoped_refptr<SequencedWorkerPool>& pool() {
- return pool_owner_->pool();
- }
-
- void PostDoStuffToWorkerPool(SequenceCheckedObject* sequence_checked_object,
- const std::string& token_name) {
- pool()->PostNamedSequencedWorkerTask(
- token_name,
- FROM_HERE,
- base::Bind(&SequenceCheckedObject::DoStuff,
- base::Unretained(sequence_checked_object)));
- }
-
- void PostDoStuffToOtherThread(
- SequenceCheckedObject* sequence_checked_object) {
- other_thread()->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&SequenceCheckedObject::DoStuff,
- base::Unretained(sequence_checked_object)));
- }
-
- void PostDeleteToOtherThread(
- scoped_ptr<SequenceCheckedObject> sequence_checked_object) {
- other_thread()->message_loop()->DeleteSoon(
- FROM_HERE,
- sequence_checked_object.release());
- }
-
- // Destroys the SequencedWorkerPool instance, blocking until it is fully shut
- // down, and creates a new instance.
- void ResetPool() {
- pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test"));
- }
-
- void MethodOnDifferentThreadDeathTest();
- void DetachThenCallFromDifferentThreadDeathTest();
- void DifferentSequenceTokensDeathTest();
- void WorkerPoolAndSimpleThreadDeathTest();
- void TwoDifferentWorkerPoolsDeathTest();
-
- private:
- MessageLoop message_loop_; // Needed by SequencedWorkerPool to function.
- base::Thread other_thread_;
- scoped_ptr<SequencedWorkerPoolOwner> pool_owner_;
-};
-
-TEST_F(SequenceCheckerTest, CallsAllowedOnSameThread) {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- // Verify that DoStuff doesn't assert.
- sequence_checked_object->DoStuff();
-
- // Verify that the destructor doesn't assert.
- sequence_checked_object.reset();
+// Call various methods of SequenceChecker to make sure nothing blows
+// up in either debug or release mode.
+TEST(SequenceCheckerTest, Basic) {
+ SequenceChecker sequence_checker(new NullTaskRunner());
+ sequence_checker.CalledOnValidSequence();
+ sequence_checker.ChangeSequence(NULL);
+ sequence_checker.CalledOnValidSequence();
}
-TEST_F(SequenceCheckerTest, DestructorAllowedOnDifferentThread) {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- // Verify the destructor doesn't assert when called on a different thread.
- PostDeleteToOtherThread(sequence_checked_object.Pass());
- other_thread()->Stop();
-}
-
-TEST_F(SequenceCheckerTest, DetachFromSequence) {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- // Verify that DoStuff doesn't assert when called on a different thread after
- // a call to DetachFromSequence.
- sequence_checked_object->DetachFromSequence();
-
- PostDoStuffToOtherThread(sequence_checked_object.get());
- other_thread()->Stop();
-}
-
-TEST_F(SequenceCheckerTest, SameSequenceTokenValid) {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- pool()->FlushForTesting();
-
- PostDeleteToOtherThread(sequence_checked_object.Pass());
- other_thread()->Stop();
-}
-
-TEST_F(SequenceCheckerTest, DetachSequenceTokenValid) {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- pool()->FlushForTesting();
-
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
- pool()->FlushForTesting();
-
- PostDeleteToOtherThread(sequence_checked_object.Pass());
- other_thread()->Stop();
-}
-
-#if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER
-
-void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- // DoStuff should assert in debug builds only when called on a
- // different thread.
- PostDoStuffToOtherThread(sequence_checked_object.get());
- other_thread()->Stop();
-}
-
-#if ENABLE_SEQUENCE_CHECKER
-TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) {
- ASSERT_DEATH({
- MethodOnDifferentThreadDeathTest();
- }, "");
-}
-#else
-TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) {
- MethodOnDifferentThreadDeathTest();
-}
-#endif // ENABLE_SEQUENCE_CHECKER
-
-void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- // DoStuff doesn't assert when called on a different thread
- // after a call to DetachFromSequence.
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToOtherThread(sequence_checked_object.get());
- other_thread()->Stop();
-
- // DoStuff should assert in debug builds only after moving to
- // another thread.
- sequence_checked_object->DoStuff();
-}
-
-#if ENABLE_SEQUENCE_CHECKER
-TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) {
- ASSERT_DEATH({
- DetachThenCallFromDifferentThreadDeathTest();
- }, "");
-}
-#else
-TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) {
- DetachThenCallFromDifferentThreadDeathTest();
-}
-#endif // ENABLE_SEQUENCE_CHECKER
-
-void SequenceCheckerTest::DifferentSequenceTokensDeathTest() {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
- pool()->FlushForTesting();
-
- PostDeleteToOtherThread(sequence_checked_object.Pass());
- other_thread()->Stop();
-}
-
-#if ENABLE_SEQUENCE_CHECKER
-TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) {
- ASSERT_DEATH({
- DifferentSequenceTokensDeathTest();
- }, "");
-}
-#else
-TEST_F(SequenceCheckerTest,
- DifferentSequenceTokensDeathTestInRelease) {
- DifferentSequenceTokensDeathTest();
-}
-#endif // ENABLE_SEQUENCE_CHECKER
-
-void SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- pool()->FlushForTesting();
-
- PostDoStuffToOtherThread(sequence_checked_object.get());
- other_thread()->Stop();
-}
-
-#if ENABLE_SEQUENCE_CHECKER
-TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) {
- ASSERT_DEATH({
- WorkerPoolAndSimpleThreadDeathTest();
- }, "");
-}
-#else
-TEST_F(SequenceCheckerTest,
- WorkerPoolAndSimpleThreadDeathTestInRelease) {
- WorkerPoolAndSimpleThreadDeathTest();
-}
-#endif // ENABLE_SEQUENCE_CHECKER
-
-void SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() {
- scoped_ptr<SequenceCheckedObject> sequence_checked_object(
- new SequenceCheckedObject);
-
- sequence_checked_object->DetachFromSequence();
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
- pool()->FlushForTesting();
-
- SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2");
- second_pool_owner.pool()->PostNamedSequencedWorkerTask(
- "A",
- FROM_HERE,
- base::Bind(&SequenceCheckedObject::DoStuff,
- base::Unretained(sequence_checked_object.get())));
- second_pool_owner.pool()->FlushForTesting();
- second_pool_owner.pool()->Shutdown();
-}
-
-#if ENABLE_SEQUENCE_CHECKER
-TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) {
- ASSERT_DEATH({
- TwoDifferentWorkerPoolsDeathTest();
- }, "");
-}
-#else
-TEST_F(SequenceCheckerTest,
- TwoDifferentWorkerPoolsDeathTestInRelease) {
- TwoDifferentWorkerPoolsDeathTest();
-}
-#endif // ENABLE_SEQUENCE_CHECKER
-
-#endif // GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER
-
} // namespace
} // namespace base
-
-// Just in case we ever get lumped together with other compilation units.
-#undef ENABLE_SEQUENCE_CHECKER
diff --git a/base/shared_memory.h b/base/shared_memory.h
deleted file mode 100644
index feb04ea..0000000
--- a/base/shared_memory.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(brettw) remove this forwarding file when all users reference the new
-// location.
-#include "base/memory/shared_memory.h"
diff --git a/base/synchronization/cancellation_flag_unittest.cc b/base/synchronization/cancellation_flag_unittest.cc
index 36b8722..02b08b6 100644
--- a/base/synchronization/cancellation_flag_unittest.cc
+++ b/base/synchronization/cancellation_flag_unittest.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/synchronization/spin_wait.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
diff --git a/base/synchronization/waitable_event_watcher.h b/base/synchronization/waitable_event_watcher.h
index f2f5f04..ede2835 100644
--- a/base/synchronization/waitable_event_watcher.h
+++ b/base/synchronization/waitable_event_watcher.h
@@ -12,7 +12,7 @@
#include "base/win/object_watcher.h"
#else
#include "base/callback.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#endif
diff --git a/base/synchronization/waitable_event_watcher_posix.cc b/base/synchronization/waitable_event_watcher_posix.cc
index a8821b3..54e01f8 100644
--- a/base/synchronization/waitable_event_watcher_posix.cc
+++ b/base/synchronization/waitable_event_watcher_posix.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/location.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
diff --git a/base/synchronization/waitable_event_watcher_unittest.cc b/base/synchronization/waitable_event_watcher_unittest.cc
index fbdc424..5319d1e 100644
--- a/base/synchronization/waitable_event_watcher_unittest.cc
+++ b/base/synchronization/waitable_event_watcher_unittest.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/callback.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
diff --git a/base/system_monitor/system_monitor.cc b/base/system_monitor/system_monitor.cc
index d11ffc0..11dd000 100644
--- a/base/system_monitor/system_monitor.cc
+++ b/base/system_monitor/system_monitor.cc
@@ -7,7 +7,7 @@
#include <utility>
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
namespace base {
diff --git a/base/system_monitor/system_monitor_unittest.cc b/base/system_monitor/system_monitor_unittest.cc
index b46e52f..e49405e 100644
--- a/base/system_monitor/system_monitor_unittest.cc
+++ b/base/system_monitor/system_monitor_unittest.cc
@@ -4,7 +4,7 @@
#include "base/system_monitor/system_monitor.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/mock_devices_changed_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/base/task_runner_util_unittest.cc b/base/task_runner_util_unittest.cc
index ef158f3..0474394 100644
--- a/base/task_runner_util_unittest.cc
+++ b/base/task_runner_util_unittest.cc
@@ -5,7 +5,7 @@
#include "base/task_runner_util.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/test/sequenced_worker_pool_owner.cc b/base/test/sequenced_worker_pool_owner.cc
index ea31441..f6a0d01 100644
--- a/base/test/sequenced_worker_pool_owner.cc
+++ b/base/test/sequenced_worker_pool_owner.cc
@@ -5,7 +5,7 @@
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/location.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
namespace base {
diff --git a/base/test/test_support_android.cc b/base/test/test_support_android.cc
index e044322..1ad4c2b 100644
--- a/base/test/test_support_android.cc
+++ b/base/test/test_support_android.cc
@@ -72,6 +72,8 @@
// The MessagePumpForUI implementation for test purpose.
class MessagePumpForUIStub : public base::MessagePumpForUI {
+ virtual ~MessagePumpForUIStub() {}
+
virtual void Start(base::MessagePump::Delegate* delegate) OVERRIDE {
NOTREACHED() << "The Start() method shouldn't be called in test, using"
" Run() method should be used.";
@@ -129,9 +131,6 @@
const base::TimeTicks& delayed_work_time) OVERRIDE {
Waitable::GetInstance()->Signal();
}
-
- protected:
- virtual ~MessagePumpForUIStub() {}
};
base::MessagePump* CreateMessagePumpForUIStub() {
diff --git a/base/threading/sequenced_worker_pool_unittest.cc b/base/threading/sequenced_worker_pool_unittest.cc
index eb63058..a07fd47 100644
--- a/base/threading/sequenced_worker_pool_unittest.cc
+++ b/base/threading/sequenced_worker_pool_unittest.cc
@@ -10,7 +10,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
diff --git a/base/threading/thread.h b/base/threading/thread.h
index 0944e1e..98831b8 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/base_export.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/platform_thread.h"
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc
index 5945e32..8bd817c 100644
--- a/base/threading/thread_unittest.cc
+++ b/base/threading/thread_unittest.cc
@@ -7,7 +7,7 @@
#include <vector>
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
diff --git a/base/threading/worker_pool_unittest.cc b/base/threading/worker_pool_unittest.cc
index 3b19c09..9a9ab95 100644
--- a/base/threading/worker_pool_unittest.cc
+++ b/base/threading/worker_pool_unittest.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
diff --git a/base/time/time.cc b/base/time/time.cc
index 1a3f6c3..5f495e3 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -5,24 +5,15 @@
#include "base/time/time.h"
#include <math.h>
-#if defined(OS_WIN)
-#include <float.h>
-#endif
-
#include <limits>
+#include "base/float_util.h"
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#include "base/third_party/nspr/prtime.h"
namespace base {
-namespace {
-#if defined(OS_WIN)
-inline bool isnan(double num) { return !!_isnan(num); }
-#endif
-}
-
// TimeDelta ------------------------------------------------------------------
int TimeDelta::InDays() const {
@@ -95,7 +86,7 @@
// static
Time Time::FromDoubleT(double dt) {
- if (dt == 0 || isnan(dt))
+ if (dt == 0 || IsNaN(dt))
return Time(); // Preserve 0 so we can tell it doesn't exist.
if (dt == std::numeric_limits<double>::max())
return Max();
diff --git a/base/timer/hi_res_timer_manager_unittest.cc b/base/timer/hi_res_timer_manager_unittest.cc
index 0017859..7ae6ab1 100644
--- a/base/timer/hi_res_timer_manager_unittest.cc
+++ b/base/timer/hi_res_timer_manager_unittest.cc
@@ -5,7 +5,7 @@
#include "base/timer/hi_res_timer_manager.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
index 0a4cbbd..417d258 100644
--- a/base/timer/timer_unittest.cc
+++ b/base/timer/timer_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/timer/timer.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/tools_sanity_unittest.cc b/base/tools_sanity_unittest.cc
index 006d142..ff78938 100644
--- a/base/tools_sanity_unittest.cc
+++ b/base/tools_sanity_unittest.cc
@@ -7,7 +7,7 @@
// errors to verify the sanity of the tools.
#include "base/atomicops.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/upload_list.cc b/base/upload_list.cc
new file mode 100644
index 0000000..50aa817
--- /dev/null
+++ b/base/upload_list.cc
@@ -0,0 +1,98 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/upload_list.h"
+
+#include <algorithm>
+#include <iterator>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/threading/sequenced_worker_pool.h"
+
+namespace base {
+
+UploadList::UploadInfo::UploadInfo(const std::string& c, const Time& t)
+ : id(c), time(t) {}
+
+UploadList::UploadInfo::~UploadInfo() {}
+
+UploadList::UploadList(Delegate* delegate,
+ const FilePath& upload_log_path,
+ SingleThreadTaskRunner* task_runner)
+ : delegate_(delegate),
+ upload_log_path_(upload_log_path),
+ task_runner_(task_runner) {}
+
+UploadList::~UploadList() {}
+
+void UploadList::LoadUploadListAsynchronously(
+ base::SequencedWorkerPool* worker_pool) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ worker_pool->PostWorkerTask(
+ FROM_HERE,
+ Bind(&UploadList::LoadUploadListAndInformDelegateOfCompletion, this));
+}
+
+void UploadList::ClearDelegate() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ delegate_ = NULL;
+}
+
+void UploadList::LoadUploadListAndInformDelegateOfCompletion() {
+ LoadUploadList();
+ task_runner_->PostTask(
+ FROM_HERE, Bind(&UploadList::InformDelegateOfCompletion, this));
+}
+
+void UploadList::LoadUploadList() {
+ if (PathExists(upload_log_path_)) {
+ std::string contents;
+ file_util::ReadFileToString(upload_log_path_, &contents);
+ std::vector<std::string> log_entries;
+ SplitStringAlongWhitespace(contents, &log_entries);
+ ParseLogEntries(log_entries);
+ }
+}
+
+void UploadList::AppendUploadInfo(const UploadInfo& info) {
+ uploads_.push_back(info);
+}
+
+void UploadList::ParseLogEntries(
+ const std::vector<std::string>& log_entries) {
+ std::vector<std::string>::const_reverse_iterator i;
+ for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) {
+ std::vector<std::string> components;
+ SplitString(*i, ',', &components);
+ // Skip any blank (or corrupted) lines.
+ if (components.size() != 2)
+ continue;
+ double seconds_since_epoch;
+ if (!StringToDouble(components[0], &seconds_since_epoch))
+ continue;
+ UploadInfo info(components[1], Time::FromDoubleT(seconds_since_epoch));
+ uploads_.push_back(info);
+ }
+}
+
+void UploadList::InformDelegateOfCompletion() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (delegate_)
+ delegate_->OnUploadListAvailable();
+}
+
+void UploadList::GetUploads(unsigned int max_count,
+ std::vector<UploadInfo>* uploads) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ std::copy(uploads_.begin(),
+ uploads_.begin() + std::min<size_t>(uploads_.size(), max_count),
+ std::back_inserter(*uploads));
+}
+
+} // namespace base
diff --git a/base/upload_list.h b/base/upload_list.h
new file mode 100644
index 0000000..dd136f0
--- /dev/null
+++ b/base/upload_list.h
@@ -0,0 +1,99 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_UPLOAD_LIST_H_
+#define BASE_UPLOAD_LIST_H_
+
+#include <string>
+#include <vector>
+
+#include "base/base_export.h"
+#include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+
+namespace base {
+
+class SingleThreadTaskRunner;
+class SequencedWorkerPool;
+
+// Loads and parses an upload list text file of the format
+// time,id
+// time,id
+// etc.
+// where each line represents an upload and "time" is Unix time. Must be used
+// from the UI thread. The loading and parsing is done on a blocking pool task
+// runner.
+class BASE_EXPORT UploadList : public RefCountedThreadSafe<UploadList> {
+ public:
+ struct BASE_EXPORT UploadInfo {
+ UploadInfo(const std::string& c, const Time& t);
+ ~UploadInfo();
+
+ std::string id;
+ Time time;
+ };
+
+ class Delegate {
+ public:
+ // Invoked when the upload list has been loaded. Will be called on the
+ // UI thread.
+ virtual void OnUploadListAvailable() = 0;
+
+ protected:
+ virtual ~Delegate() {}
+ };
+
+ // Creates a new upload list with the given callback delegate.
+ UploadList(Delegate* delegate,
+ const FilePath& upload_log_path,
+ SingleThreadTaskRunner* task_runner);
+
+ // Starts loading the upload list. OnUploadListAvailable will be called when
+ // loading is complete.
+ void LoadUploadListAsynchronously(SequencedWorkerPool* worker_pool);
+
+ // Clears the delegate, so that any outstanding asynchronous load will not
+ // call the delegate on completion.
+ void ClearDelegate();
+
+ // Populates |uploads| with the |max_count| most recent uploads,
+ // in reverse chronological order.
+ // Must be called only after OnUploadListAvailable has been called.
+ void GetUploads(unsigned int max_count, std::vector<UploadInfo>* uploads);
+
+ protected:
+ virtual ~UploadList();
+
+ // Reads the upload log and stores the entries in |uploads_|.
+ virtual void LoadUploadList();
+
+ // Adds |info| to |uploads_|.
+ void AppendUploadInfo(const UploadInfo& info);
+
+ private:
+ friend class RefCountedThreadSafe<UploadList>;
+ FRIEND_TEST_ALL_PREFIXES(UploadListTest, ParseLogEntries);
+
+ // Manages the background thread work for LoadUploadListAsynchronously().
+ void LoadUploadListAndInformDelegateOfCompletion();
+
+ // Calls the delegate's callback method, if there is a delegate.
+ void InformDelegateOfCompletion();
+
+ // Parses upload log lines, converting them to UploadInfo entries.
+ void ParseLogEntries(const std::vector<std::string>& log_entries);
+
+ std::vector<UploadInfo> uploads_;
+ Delegate* delegate_;
+ const FilePath upload_log_path_;
+ SingleThreadTaskRunner* task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(UploadList);
+};
+
+} // namespace base
+
+#endif // BASE_UPLOAD_LIST_H_
diff --git a/base/upload_list_unittest.cc b/base/upload_list_unittest.cc
new file mode 100644
index 0000000..41e1782
--- /dev/null
+++ b/base/upload_list_unittest.cc
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
+#include "base/upload_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+// Test that UploadList can parse a vector of log entry strings to a vector of
+// UploadInfo objects. See the UploadList declaration for a description of the
+// log entry string format.
+TEST(UploadListTest, ParseLogEntries) {
+ const char kTestTime[] = "1234567890";
+ const char kTestID[] = "0123456789abcdef";
+ std::string test_entry = kTestTime;
+ test_entry += ",";
+ test_entry.append(kTestID, sizeof(kTestID));
+
+ scoped_refptr<UploadList> upload_list =
+ new UploadList(NULL, base::FilePath(), MessageLoopProxy::current());
+
+ // 1 entry.
+ std::vector<std::string> log_entries;
+ log_entries.push_back(test_entry);
+ upload_list->ParseLogEntries(log_entries);
+ EXPECT_EQ(1u, upload_list->uploads_.size());
+ double time_double = upload_list->uploads_[0].time.ToDoubleT();
+ EXPECT_STREQ(kTestTime, base::DoubleToString(time_double).c_str());
+ EXPECT_STREQ(kTestID, upload_list->uploads_[0].id.c_str());
+
+ // Add 3 more entries.
+ log_entries.push_back(test_entry);
+ log_entries.push_back(test_entry);
+ upload_list->ParseLogEntries(log_entries);
+ EXPECT_EQ(4u, upload_list->uploads_.size());
+ time_double = upload_list->uploads_[3].time.ToDoubleT();
+ EXPECT_STREQ(kTestTime, base::DoubleToString(time_double).c_str());
+ EXPECT_STREQ(kTestID, upload_list->uploads_[3].id.c_str());
+}
+
+} // namespace base
diff --git a/base/win/metro.cc b/base/win/metro.cc
index acf530f..afe4fce 100644
--- a/base/win/metro.cc
+++ b/base/win/metro.cc
@@ -4,7 +4,7 @@
#include "base/win/metro.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h
index 742f2b0..4222c20 100644
--- a/base/win/object_watcher.h
+++ b/base/win/object_watcher.h
@@ -10,7 +10,7 @@
#include "base/base_export.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
namespace base {
namespace win {
diff --git a/base/win/object_watcher_unittest.cc b/base/win/object_watcher_unittest.cc
index df66646..46b98de 100644
--- a/base/win/object_watcher_unittest.cc
+++ b/base/win/object_watcher_unittest.cc
@@ -6,7 +6,7 @@
#include <process.h>
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/win/wrapped_window_proc_unittest.cc b/base/win/wrapped_window_proc_unittest.cc
index ccf3c85..161c913 100644
--- a/base/win/wrapped_window_proc_unittest.cc
+++ b/base/win/wrapped_window_proc_unittest.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/message_loop/message_loop.h"
#include "base/win/wrapped_window_proc.h"
-#include "base/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {