1 // Copyright 2018 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 "services/network/pending_callback_chain.h"
6 #include "base/bind.h"
7 
8 namespace network {
9 
PendingCallbackChain(net::CompletionOnceCallback complete)10 PendingCallbackChain::PendingCallbackChain(net::CompletionOnceCallback complete)
11     : complete_(std::move(complete)) {}
12 
~PendingCallbackChain()13 PendingCallbackChain::~PendingCallbackChain() {}
14 
CreateCallback()15 net::CompletionOnceCallback PendingCallbackChain::CreateCallback() {
16   return base::BindOnce(&PendingCallbackChain::CallbackComplete, this);
17 }
18 
AddResult(int result)19 void PendingCallbackChain::AddResult(int result) {
20   if (result == net::ERR_IO_PENDING)
21     num_waiting_++;
22   else
23     SetResult(result);
24 }
25 
GetResult() const26 int PendingCallbackChain::GetResult() const {
27   if (num_waiting_ > 0)
28     return net::ERR_IO_PENDING;
29   return final_result_;
30 }
31 
CallbackComplete(int result)32 void PendingCallbackChain::CallbackComplete(int result) {
33   DCHECK_GT(num_waiting_, 0);
34   SetResult(result);
35   num_waiting_--;
36   if (num_waiting_ == 0)
37     std::move(complete_).Run(final_result_);
38 }
39 
SetResult(int result)40 void PendingCallbackChain::SetResult(int result) {
41   DCHECK_NE(result, net::ERR_IO_PENDING);
42   if (final_result_ == net::OK) {
43     final_result_ = result;
44   } else if (result != net::OK && result != final_result_) {
45     // If we have two non-OK results, default to ERR_FAILED.
46     final_result_ = net::ERR_FAILED;
47   }
48 }
49 
50 }  // namespace network
51