1 //
2 // Copyright (C) 2013 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/result_aggregator.h"
18 
19 #include "shill/event_dispatcher.h"
20 #include "shill/logging.h"
21 
22 namespace shill {
23 
ResultAggregator(const ResultCallback & callback)24 ResultAggregator::ResultAggregator(const ResultCallback& callback)
25     : ResultAggregator(callback, nullptr, -1) {}
26 
ResultAggregator(const ResultCallback & callback,EventDispatcher * dispatcher,int timeout_milliseconds)27 ResultAggregator::ResultAggregator(const ResultCallback& callback,
28                                    EventDispatcher* dispatcher,
29                                    int timeout_milliseconds)
30     : weak_ptr_factory_(this),
31       callback_(callback),
32       timeout_callback_(base::Bind(&ResultAggregator::Timeout,
33                                    weak_ptr_factory_.GetWeakPtr())),
34       got_result_(false),
35       timed_out_(false) {
36   CHECK(!callback.is_null());
37   if (dispatcher && timeout_milliseconds >= 0) {
38     dispatcher->PostDelayedTask(timeout_callback_.callback(),
39                                 timeout_milliseconds);
40   }
41 }
42 
~ResultAggregator()43 ResultAggregator::~ResultAggregator() {
44   if (got_result_ && !timed_out_) {
45     callback_.Run(error_);
46   }
47   // timeout_callback_ will automatically be canceled when its destructor
48   // is invoked.
49 }
50 
ReportResult(const Error & error)51 void ResultAggregator::ReportResult(const Error& error) {
52   LOG(INFO) << "Error type " << error << " reported";
53   CHECK(!error.IsOngoing());  // We want the final result.
54   got_result_ = true;
55   if (error_.IsSuccess()) {  // Only copy first |error|.
56     error_.CopyFrom(error);
57   } else {
58     LOG(WARNING) << "Dropping error type " << error;
59   }
60 }
61 
Timeout()62 void ResultAggregator::Timeout() {
63   LOG(WARNING) << "Results aggregator timed out";
64   timed_out_ = true;
65   error_.Populate(Error::kOperationTimeout);
66   callback_.Run(error_);
67 }
68 
69 }  // namespace shill
70