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

Side by Side Diff: chrome/common/notification_registrar.cc

Issue 449044: Adding instrument to NotificationRegistrar to check... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years 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
« no previous file with comments | « chrome/common/notification_registrar.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 #include "chrome/common/notification_registrar.h" 5 #include "chrome/common/notification_registrar.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "chrome/common/notification_service.h" 10 #include "chrome/common/notification_service.h"
11 11
12 struct NotificationRegistrar::Record { 12 struct NotificationRegistrar::Record {
13 bool operator==(const Record& other) const; 13 bool operator==(const Record& other) const;
14 14
15 NotificationObserver* observer; 15 NotificationObserver* observer;
16 NotificationType type; 16 NotificationType type;
17 NotificationSource source; 17 NotificationSource source;
18 }; 18 };
19 19
20 bool NotificationRegistrar::Record::operator==(const Record& other) const { 20 bool NotificationRegistrar::Record::operator==(const Record& other) const {
21 return observer == other.observer && 21 return observer == other.observer &&
22 type == other.type && 22 type == other.type &&
23 source == other.source; 23 source == other.source;
24 } 24 }
25 25
26 NotificationRegistrar::NotificationRegistrar() { 26 NotificationRegistrar::NotificationRegistrar() {
27 if (!ChromeThread::GetCurrentThreadIdentifier(&thread_id_)) {
28 // If we are not created in well known thread, GetCurrentThreadIdentifier
29 // fails. Assign thread_id_ to an ID not used.
30 thread_id_ = ChromeThread::ID_COUNT;
31 }
27 } 32 }
28 33
29 NotificationRegistrar::~NotificationRegistrar() { 34 NotificationRegistrar::~NotificationRegistrar() {
30 RemoveAll(); 35 RemoveAll();
31 } 36 }
32 37
33 void NotificationRegistrar::Add(NotificationObserver* observer, 38 void NotificationRegistrar::Add(NotificationObserver* observer,
34 NotificationType type, 39 NotificationType type,
35 const NotificationSource& source) { 40 const NotificationSource& source) {
36 Record record = { observer, type, source }; 41 Record record = { observer, type, source };
37 DCHECK(std::find(registered_.begin(), registered_.end(), record) == 42 DCHECK(std::find(registered_.begin(), registered_.end(), record) ==
38 registered_.end()) << "Duplicate registration."; 43 registered_.end()) << "Duplicate registration.";
39 registered_.push_back(record); 44 registered_.push_back(record);
40 45
46 if (ChromeThread::IsWellKnownThread(thread_id_)) {
47 if (!ChromeThread::CurrentlyOn(thread_id_)) {
48 // We are created on a well known thread, but this function is called
49 // on a different thread. This could be a bug, or maybe the object is
50 // passed around.
51 // To be safe, reset thread_id_ so we don't call CHECK during remove.
52 thread_id_ = ChromeThread::ID_COUNT;
53 }
54 }
55
41 NotificationService::current()->AddObserver(observer, type, source); 56 NotificationService::current()->AddObserver(observer, type, source);
42 } 57 }
43 58
44 void NotificationRegistrar::Remove(NotificationObserver* observer, 59 void NotificationRegistrar::Remove(NotificationObserver* observer,
45 NotificationType type, 60 NotificationType type,
46 const NotificationSource& source) { 61 const NotificationSource& source) {
47 Record record = { observer, type, source }; 62 Record record = { observer, type, source };
48 RecordVector::iterator found = std::find( 63 RecordVector::iterator found = std::find(
49 registered_.begin(), registered_.end(), record); 64 registered_.begin(), registered_.end(), record);
50 if (found == registered_.end()) { 65 if (found == registered_.end()) {
51 NOTREACHED() << "Trying to remove unregistered observer of type " << 66 NOTREACHED() << "Trying to remove unregistered observer of type " <<
52 type.value << " from list of size " << registered_.size() << "."; 67 type.value << " from list of size " << registered_.size() << ".";
53 return; 68 return;
54 } 69 }
55 registered_.erase(found); 70 registered_.erase(found);
56 71
72 CheckCalledOnValidWellKnownThread();
73
57 // This can be NULL if our owner outlives the NotificationService, e.g. if our 74 // This can be NULL if our owner outlives the NotificationService, e.g. if our
58 // owner is a Singleton. 75 // owner is a Singleton.
59 NotificationService* service = NotificationService::current(); 76 NotificationService* service = NotificationService::current();
60 if (service) 77 if (service)
61 service->RemoveObserver(observer, type, source); 78 service->RemoveObserver(observer, type, source);
62 } 79 }
63 80
64 void NotificationRegistrar::RemoveAll() { 81 void NotificationRegistrar::RemoveAll() {
65 // Early-exit if no registrations, to avoid calling 82 // Early-exit if no registrations, to avoid calling
66 // NotificationService::current. If we've constructed an object with a 83 // NotificationService::current. If we've constructed an object with a
67 // NotificationRegistrar member, but haven't actually used the notification 84 // NotificationRegistrar member, but haven't actually used the notification
68 // service, and we reach prgram exit, then calling current() below could try 85 // service, and we reach prgram exit, then calling current() below could try
69 // to initialize the service's lazy TLS pointer during exit, which throws 86 // to initialize the service's lazy TLS pointer during exit, which throws
70 // wrenches at things. 87 // wrenches at things.
71 if (registered_.empty()) 88 if (registered_.empty())
72 return; 89 return;
73 90
91 CheckCalledOnValidWellKnownThread();
92
74 // This can be NULL if our owner outlives the NotificationService, e.g. if our 93 // This can be NULL if our owner outlives the NotificationService, e.g. if our
75 // owner is a Singleton. 94 // owner is a Singleton.
76 NotificationService* service = NotificationService::current(); 95 NotificationService* service = NotificationService::current();
77 if (service) { 96 if (service) {
78 for (size_t i = 0; i < registered_.size(); i++) { 97 for (size_t i = 0; i < registered_.size(); i++) {
79 service->RemoveObserver(registered_[i].observer, 98 service->RemoveObserver(registered_[i].observer,
80 registered_[i].type, 99 registered_[i].type,
81 registered_[i].source); 100 registered_[i].source);
82 } 101 }
83 } 102 }
84 registered_.clear(); 103 registered_.clear();
85 } 104 }
86 105
87 bool NotificationRegistrar::IsEmpty() const { 106 bool NotificationRegistrar::IsEmpty() const {
88 return registered_.empty(); 107 return registered_.empty();
89 } 108 }
109
110 void NotificationRegistrar::CheckCalledOnValidWellKnownThread() {
111 if (ChromeThread::IsWellKnownThread(thread_id_)) {
112 CHECK(ChromeThread::CurrentlyOn(thread_id_));
113 }
114 }
OLDNEW
« no previous file with comments | « chrome/common/notification_registrar.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698