1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/x/future.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/event.h"
namespace x11 {
FutureImpl::FutureImpl(Connection* connection,
SequenceType sequence,
bool generates_reply,
const char* request_name_for_tracing)
: connection_(connection),
sequence_(sequence),
generates_reply_(generates_reply),
request_name_for_tracing_(request_name_for_tracing) {}
void FutureImpl::Wait() {
connection_->WaitForResponse(this);
}
void FutureImpl::DispatchNow() {
Wait();
ProcessResponse();
}
bool FutureImpl::AfterEvent(const Event& event) const {
return CompareSequenceIds(event.sequence(), sequence_) > 0;
}
void FutureImpl::Sync(RawReply* raw_reply, std::unique_ptr<Error>* error) {
Wait();
TakeResponse(raw_reply, error);
}
void FutureImpl::OnResponse(ResponseCallback callback) {
UpdateRequestHandler(std::move(callback));
}
void FutureImpl::UpdateRequestHandler(ResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(connection_->sequence_checker_);
CHECK(callback);
auto* request = connection_->GetRequestForFuture(this);
// Make sure we haven't processed this request yet.
CHECK(request->callback);
request->callback = std::move(callback);
}
void FutureImpl::ProcessResponse() {
DCHECK_CALLED_ON_VALID_SEQUENCE(connection_->sequence_checker_);
auto* request = connection_->GetRequestForFuture(this);
CHECK(request->callback);
CHECK(request->have_response);
std::move(request->callback)
.Run(std::move(request->reply), std::move(request->error));
}
void FutureImpl::TakeResponse(RawReply* raw_reply,
std::unique_ptr<Error>* error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(connection_->sequence_checker_);
auto* request = connection_->GetRequestForFuture(this);
CHECK(request->callback);
CHECK(request->have_response);
*raw_reply = std::move(request->reply);
*error = std::move(request->error);
request->callback.Reset();
}
FutureBase::FutureBase() = default;
FutureBase::FutureBase(std::unique_ptr<FutureImpl> impl)
: impl_(std::move(impl)) {}
FutureBase::FutureBase(FutureBase&&) = default;
FutureBase& FutureBase::operator=(FutureBase&&) = default;
FutureBase::~FutureBase() = default;
void FutureBase::Wait() {
if (impl_) {
impl_->Wait();
}
}
void FutureBase::DispatchNow() {
CHECK(impl_);
impl_->DispatchNow();
}
bool FutureBase::AfterEvent(const Event& event) const {
return impl_ ? impl_->AfterEvent(event) : false;
}
} // namespace x11
|