Skip to content

Commit

Permalink
Lock NMOS before finding resources
Browse files Browse the repository at this point in the history
  • Loading branch information
joaofigueiredobisect committed Sep 17, 2024
1 parent 0825389 commit 1a4bf32
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ namespace bisect::nmoscpp

std::function<maybe_ok(unsigned int milliseconds, nmos::resources& resources, const nmos::id& resource_id)>
erase_resource_after_;

std::function<bisect::expected<nmos::resource>(unsigned int milliseconds, nmos::resources& resources,
const nmos::id& id)>
find_resource_after_;
};

using nmos_controller_uptr = std::unique_ptr<nmos_controller_t>;
Expand Down
67 changes: 38 additions & 29 deletions cpp/libs/bisect_nmoscpp/lib/src/nmos_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,27 @@ nmos_controller_t::nmos_controller_t(logger_t& logger, web::json::value configur
return {};
};

find_resource_after_ = [this](unsigned int milliseconds, nmos::resources& resources,
const nmos::id& id) -> expected<nmos::resource> {
auto lock = base_controller_.node_model_.read_lock();
if(nmos::details::wait_for(base_controller_.node_model_.shutdown_condition, lock,
std::chrono::milliseconds(delay_millis),
[&] { return base_controller_.node_model_.shutdown; }))
{
BST_FAIL("Could not lock node model in order to read the resources in it");
}

const auto resource_it = nmos::find_resource(resources, id);
if(resource_it == resources.end())
{
base_controller_.node_model_.notify();
BST_FAIL("Resource with id {} not found", utility::us2s(id));
}

base_controller_.node_model_.notify();
return *resource_it;
};

