blob: 59afb2e37fe70e0297c697b2c8ec7713cea21835 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/console/console.h"
#include "src/developer/debug/zxdb/console/async_output_buffer.h"
#include "src/developer/debug/zxdb/console/command_parser.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
namespace zxdb {
Console* Console::singleton_ = nullptr;
Console::Console(Session* session) : context_(session), weak_factory_(this) {
FX_DCHECK(!singleton_);
singleton_ = this;
}
Console::~Console() {
FX_DCHECK(singleton_ == this);
singleton_ = nullptr;
// Clear backpointers bound with the callbacks for any pending async buffers.
for (auto& pair : async_output_)
pair.second->SetCompletionCallback({});
}
fxl::WeakPtr<Console> Console::GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
void Console::Output(const std::string& s) {
OutputBuffer buffer;
buffer.Append(s);
Output(buffer);
}
void Console::Output(const Err& err) {
OutputBuffer buffer;
buffer.Append(err);
Output(buffer);
}
void Console::Output(fxl::RefPtr<AsyncOutputBuffer> output) {
if (output->is_complete()) {
// Synchronously available.
Output(output->DestructiveFlatten());
} else {
// Listen for completion.
//
// Binds |this|. On our destruction we'll clear all the callbacks to prevent dangling pointers
// for anything not completed yet.
AsyncOutputBuffer* output_ptr = output.get();
output->SetCompletionCallback([this, output_ptr]() {
Output(output_ptr->DestructiveFlatten());
auto found = async_output_.find(output_ptr);
FX_DCHECK(found != async_output_.end());
// Clear the completion callback out of paranoia.
async_output_.erase(found);
});
async_output_[output_ptr] = std::move(output);
}
}
} // namespace zxdb