Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Unified Diff: base/message_loop/message_loop.h

Issue 1011683002: Lazily initialize MessageLoop for faster thread startup (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: non-blocking thread_id() Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/message_loop/message_loop.h
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index fd7596a79204ed89291f32b2f9135108a73b2882..352e9b04dfba2552363d14ed635c05ef42444786 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -109,14 +109,78 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
#endif // defined(OS_ANDROID)
};
+ // Init options for CreateForLazyInit().
+ struct BASE_EXPORT LazyInitOptions {
+ using MessagePumpFactory = Callback<scoped_ptr<MessagePump>()>;
+ LazyInitOptions();
+ ~LazyInitOptions();
+
+ // Specify the type of message loop that will be initialized in LazyInit.
+ // This is ignored if message_pump_factory.is_null() is false.
+ MessageLoop::Type message_loop_type;
+
+ // Specify timer slack for the message loop.
+ TimerSlack timer_slack;
+
+ // Used to create the MessagePump for the MessageLoop in LazyInit.
+ // If message_pump_factory.is_null() is true, then a MessagePump appropriate
+ // for |message_loop_type| is created. Setting this forces the
+ // MessageLoop::Type to TYPE_CUSTOM.
+ MessagePumpFactory message_pump_factory;
+ };
+
// Normally, it is not necessary to instantiate a MessageLoop. Instead, it
// is typical to make use of the current thread's MessageLoop instance.
explicit MessageLoop(Type type = TYPE_DEFAULT);
// Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must
// be non-NULL.
- explicit MessageLoop(scoped_ptr<base::MessagePump> pump);
+ explicit MessageLoop(scoped_ptr<MessagePump> pump);
~MessageLoop() override;
+ // Creates a MessageLoop for lazy initialization. This can be called on a
+ // different thread from the final 'current' thread of this message loop
+ // to pre-construct a message loop that accepts incoming tasks before
+ // the thread becomes ready to run. The caller must call LazyInit method
+ // on the final 'current' thread before calling Run to start running
+ // tasks.
+ //
+ // Note that until LazyInit() is called on the final 'current' thread
+ // only "PostTask" family methods can be called to 'queue' a task.
+ // Usually this should not be a problem in production code, because
+ // almost all other methods (except for ScheduleWork) are allowed to be
+ // called only on the final 'current' thread where the message loop's Run
+ // method runs, and no tasks can run there until the message loop actually
+ // spins up and calls Run, which must happen after LazyInit.
+ //
+ // Typical usage of CreateForLazyInit should look like following:
+ //
+ // // On the calling thread:
+ // {
+ // scoped_ptr<MessageLoop::LazyInitOptions> options(new
+ // MessageLoop::LazyInitOptions);
+ // options->message_loop_type = YOUR_MESSAGE_LOOP_TYPE;
+ // options->timer_slack = YOUR_TIMER_SLACK;
+ // ...
+ //
+ // message_loop_ = MessageLoop::CreateForLazyInit(options.Pass());
+ // // Right after here the caller can start posting tasks to this
+ // // message loop, though it won't run until LazyInit and Run is
+ // // called on the target thread.
+ //
+ // PlatformThread::Create(...);
+ // }
+ //
+ // // On the target thread where the message loop actually runs:
+ // void ThreadMain() {
+ // // Do the remaining initialization. This also sets up current().
+ // message_loop_->LazyInit();
+ //
+ // // Start running the loop.
+ // message_loop_->Run();
+ // }
+ //
+ static MessageLoop* CreateForLazyInit(scoped_ptr<LazyInitOptions> options);
rvargas (doing something else) 2015/03/26 02:19:27 should return a scoped_ptr
rvargas (doing something else) 2015/03/26 02:19:27 nit: Do we really need the "ForLazyInit" part?. Th
kinuko 2015/04/13 02:02:59 Done.
+
// Returns the MessageLoop object for the current thread, or null if none.
static MessageLoop* current();
@@ -147,6 +211,13 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
virtual ~DestructionObserver();
};
+ // Configure various members and bind this message loop to the current thread.
+ // This must be called on the final 'current' thread of this message loop.
+ // It is not valid to call this unless this message loop is constructed by
+ // CreateForLazyInit.
+ // (See the comment at CreateForLazyInit for more details)
+ void LazyInit();
+
// Add a DestructionObserver, which will start receiving notifications
// immediately.
void AddDestructionObserver(DestructionObserver* destruction_observer);
@@ -412,7 +483,10 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
private:
friend class RunLoop;
- // Configures various members for the two constructors.
+ // Private constructor for CreateForLazyInit().
+ explicit MessageLoop(scoped_ptr<LazyInitOptions> options);
+
+ // Configures various members for the two public constructors.
void Init();
// Invokes the actual run loop using the message pump.
@@ -490,6 +564,9 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
bool os_modal_loop_;
#endif
+ // Non-null only when this message loop is constructed by CreateForLazyInit.
+ scoped_ptr<LazyInitOptions> lazy_init_options_;
+
std::string thread_name_;
// A profiling histogram showing the counts of various messages and events.
HistogramBase* message_histogram_;

Powered by Google App Engine
This is Rietveld 408576698