if(!nmos::experimental::fields::http_trace(base_controller_.node_model_.settings))
{
// Disable TRACE method
Expand Down Expand Up @@ -515,7 +536,7 @@ maybe_ok nmos_controller_t::insert_connection_resource(nmos::resource&& resource
auto id = resource.id;
BST_CHECK(
insert_resource_after_(delay_millis, base_controller_.node_model_.connection_resources, std::move(resource)));
BST_CHECK(find_resource(id));
BST_CHECK(find_connection_resource(id));

return {};
}
Expand Down Expand Up @@ -548,60 +569,52 @@ maybe_ok nmos_controller_t::modify_connection_receiver(const nmos_receiver_t& co

expected<nmos::resource> nmos_controller_t::find_resource(const nmos::id& id)
{
const auto resource_it = nmos::find_resource(base_controller_.node_model_.node_resources, id);
BST_ENFORCE(resource_it != base_controller_.node_model_.node_resources.end(),
"trying to find a non-existing NMOS resource {}", utility::us2s(id));
return *resource_it;
return find_resource_after_(delay_millis, base_controller_.node_model_.node_resources, id);
}

expected<nmos::resource> nmos_controller_t::find_connection_resource(const nmos::id& id)
{
const auto resource_it = nmos::find_resource(base_controller_.node_model_.connection_resources, id);
BST_ENFORCE(resource_it != base_controller_.node_model_.connection_resources.end(),
"trying to find a non-existing NMOS connection resource {}", utility::us2s(id));
return *resource_it;
return find_resource_after_(delay_millis, base_controller_.node_model_.connection_resources, id);
}

maybe_ok nmos_controller_t::erase_resource(const nmos::id& resource_id)
{

BST_CHECK(erase_resource_after_(delay_millis, base_controller_.node_model_.node_resources, resource_id));
auto resource = find_resource(resource_id);

const auto resource = nmos::find_resource(base_controller_.node_model_.node_resources, resource_id);
BST_ENFORCE(base_controller_.node_model_.node_resources.end() == resource,
"NMOS Resource with id {} was not deleted", utility::us2s(resource_id));
if(!is_error(resource))
{
BST_FAIL("Error erasing resource.");
}

return {};
}

maybe_ok nmos_controller_t::erase_connection_resource(const nmos::id& resource_id)
{
BST_CHECK(erase_resource_after_(delay_millis, base_controller_.node_model_.connection_resources, resource_id));
auto resource = find_connection_resource(resource_id);

const auto resource = nmos::find_resource(base_controller_.node_model_.connection_resources, resource_id);
BST_ENFORCE(base_controller_.node_model_.connection_resources.end() == resource,
"NMOS Connection resource with id {} was not deleted", utility::us2s(resource_id));
if(!is_error(resource))
{
BST_FAIL("Error erasing connection resource.");
}

return {};
}

maybe_ok nmos_controller_t::erase_device(const nmos::id& device_id)
{
const auto device =
nmos::find_resource(base_controller_.node_model_.node_resources, {device_id, nmos::types::device});
BST_ASSIGN(device, find_resource(device_id));

std::vector<maybe_ok> maybe_result_deleting_sub_resources;

std::transform(
device->sub_resources.begin(), device->sub_resources.end(),
device.sub_resources.begin(), device.sub_resources.end(),
std::back_inserter(maybe_result_deleting_sub_resources),
[this, resources = base_controller_.node_model_.node_resources](const nmos::id& sub_resource_id) -> maybe_ok {
const auto resource = nmos::find_resource(resources, sub_resource_id);
if(resources.end() == resource)
{
slog::log<slog::severities::severe>(base_controller_.gate_, SLOG_FLF)
<< "Sub-resource does not exist: " << sub_resource_id;
}
const auto resource = find_resource(sub_resource_id);
if(resource->type == nmos::types::receiver || resource->type == nmos::types::sender)
{
return erase_connection_resource(resource->id);
Expand All @@ -625,11 +638,7 @@ maybe_ok nmos_controller_t::erase_device(const nmos::id& device_id)

maybe_ok nmos_controller_t::update_transport_file(const nmos::id& sender_id)
{
const auto sender_it =
nmos::find_resource(base_controller_.node_model_.node_resources, {sender_id, nmos::types::sender});
BST_ENFORCE(sender_it == base_controller_.node_model_.node_resources.end(),
"trying to update the transport file of a non-existing NMOS sender {}", utility::us2s(sender_id));
auto& sender = *sender_it;
BST_ASSIGN(sender, find_resource(sender_id));

modify_connection_resource(sender_id, [this, &sender](nmos::resource& connection_sender) {
web::json::value endpoint_transportfile;
Expand Down
7 changes: 7 additions & 0 deletions cpp/libs/bisect_nmoscpp/lib/src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ using namespace bisect::core::detail;
using namespace bisect::nmoscpp;
namespace conan_sdp = sdp;

namespace
{
constexpr auto delay_millis{0};
}

// Example Connection API activation callback to resolve "auto" values when /staged is transitioned to /active
nmos::connection_resource_auto_resolver
bisect::nmoscpp::make_node_implementation_auto_resolver(const nmos::settings& settings,
Expand Down Expand Up @@ -181,6 +186,8 @@ nmos::interlace_mode bisect::get_interlace_mode(const nmos::settings& settings)
: nmos::interlace_modes::progressive;
}

/******************************** Warning ********************************/
/* before calling this function make sure that the model is locked in */
bisect::maybe_ok bisect::nmoscpp::build_transport_file(const nmos::resources& node_resources,
nmos_event_handler_t* event_handler,
const nmos::resource& sender,
Expand Down
8 changes: 4 additions & 4 deletions cpp/libs/ossrf_nmos_api/lib/src/nmos_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ maybe_ok nmos_client_t::add_receiver(const std::string& device_id, const std::st

receiver_config.master_enable = true;

BST_CHECK(impl_->context_->nmos().add_receiver(device_id, receiver_config));

auto r = std::make_shared<nmos_resource_receiver_t>(device_id, receiver_config, callback);
impl_->context_->resources().insert(device_id, std::move(r));
BST_CHECK(impl_->context_->nmos().add_receiver(device_id, receiver_config));

BST_CHECK(update_device_sub_resources(impl_->context_, device_id));

return {};
Expand All @@ -98,10 +98,10 @@ maybe_ok nmos_client_t::add_sender(const std::string& device_id, const std::stri

sender_config.master_enable = true;

auto s = std::make_shared<nmos_resource_sender_t>(device_id, sender_config, callback);
impl_->context_->resources().insert(device_id, std::move(s));
BST_CHECK(impl_->context_->nmos().add_sender(device_id, sender_config));

auto r = std::make_shared<nmos_resource_sender_t>(device_id, sender_config, callback);
impl_->context_->resources().insert(device_id, std::move(r));
BST_CHECK(update_device_sub_resources(impl_->context_, device_id));

return {};
Expand Down

0 comments on commit 1a4bf32

Please sign in to comment.