shill: Framework for asynchronous service side RPC calls.
Use the framework to switch EnterPIN to return asynchronously.
Also, added a few try/catch clauses around DBus proxy calls to ease testing and
debugging. They should go away as we transition to asynchronous proxy calls.
BUG=chromium-os:17263
TEST=unit tests, tested on device
Change-Id: I4177c5b91e23c31838b03689de729932c859a936
Reviewed-on: https://gerrit.chromium.org/gerrit/12541
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Reviewed-by: Eric Shienbrood <ers@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/dbus_adaptor.cc b/dbus_adaptor.cc
index ea1ada9..5d71d95 100644
--- a/dbus_adaptor.cc
+++ b/dbus_adaptor.cc
@@ -349,4 +349,91 @@
return signature == ::DBus::type<uint32>::sig();
}
+// static
+DBusAdaptor::Returner *DBusAdaptor::Returner::Create(DBusAdaptor *adaptor) {
+ return new Returner(adaptor);
+}
+
+DBusAdaptor::Returner::Returner(DBusAdaptor *adaptor)
+ : adaptor_(adaptor),
+ state_(kStateInitialized) {
+ VLOG(2) << __func__ << " @ " << this;
+}
+
+DBusAdaptor::Returner::~Returner() {
+ CHECK(state_ != kStateDestroyed);
+ VLOG(2) << "Destroying returner @ " << this << " state: " << state_;
+ adaptor_ = NULL;
+ state_ = kStateDestroyed;
+}
+
+void DBusAdaptor::Returner::Return() {
+ VLOG(2) << __func__ << " @ " << this << " state: " << state_;
+ switch (state_) {
+ case kStateInitialized:
+ // Service method is returning right away, without any continuation.
+ state_ = kStateReturned;
+ return;
+ case kStateDelayed: {
+ // This return happens in the continuation.
+ DBus::ObjectAdaptor::Continuation *cont =
+ adaptor_->find_continuation(this);
+ CHECK(cont);
+ adaptor_->return_now(cont);
+ delete this;
+ return;
+ }
+ default:
+ NOTREACHED() << "Unexpected state: " << state_;
+ break;
+ }
+}
+
+void DBusAdaptor::Returner::ReturnError(const Error &error) {
+ VLOG(2) << __func__ << " @ " << this << " state: " << state_;
+ switch (state_) {
+ case kStateInitialized:
+ // Service method is returning right away, without any continuation.
+ error_.CopyFrom(error);
+ state_ = kStateReturned;
+ return;
+ case kStateDelayed: {
+ // This return happens in the continuation.
+ DBus::Error dbus_error;
+ error.ToDBusError(&dbus_error);
+ DBus::ObjectAdaptor::Continuation *cont =
+ adaptor_->find_continuation(this);
+ CHECK(cont);
+ adaptor_->return_error(cont, dbus_error);
+ delete this;
+ return;
+ }
+ default:
+ NOTREACHED() << "Unexpected state: " << state_;
+ break;
+ }
+}
+
+void DBusAdaptor::Returner::DelayOrReturn(DBus::Error *error) {
+ VLOG(2) << __func__ << " @ " << this << " state: " << state_;
+ switch (state_) {
+ case kStateInitialized:
+ // Service method needs continuation so delay the return.
+ state_ = kStateDelayed;
+
+ // return_later does not return. It unwinds the stack up to the dbus-c++
+ // message handler by throwing an exception.
+ adaptor_->return_later(this);
+ return;
+ case kStateReturned:
+ // Service method has returned right away, without any continuation.
+ error_.ToDBusError(error);
+ delete this;
+ return;
+ default:
+ NOTREACHED() << "Unexpected state: " << state_;
+ break;
+ }
+}
+
} // namespace shill