blob: 12f48d540e83c2281f7f2df51accda2ddd4894fc [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 "codec_admission_control.h"
#include "device_ctx.h"
#include <lib/fxl/logging.h>
#include <stdint.h>
#include <mutex>
void CodecAdmissionControl::TryAddCodec(
fit::function<void(std::unique_ptr<CodecAdmission>)>
continue_after_previously_started_channel_closes_done) {
PostAfterPreviouslyStartedClosesDone(
[this, callback = std::move(
continue_after_previously_started_channel_closes_done)] {
callback(TryAddCodecInternal());
});
}
void CodecAdmissionControl::PostAfterPreviouslyStartedClosesDone(
fit::closure to_run) {
// TODO(dustingreen): This post is a partial simulation of more robust fencing
// of previously initiated closes before newly initiated create. See TODO in
// the header file.
device_ctx_->driver()->PostToSharedFidl(std::move(to_run));
}
std::unique_ptr<CodecAdmission> CodecAdmissionControl::TryAddCodecInternal() {
std::lock_guard<std::mutex> lock(lock_);
if (codec_count_ != 0) {
FXL_DCHECK(codec_count_ == 1);
printf("CodecAdmissionControl::AddCodec(): we've already got one\n");
return nullptr;
}
codec_count_++;
FXL_DCHECK(codec_count_ == 1);
// private constructor so have to explicitly new, since friending
// std::make_unique<> would allow any class to create one.
return std::unique_ptr<CodecAdmission>(new CodecAdmission(this));
}
CodecAdmissionControl::CodecAdmissionControl(DeviceCtx* device_ctx)
: device_ctx_(device_ctx) {
FXL_DCHECK(device_ctx_);
}
void CodecAdmissionControl::RemoveCodec() {
std::lock_guard<std::mutex> lock(lock_);
// Else bug in caller.
FXL_DCHECK(codec_count_ == 1);
codec_count_--;
}
CodecAdmission::~CodecAdmission() { codec_admission_control_->RemoveCodec(); }
CodecAdmission::CodecAdmission(CodecAdmissionControl* codec_admission_control)
: codec_admission_control_(codec_admission_control) {
FXL_DCHECK(codec_admission_control_);
}