|  | /* | 
|  | * Copyright (C) 2017 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #include "perfetto/ipc/deferred.h" | 
|  |  | 
|  | #include "google/protobuf/message_lite.h" | 
|  | #include "perfetto/base/logging.h" | 
|  |  | 
|  | namespace perfetto { | 
|  | namespace ipc { | 
|  |  | 
|  | DeferredBase::DeferredBase( | 
|  | std::function<void(AsyncResult<ProtoMessage>)> callback) | 
|  | : callback_(std::move(callback)) {} | 
|  |  | 
|  | DeferredBase::~DeferredBase() { | 
|  | if (callback_) | 
|  | Reject(); | 
|  | } | 
|  |  | 
|  | // Can't just use "= default" here because the default move operator for | 
|  | // std::function doesn't necessarily swap and hence can leave a copy of the | 
|  | // bind state around, which is undesirable. | 
|  | DeferredBase::DeferredBase(DeferredBase&& other) noexcept { | 
|  | Move(other); | 
|  | } | 
|  |  | 
|  | DeferredBase& DeferredBase::operator=(DeferredBase&& other) { | 
|  | if (callback_) | 
|  | Reject(); | 
|  | Move(other); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | void DeferredBase::Move(DeferredBase& other) { | 
|  | callback_ = std::move(other.callback_); | 
|  | other.callback_ = nullptr; | 
|  | } | 
|  |  | 
|  | void DeferredBase::Bind( | 
|  | std::function<void(AsyncResult<ProtoMessage>)> callback) { | 
|  | callback_ = std::move(callback); | 
|  | } | 
|  |  | 
|  | bool DeferredBase::IsBound() const { | 
|  | return !!callback_; | 
|  | } | 
|  |  | 
|  | void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) { | 
|  | if (!callback_) { | 
|  | PERFETTO_DFATAL("No callback set."); | 
|  | return; | 
|  | } | 
|  | bool has_more = async_result.has_more(); | 
|  | callback_(std::move(async_result)); | 
|  | if (!has_more) | 
|  | callback_ = nullptr; | 
|  | } | 
|  |  | 
|  | // Resolves with a nullptr |msg_|, signalling failure to |callback_|. | 
|  | void DeferredBase::Reject() { | 
|  | Resolve(AsyncResult<ProtoMessage>()); | 
|  | } | 
|  |  | 
|  | }  // namespace ipc | 
|  | }  // namespace perfetto |