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

Side by Side Diff: experimental/c_salt/notification_center.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2010 The Ginsu Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can
3 // be found in the LICENSE file.
4
5 #include "c_salt/notification_center.h"
6
7 #include "c_salt/notification.h"
8
9 namespace {
10 const int kPthreadMutexSuccess = 0;
11
12 // The class singleton and its mutex.
13 // TODO(c_salt_authors): This mutex should really be some kind of scoped
14 // mutex class, such as boost::mutex and boost::lock_guard.
15 pthread_mutex_t notification_center_mutex = PTHREAD_MUTEX_INITIALIZER;
16 c_salt::NotificationCenter* notification_center = NULL;
17 } // namespace
18
19 namespace c_salt {
20
21 const char* const NotificationCenter::kAnonymousPublisherName = "";
22
23 NotificationCenter* NotificationCenter::DefaultCenter(
24 const c_salt::Instance& instance) {
25 // TODO(c_salt_authors): There needs to be one DefaultCenter() per
26 // Instance. We need to implement this.
27 if (pthread_mutex_lock(&notification_center_mutex) != kPthreadMutexSuccess)
28 return NULL;
29 if (notification_center == NULL) {
30 notification_center = new NotificationCenter();
31 }
32 pthread_mutex_unlock(&notification_center_mutex);
33 return notification_center;
34 }
35
36 NotificationCenter::NotificationCenter() {
37 pthread_mutex_init(&mutex_, NULL);
38 }
39
40 NotificationCenter::~NotificationCenter() {
41 pthread_mutex_destroy(&mutex_);
42 }
43
44 bool NotificationCenter::AddSubscriberImpl(
45 const std::string& notification_name,
46 uint64_t subscriber_id,
47 boost::function<void(const Notification&)> subscriber_functor,
48 const std::string& publisher_name) {
49 if (pthread_mutex_lock(&mutex_) != kPthreadMutexSuccess) {
50 return false;
51 }
52 SharedNotificationSlot notification_slot;
53 std::pair<NotificationDict::iterator, bool> slot_iter =
54 notifications_.insert(NotificationDict::value_type(notification_name,
55 notification_slot));
56 // If this is a newly inserted notification signal, then reset the
57 // value with a new signal object.
58 if (slot_iter.second) {
59 slot_iter.first->second.reset(new NotificationSlot());
60 }
61 // Grab the actual NotificationSlot and hook up the subscriber.
62 notification_slot = slot_iter.first->second;
63 boost::signals2::connection connection;
64 if (publisher_name.empty()) {
65 connection = notification_slot->any_publisher_signal_
66 .connect(subscriber_functor);
67 } else {
68 // Add a new shared_ptr if there isn't one already. The [] notation on
69 // std::map doesn't help here. This is to work around the lack of a copy
70 // ctor on boost::signals2::signal.
71 SharedNotificationSignal publisher_signal(new NotificationSignal());
72 std::pair<PublisherSignalDict::iterator, bool> pub_sig_iter =
73 notification_slot->publisher_signals_.insert(
74 PublisherSignalDict::value_type(publisher_name, publisher_signal));
75 connection = pub_sig_iter.first->second->connect(subscriber_functor);
76 }
77 notification_slot->connections_[subscriber_id].push_back(connection);
78 pthread_mutex_unlock(&mutex_);
79 return true;
80 }
81
82 bool NotificationCenter::RemoveSubscriberImpl(uint64_t subscriber_id) {
83 if (pthread_mutex_lock(&mutex_) != kPthreadMutexSuccess) {
84 return false;
85 }
86 NotificationDict::iterator note_iter = notifications_.begin();
87 const NotificationDict::const_iterator end = notifications_.end();
88 for (; note_iter != end; ++note_iter) {
89 // Disconnect all the connections this subscriber might have for the
90 // notification at |note_iter|.
91 (note_iter->second)->DisconnectSubscriber(subscriber_id);
92 }
93 pthread_mutex_unlock(&mutex_);
94 return true;
95 }
96
97 bool NotificationCenter::RemoveSubscriberFromNotificationImpl(
98 uint64_t subscriber_id,
99 const std::string& notification_name) {
100 if (pthread_mutex_lock(&mutex_) != kPthreadMutexSuccess) {
101 return false;
102 }
103 const NotificationDict::iterator note_iter =
104 notifications_.find(notification_name);
105 if (note_iter != notifications_.end()) {
106 // Disconnect all the connections this subscriber might have for the
107 // notification at |note_iter|.
108 (note_iter->second)->DisconnectSubscriber(subscriber_id);
109 }
110 pthread_mutex_unlock(&mutex_);
111 return true;
112 }
113
114 bool NotificationCenter::RemoveNotification(
115 const std::string& notification_name) {
116 if (pthread_mutex_lock(&mutex_) != kPthreadMutexSuccess) {
117 return false;
118 }
119 notifications_.erase(notification_name);
120 pthread_mutex_unlock(&mutex_);
121 return true;
122 }
123
124 bool NotificationCenter::PublishNotification(
125 const std::string& notification_name,
126 const Notification& notification,
127 const std::string& publisher_name) {
128 if (pthread_mutex_lock(&mutex_) != kPthreadMutexSuccess) {
129 return false;
130 }
131 const NotificationDict::const_iterator note_iter =
132 notifications_.find(notification_name);
133 SharedNotificationSlot notification_slot;
134 SharedNotificationSignal publisher_signal;
135 if (note_iter != notifications_.end()) {
136 // Make a local copy of the signals, in the event that the
137 // notification gets removed before signals can be fired (which will
138 // make the iterator invalid). The local copy of the NotificationSlot
139 // shared_ptr manages |any_publisher_signal_|.
140 notification_slot = note_iter->second;
141 // See if there are any publisher-specific signals. The signal itself is
142 // managed with a shared_ptr, because boost::signals2::signal does not have
143 // a copy ctor.
144 PublisherSignalDict::const_iterator sig_iter =
145 (note_iter->second)->publisher_signals_.find(publisher_name);
146 if (sig_iter != (note_iter->second)->publisher_signals_.end()) {
147 publisher_signal = sig_iter->second;
148 }
149 }
150 // Signal the subscribers. boost makes the actual signalling thread-safe, so
151 // it is ok to unlock the mutex before signaling the subscribers. Note that
152 // it's possible for another thread to disconnect the signal before this gets
153 // reached, in which case the signal will not fire.
154 pthread_mutex_unlock(&mutex_);
155 // Always fire the any-publisher matches.
156 if (notification_slot != NULL) {
157 (notification_slot->any_publisher_signal_)(notification);
158 }
159 // Fire any publisher-specific notifications. If there were none, then this
160 // signal set will be empty and signaling will have no effect.
161 if (publisher_signal != NULL) {
162 (*publisher_signal)(notification);
163 }
164 return true;
165 }
166
167 NotificationCenter::NotificationSlot::~NotificationSlot() {
168 ConnectionDict::iterator conn_iter;
169 for (conn_iter = connections_.begin();
170 conn_iter != connections_.end();
171 ++conn_iter) {
172 DisconnectAll(conn_iter);
173 // No need to erase(conn_iter), since this will be done as part of the
174 // std::map<> dtor.
175 }
176 }
177
178 void NotificationCenter::NotificationSlot::DisconnectSubscriber(
179 uint64_t subscriber_id) {
180 ConnectionDict::iterator conn_iter = connections_.find(subscriber_id);
181 if (conn_iter != connections_.end()) {
182 DisconnectAll(conn_iter);
183 connections_.erase(conn_iter);
184 }
185 }
186
187 void NotificationCenter::NotificationSlot::DisconnectAll(
188 const ConnectionDict::iterator& conn_iter) {
189 std::vector<boost::signals2::connection>::iterator signal_iter;
190 for (signal_iter = conn_iter->second.begin();
191 signal_iter != conn_iter->second.end();
192 ++signal_iter) {
193 // Note that ~connection() does *not* disconnect the signal, so this has
194 // to be done manually in a loop.
195 signal_iter->disconnect();
196 }
197 }
198
199 } // namespace c_salt
OLDNEW
« no previous file with comments | « experimental/c_salt/notification_center.h ('k') | experimental/c_salt/notification_center_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698