Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/property_changed_handler.h" | |
| 6 | |
| 7 #include <glog/logging.h> | |
| 8 | |
| 9 namespace cashew { | |
| 10 | |
| 11 PropertyChangedHandler::PropertyChangedHandler() | |
| 12 : delegate_(NULL), source_id_(0) {} | |
| 13 | |
| 14 PropertyChangedHandler::~PropertyChangedHandler() { | |
| 15 DeletePendingSignals(); | |
| 16 if (source_id_ != 0 && !g_source_remove(source_id_)) { | |
| 17 LOG(WARNING) << "dtor: g_source_remove failed"; | |
| 18 } | |
| 19 } | |
| 20 | |
| 21 void PropertyChangedHandler::delegate(PropertyChangedDelegate *delegate) { | |
| 22 delegate_ = delegate; | |
| 23 } | |
| 24 | |
| 25 void PropertyChangedHandler::EnqueueSignal( | |
| 26 const PropertyChangedSignal& signal) { | |
| 27 signal_queue_.push(signal); | |
| 28 // schedule glib callback to do deferred signal processing if one is not | |
| 29 // already scheduled | |
| 30 if (source_id_ != 0) { | |
| 31 return; | |
| 32 } | |
| 33 source_id_ = g_idle_add(StaticOnPropertyChangedCallback, this); | |
|
Daniel Kurtz
2010/11/29 05:20:17
I don't know how well this will work. Mucking wit
Vince Laviano
2010/11/29 20:13:08
This is no different than the approach taken in my
Daniel Kurtz
2010/11/29 21:52:08
OK I agree since it is all single-threaded.
| |
| 34 if (source_id_ == 0) { | |
| 35 LOG(ERROR) << "EnqueueSignal: g_idle_add failed"; | |
| 36 return; | |
| 37 } | |
| 38 } | |
| 39 | |
| 40 // Private methods | |
| 41 | |
| 42 // static | |
| 43 gboolean PropertyChangedHandler::StaticOnPropertyChangedCallback( | |
| 44 gpointer data) { | |
| 45 PropertyChangedHandler *handler = | |
| 46 reinterpret_cast<PropertyChangedHandler*>(data); | |
| 47 DCHECK(handler != NULL); | |
| 48 DCHECK_NE(handler->source_id_, 0); | |
| 49 // TODO(vlaviano): we could impose a limit on the number of signals that we're | |
| 50 // willing to process per invocation and return TRUE to reschedule this | |
| 51 // callback if there are signals remaining in the queue | |
| 52 while (!handler->signal_queue_.empty()) { | |
| 53 PropertyChangedSignal signal = handler->signal_queue_.front(); | |
| 54 const std::string& property_name = signal.first; | |
| 55 const DBus::Variant& new_value = signal.second; | |
| 56 if (handler->delegate_ != NULL) { | |
| 57 handler->delegate_->OnPropertyChanged(handler, property_name, new_value); | |
| 58 } | |
| 59 handler->signal_queue_.pop(); | |
| 60 } | |
| 61 // we don't want to be run again automatically | |
| 62 // EnqueueSignal will schedule us as needed | |
| 63 handler->source_id_ = 0; | |
|
Daniel Kurtz
2010/11/29 05:20:17
There is a race condition if ::EnqueSignal() is ca
Vince Laviano
2010/11/29 20:13:08
cashew is a single-threaded application structured
Daniel Kurtz
2010/11/29 21:52:08
OK I agree since it is all single-threaded.
| |
| 64 return FALSE; | |
|
Daniel Kurtz
2010/11/29 05:20:17
http://library.gnome.org/devel/glib/unstable/glib-
Vince Laviano
2010/11/29 20:13:08
I could, but I think that a simple g_idle_add meet
Daniel Kurtz
2010/11/29 21:52:08
OK I agree, if creating a new idle handler on each
| |
| 65 } | |
| 66 | |
| 67 void PropertyChangedHandler::DeletePendingSignals() { | |
| 68 while (!signal_queue_.empty()) { | |
| 69 signal_queue_.pop(); | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 } // namespace cashew | |
| OLD | NEW |