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

Side by Side Diff: base/message_loop/message_loop.h

Issue 17567007: Made MessagePump a non-thread safe class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved incoming_queue_ to MessageLoopProxyImpl Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
7 7
8 #include <queue> 8 #include <queue>
9 #include <string> 9 #include <string>
10 10
11 #include "base/base_export.h" 11 #include "base/base_export.h"
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/callback_forward.h" 13 #include "base/callback_forward.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_loop_proxy.h" 17 #include "base/message_loop/message_loop_proxy.h"
17 #include "base/message_loop/message_pump.h" 18 #include "base/message_loop/message_pump.h"
18 #include "base/observer_list.h" 19 #include "base/observer_list.h"
19 #include "base/pending_task.h" 20 #include "base/pending_task.h"
20 #include "base/sequenced_task_runner_helpers.h" 21 #include "base/sequenced_task_runner_helpers.h"
21 #include "base/synchronization/lock.h" 22 #include "base/synchronization/lock.h"
22 #include "base/tracking_info.h" 23 #include "base/tracking_info.h"
23 #include "base/time.h" 24 #include "base/time.h"
24 25
25 #if defined(OS_WIN) 26 #if defined(OS_WIN)
(...skipping 14 matching lines...) Expand all
40 #include "base/message_loop/message_pump_gtk.h" 41 #include "base/message_loop/message_pump_gtk.h"
41 #endif 42 #endif
42 43
43 #endif 44 #endif
44 #endif 45 #endif
45 46
46 namespace base { 47 namespace base {
47 48
48 class HistogramBase; 49 class HistogramBase;
49 class MessageLoopLockTest; 50 class MessageLoopLockTest;
51 class MessageLoopProxyImpl;
50 class RunLoop; 52 class RunLoop;
51 class ThreadTaskRunnerHandle; 53 class ThreadTaskRunnerHandle;
52 #if defined(OS_ANDROID) 54 #if defined(OS_ANDROID)
53 class MessagePumpForUI; 55 class MessagePumpForUI;
54 #endif 56 #endif
55 57
56 // A MessageLoop is used to process events for a particular thread. There is 58 // A MessageLoop is used to process events for a particular thread. There is
57 // at most one MessageLoop instance per thread. 59 // at most one MessageLoop instance per thread.
58 // 60 //
59 // Events include at a minimum Task instances submitted to PostTask and its 61 // Events include at a minimum Task instances submitted to PostTask and its
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 Type type() const { return type_; } 277 Type type() const { return type_; }
276 278
277 // Optional call to connect the thread name with this loop. 279 // Optional call to connect the thread name with this loop.
278 void set_thread_name(const std::string& thread_name) { 280 void set_thread_name(const std::string& thread_name) {
279 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; 281 DCHECK(thread_name_.empty()) << "Should not rename this thread!";
280 thread_name_ = thread_name; 282 thread_name_ = thread_name;
281 } 283 }
282 const std::string& thread_name() const { return thread_name_; } 284 const std::string& thread_name() const { return thread_name_; }
283 285
284 // Gets the message loop proxy associated with this message loop. 286 // Gets the message loop proxy associated with this message loop.
285 scoped_refptr<MessageLoopProxy> message_loop_proxy() { 287 scoped_refptr<MessageLoopProxy> message_loop_proxy();
286 return message_loop_proxy_.get();
287 }
288 288
289 // Enables or disables the recursive task processing. This happens in the case 289 // Enables or disables the recursive task processing. This happens in the case
290 // of recursive message loops. Some unwanted message loop may occurs when 290 // of recursive message loops. Some unwanted message loop may occurs when
291 // using common controls or printer functions. By default, recursive task 291 // using common controls or printer functions. By default, recursive task
292 // processing is disabled. 292 // processing is disabled.
293 // 293 //
294 // Please utilize |ScopedNestableTaskAllower| instead of calling these methods 294 // Please utilize |ScopedNestableTaskAllower| instead of calling these methods
295 // directly. In general nestable message loops are to be avoided. They are 295 // directly. In general nestable message loops are to be avoided. They are
296 // dangerous and difficult to get right, so please use with extreme caution. 296 // dangerous and difficult to get right, so please use with extreme caution.
297 // 297 //
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 352
353 protected: 353 protected:
354 virtual ~TaskObserver(); 354 virtual ~TaskObserver();
355 }; 355 };
356 356
357 // These functions can only be called on the same thread that |this| is 357 // These functions can only be called on the same thread that |this| is
358 // running on. 358 // running on.
359 void AddTaskObserver(TaskObserver* task_observer); 359 void AddTaskObserver(TaskObserver* task_observer);
360 void RemoveTaskObserver(TaskObserver* task_observer); 360 void RemoveTaskObserver(TaskObserver* task_observer);
361 361
362 // Returns true if the message loop has high resolution timers enabled.
363 // Provided for testing.
364 bool high_resolution_timers_enabled() {
365 #if defined(OS_WIN)
366 return !high_resolution_timer_expiration_.is_null();
367 #else
368 return true;
369 #endif
370 }
371
372 // When we go into high resolution timer mode, we will stay in hi-res mode 362 // When we go into high resolution timer mode, we will stay in hi-res mode
373 // for at least 1s. 363 // for at least 1s.
374 static const int kHighResolutionTimerModeLeaseTimeMs = 1000; 364 static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
375 365
376 // Asserts that the MessageLoop is "idle".
377 void AssertIdle() const;
378
379 #if defined(OS_WIN) 366 #if defined(OS_WIN)
380 void set_os_modal_loop(bool os_modal_loop) { 367 void set_os_modal_loop(bool os_modal_loop) {
381 os_modal_loop_ = os_modal_loop; 368 os_modal_loop_ = os_modal_loop;
382 } 369 }
383 370
384 bool os_modal_loop() const { 371 bool os_modal_loop() const {
385 return os_modal_loop_; 372 return os_modal_loop_;
386 } 373 }
387 #endif // OS_WIN 374 #endif // OS_WIN
388 375
389 // Can only be called from the thread that owns the MessageLoop. 376 // Can only be called from the thread that owns the MessageLoop.
390 bool is_running() const; 377 bool is_running() const;
391 378
379 // Returns true if the message loop has high resolution timers enabled.
380 // Provided for testing.
381 bool IsHishResolutionTimersEnabledForTest();
382
383 // Returns true if the message loop is "idle". Provided for testing.
384 bool IsIdleForTest();
385
392 //---------------------------------------------------------------------------- 386 //----------------------------------------------------------------------------
393 protected: 387 protected:
394 388
395 #if defined(OS_WIN) 389 #if defined(OS_WIN)
396 MessagePumpWin* pump_win() { 390 MessagePumpWin* pump_win() {
397 return static_cast<MessagePumpWin*>(pump_.get()); 391 return static_cast<MessagePumpWin*>(pump_.get());
398 } 392 }
399 #elif defined(OS_POSIX) && !defined(OS_IOS) 393 #elif defined(OS_POSIX) && !defined(OS_IOS)
400 MessagePumpLibevent* pump_libevent() { 394 MessagePumpLibevent* pump_libevent() {
401 return static_cast<MessagePumpLibevent*>(pump_.get()); 395 return static_cast<MessagePumpLibevent*>(pump_.get());
402 } 396 }
403 #endif 397 #endif
404 398
405 scoped_refptr<MessagePump> pump_; 399 scoped_ptr<MessagePump> pump_;
406 400
407 private: 401 private:
408 friend class RunLoop; 402 friend class RunLoop;
409 friend class MessageLoopLockTest; 403 friend class MessageLoopLockTest;
404 friend class MessageLoopProxyImpl;
410 405
411 // A function to encapsulate all the exception handling capability in the 406 // A function to encapsulate all the exception handling capability in the
412 // stacks around the running of a main message loop. It will run the message 407 // stacks around the running of a main message loop. It will run the message
413 // loop in a SEH try block or not depending on the set_SEH_restoration() 408 // loop in a SEH try block or not depending on the set_SEH_restoration()
414 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). 409 // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
415 void RunHandler(); 410 void RunHandler();
416 411
417 #if defined(OS_WIN) 412 #if defined(OS_WIN)
418 __declspec(noinline) void RunInternalInSEHFrame(); 413 __declspec(noinline) void RunInternalInSEHFrame();
419 #endif 414 #endif
420 415
421 // A surrounding stack frame around the running of the message loop that 416 // A surrounding stack frame around the running of the message loop that
422 // supports all saving and restoring of state, as is needed for any/all (ugly) 417 // supports all saving and restoring of state, as is needed for any/all (ugly)
423 // recursive calls. 418 // recursive calls.
424 void RunInternal(); 419 void RunInternal();
425 420
426 // Called to process any delayed non-nestable tasks. 421 // Called to process any delayed non-nestable tasks.
427 bool ProcessNextDelayedNonNestableTask(); 422 bool ProcessNextDelayedNonNestableTask();
428 423
429 // Runs the specified PendingTask. 424 // Runs the specified PendingTask.
430 void RunTask(const PendingTask& pending_task); 425 void RunTask(const PendingTask& pending_task);
431 426
432 // Calls RunTask or queues the pending_task on the deferred task list if it 427 // Calls RunTask or queues the pending_task on the deferred task list if it
433 // cannot be run right now. Returns true if the task was run. 428 // cannot be run right now. Returns true if the task was run.
434 bool DeferOrRunPendingTask(const PendingTask& pending_task); 429 bool DeferOrRunPendingTask(const PendingTask& pending_task);
435 430
436 // Adds the pending task to delayed_work_queue_. 431 // Adds the pending task to delayed_work_queue_.
437 void AddToDelayedWorkQueue(const PendingTask& pending_task); 432 void AddToDelayedWorkQueue(const PendingTask& pending_task);
438 433
439 // This function attempts to add pending task to our incoming_queue_.
440 // The append can only possibly fail when |use_try_lock| is true.
441 //
442 // When |use_try_lock| is true, then this call will avoid blocking if
443 // the related lock is already held, and will in that case (when the
444 // lock is contended) fail to perform the append, and will return false.
445 //
446 // If the call succeeds to append to the queue, then this call
447 // will return true.
448 //
449 // In all cases, the caller retains ownership of |pending_task|, but this
450 // function will reset the value of pending_task->task. This is needed to
451 // ensure that the posting call stack does not retain pending_task->task
452 // beyond this function call.
453 bool AddToIncomingQueue(PendingTask* pending_task, bool use_try_lock);
454
455 // Load tasks from the incoming_queue_ into work_queue_ if the latter is
456 // empty. The former requires a lock to access, while the latter is directly
457 // accessible on this thread.
458 void ReloadWorkQueue();
459
460 // Delete tasks that haven't run yet without running them. Used in the 434 // Delete tasks that haven't run yet without running them. Used in the
461 // destructor to make sure all the task's destructors get called. Returns 435 // destructor to make sure all the task's destructors get called. Returns
462 // true if some work was done. 436 // true if some work was done.
463 bool DeletePendingTasks(); 437 bool DeletePendingTasks();
464 438
465 // Calculates the time at which a PendingTask should run. 439 // Wakes up the message pump. Can be called on any thread. The caller is
466 TimeTicks CalculateDelayedRuntime(TimeDelta delay); 440 // resonsible for synchronizing StartPump() calls.
rvargas (doing something else) 2013/06/28 22:59:44 typo: responsible
alexeypa (please no reviews) 2013/07/03 18:56:48 Done.
441 void StartPump();
rvargas (doing something else) 2013/06/28 22:59:44 nit: Maybe WakeUpPump()? RestartPump()? StartPump
alexeypa (please no reviews) 2013/07/03 18:56:48 Done.
442
443 // Creates a process-wide unique ID to represent this task in trace events.
444 // This will be mangled with a Process ID hash to reduce the likelyhood of
445 // colliding with MessageLoop pointers on other processes.
446 uint64 GetTaskTraceID(const PendingTask& task);
467 447
468 // Start recording histogram info about events and action IF it was enabled 448 // Start recording histogram info about events and action IF it was enabled
469 // and IF the statistics recorder can accept a registration of our histogram. 449 // and IF the statistics recorder can accept a registration of our histogram.
470 void StartHistogrammer(); 450 void StartHistogrammer();
471 451
472 // Add occurrence of event to our histogram, so that we can see what is being 452 // Add occurrence of event to our histogram, so that we can see what is being
473 // done in a specific MessageLoop instance (i.e., specific thread). 453 // done in a specific MessageLoop instance (i.e., specific thread).
474 // If message_histogram_ is NULL, this is a no-op. 454 // If message_histogram_ is NULL, this is a no-op.
475 void HistogramEvent(int event); 455 void HistogramEvent(int event);
476 456
(...skipping 24 matching lines...) Expand all
501 // A recursion block that prevents accidentally running additional tasks when 481 // A recursion block that prevents accidentally running additional tasks when
502 // insider a (accidentally induced?) nested message pump. 482 // insider a (accidentally induced?) nested message pump.
503 bool nestable_tasks_allowed_; 483 bool nestable_tasks_allowed_;
504 484
505 bool exception_restoration_; 485 bool exception_restoration_;
506 486
507 std::string thread_name_; 487 std::string thread_name_;
508 // A profiling histogram showing the counts of various messages and events. 488 // A profiling histogram showing the counts of various messages and events.
509 HistogramBase* message_histogram_; 489 HistogramBase* message_histogram_;
510 490
511 // An incoming queue of tasks that are acquired under a mutex for processing
512 // on this instance's thread. These tasks have not yet been sorted out into
513 // items for our work_queue_ vs delayed_work_queue_.
514 TaskQueue incoming_queue_;
515 // Protect access to incoming_queue_.
516 mutable Lock incoming_queue_lock_;
517
518 RunLoop* run_loop_;
519
520 #if defined(OS_WIN) 491 #if defined(OS_WIN)
521 TimeTicks high_resolution_timer_expiration_;
522 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc 492 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
523 // which enter a modal message loop. 493 // which enter a modal message loop.
524 bool os_modal_loop_; 494 bool os_modal_loop_;
rvargas (doing something else) 2013/06/28 22:59:44 Now that you're moving variables do you mind keepi
alexeypa (please no reviews) 2013/07/03 18:56:48 Done.
525 #endif 495 #endif
526 496
527 // The next sequence number to use for delayed tasks. Updating this counter is 497 RunLoop* run_loop_;
528 // protected by incoming_queue_lock_.
529 int next_sequence_num_;
530 498
531 ObserverList<TaskObserver> task_observers_; 499 ObserverList<TaskObserver> task_observers_;
532 500
533 // The message loop proxy associated with this message loop, if one exists. 501 // The message loop proxy associated with this message loop.
534 scoped_refptr<MessageLoopProxy> message_loop_proxy_; 502 scoped_refptr<MessageLoopProxyImpl> message_loop_proxy_;
535 scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_; 503 scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
536 504
537 template <class T, class R> friend class base::subtle::DeleteHelperInternal; 505 template <class T, class R> friend class base::subtle::DeleteHelperInternal;
538 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; 506 template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
539 507
540 void DeleteSoonInternal(const tracked_objects::Location& from_here, 508 void DeleteSoonInternal(const tracked_objects::Location& from_here,
541 void(*deleter)(const void*), 509 void(*deleter)(const void*),
542 const void* object); 510 const void* object);
543 void ReleaseSoonInternal(const tracked_objects::Location& from_here, 511 void ReleaseSoonInternal(const tracked_objects::Location& from_here,
544 void(*releaser)(const void*), 512 void(*releaser)(const void*),
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 688
721 // Do not add any member variables to MessageLoopForIO! This is important b/c 689 // Do not add any member variables to MessageLoopForIO! This is important b/c
722 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 690 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
723 // data that you need should be stored on the MessageLoop's pump_ instance. 691 // data that you need should be stored on the MessageLoop's pump_ instance.
724 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 692 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
725 MessageLoopForIO_should_not_have_extra_member_variables); 693 MessageLoopForIO_should_not_have_extra_member_variables);
726 694
727 } // namespace base 695 } // namespace base
728 696
729 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 697 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
OLDNEW
« no previous file with comments | « no previous file | base/message_loop/message_loop.cc » ('j') | base/message_loop/message_loop_proxy_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698