/* * Copyright (c) 2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include namespace Kernel { static Atomic s_hostname_context_id = 0; static Singleton> s_all_instances {}; UNMAP_AFTER_INIT ErrorOr> HostnameContext::create_initial() { return create_with_name("courage"sv); } ErrorOr> HostnameContext::create_with_name(StringView name) { return s_all_instances->with([&](auto& list) -> ErrorOr> { auto hostname_context = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) HostnameContext(name))); list.append(hostname_context); return hostname_context; }); } ErrorOr> HostnameContext::hostname_context_for_id(int id) { if (id < 0) return Error::from_errno(EINVAL); auto index = static_cast(id); return s_all_instances->with([&](auto& list) -> ErrorOr> { for (auto& hostname_context : list) { if (hostname_context.id() == index) return hostname_context; } return Error::from_errno(ESRCNOTFOUND); }); } void HostnameContext::set_attached(Badge) { m_attach_count.with([&](auto& my_attach_count) { my_attach_count++; s_all_instances->with([&](auto& list) { // NOTE: It could happen that we have been detached from the // global list but a Process got a reference and wants to // attach so now re-attach this context. if (!list.contains(*this)) list.append(*this); }); }); } void HostnameContext::detach(Badge) { VERIFY(ref_count() > 0); m_attach_count.with([&](auto& my_attach_count) { VERIFY(my_attach_count > 0); my_attach_count--; if (my_attach_count == 0) { s_all_instances->with([&](auto&) { m_list_node.remove(); }); } }); } HostnameContext::HostnameContext(StringView name) : m_id(s_hostname_context_id.fetch_add(1)) { m_buffer.with([name](auto& buffer) { buffer.store_characters(name); }); } }