Home | History | Annotate | Download | only in dbus
      1 // Copyright (c) 2012 The Chromium 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 "chromeos/dbus/blocking_method_caller.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback_helpers.h"
      9 #include "base/location.h"
     10 #include "base/task_runner.h"
     11 #include "base/threading/thread_restrictions.h"
     12 #include "dbus/bus.h"
     13 #include "dbus/object_proxy.h"
     14 
     15 namespace chromeos {
     16 
     17 namespace {
     18 
     19 // This function is a part of CallMethodAndBlock implementation.
     20 void CallMethodAndBlockInternal(
     21     scoped_ptr<dbus::Response>* response,
     22     base::ScopedClosureRunner* signaler,
     23     dbus::ObjectProxy* proxy,
     24     dbus::MethodCall* method_call) {
     25   *response = proxy->CallMethodAndBlock(
     26       method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
     27 }
     28 
     29 }  // namespace
     30 
     31 BlockingMethodCaller::BlockingMethodCaller(dbus::Bus* bus,
     32                                            dbus::ObjectProxy* proxy)
     33     : bus_(bus),
     34       proxy_(proxy),
     35       on_blocking_method_call_(false /* manual_reset */,
     36                                false /* initially_signaled */) {
     37 }
     38 
     39 BlockingMethodCaller::~BlockingMethodCaller() {
     40 }
     41 
     42 scoped_ptr<dbus::Response> BlockingMethodCaller::CallMethodAndBlock(
     43     dbus::MethodCall* method_call) {
     44   // on_blocking_method_call_->Signal() will be called when |signaler| is
     45   // destroyed.
     46   base::Closure signal_task(
     47       base::Bind(&base::WaitableEvent::Signal,
     48                  base::Unretained(&on_blocking_method_call_)));
     49   base::ScopedClosureRunner* signaler =
     50       new base::ScopedClosureRunner(signal_task);
     51 
     52   scoped_ptr<dbus::Response> response;
     53   bus_->GetDBusTaskRunner()->PostTask(
     54       FROM_HERE,
     55       base::Bind(&CallMethodAndBlockInternal,
     56                  &response,
     57                  base::Owned(signaler),
     58                  base::Unretained(proxy_),
     59                  method_call));
     60   // http://crbug.com/125360
     61   base::ThreadRestrictions::ScopedAllowWait allow_wait;
     62   on_blocking_method_call_.Wait();
     63   return response.Pass();
     64 }
     65 
     66 }  // namespace chromeos
     67