25#include <flow/util/basic_blob.hpp>
26#include <boost/interprocess/managed_shared_memory.hpp>
149 public flow::log::Log_context,
150 private boost::noncopyable
192 using Blob = flow::util::Blob_sans_log_context;
341 template<
typename Handle_name_func>
421 template<
typename T,
typename... Ctor_args>
502 using Pool = ::ipc::bipc::managed_shared_memory;
563 template<
typename Mode_tag>
564 explicit Pool_arena(Mode_tag mode_tag, flow::log::Logger* logger_ptr,
const Shared_name& pool_name,
size_t pool_sz,
581 template<
typename T,
typename... Ctor_args>
582 static void construct_at(T* obj, Ctor_args&&... ctor_args);
615 const auto p =
reinterpret_cast<const uint8_t*
>(handle.get());
616 const auto pool_base =
static_cast<const uint8_t*
>(
m_pool->get_address());
617 return (p >= pool_base) && (p < (pool_base +
m_pool->get_size()));
620template<
typename T,
typename... Ctor_args>
625 using boost::shared_ptr;
633 const auto handle_state =
static_cast<Shm_handle*
>(
allocate(
sizeof(Value)));
639 construct_at(&handle_state->m_obj, std::forward<Ctor_args>(ctor_args)...);
642 shared_ptr<Shm_handle> real_shm_handle(handle_state, [
this](Shm_handle* handle_state)
644 handle_deleter_impl<Value>(handle_state);
648 return Handle<Value>(std::move(real_shm_handle), &handle_state->m_obj);
657 using flow::util::buffers_dump_string;
665 const auto handle_state =
reinterpret_cast<Shm_handle*
>(handle.get());
666 const auto new_owner_ct = ++handle_state->m_atomic_owner_ct;
668 const ptrdiff_t offset_from_pool_base =
reinterpret_cast<const uint8_t*
>(handle_state)
669 -
static_cast<const uint8_t*
>(
m_pool->get_address());
671 Blob serialization(
sizeof(offset_from_pool_base));
672 *(
reinterpret_cast<ptrdiff_t*
>(serialization.data())) = offset_from_pool_base;
674 FLOW_LOG_TRACE(
"SHM-classic pool [" << *
this <<
"]: Serializing SHM outer handle [" << handle <<
"] before "
675 "IPC-transmission: Owning process-count incremented to [" << new_owner_ct <<
"] "
676 "(may change concurrently). "
677 "Handle points to SHM-offset [" << offset_from_pool_base <<
"] (serialized). Serialized contents are "
678 "[" << buffers_dump_string(serialization.const_buffer(),
" ") <<
"].");
680 return serialization;
688 using flow::util::buffers_dump_string;
689 using boost::shared_ptr;
697 ptrdiff_t offset_from_pool_base;
698 assert((serialization.size() ==
sizeof(offset_from_pool_base))
699 &&
"lend_object() and borrow_object() incompatible? Bug?");
701 offset_from_pool_base = *(
reinterpret_cast<decltype(offset_from_pool_base)
const *
>
702 (serialization.const_data()));
703 const auto handle_state
704 =
reinterpret_cast<Shm_handle*
>
705 (
static_cast<uint8_t*
>(
m_pool->get_address()) + offset_from_pool_base);
709 shared_ptr<Shm_handle> real_shm_handle(handle_state, [
this](Shm_handle* handle_state)
711 handle_deleter_impl<Value>(handle_state);
714 FLOW_LOG_TRACE(
"SHM-classic pool [" << *
this <<
"]: Deserialized SHM outer handle [" << real_shm_handle <<
"] "
715 "(type [" <<
typeid(Value).name() <<
"]) "
716 "after IPC-receipt: Owner-count is at [" << handle_state->m_atomic_owner_ct <<
"] "
717 "(may change concurrently; but includes us at least hence must be 1+). "
718 "Handle points to SHM-offset [" << offset_from_pool_base <<
"] (deserialized). Serialized "
719 "contents are [" << buffers_dump_string(serialization.const_buffer(),
" ") <<
"].");
721 return Handle<Value>(std::move(real_shm_handle), &handle_state->m_obj);
732 assert((prev_owner_ct != 0) &&
"How was owner_ct=0, yet handle was still alive? Bug?");
734 FLOW_LOG_TRACE(
"SHM-classic pool [" << *
this <<
"]: Return SHM outer handle [" << handle_state <<
"] "
735 "(type [" <<
typeid(Value).name() <<
"]) "
736 "because, for a given owner, a Handle is being destroyed due to shared_ptr ref-count reaching 0: "
737 "Owner-count decremented to [" << (prev_owner_ct - 1) <<
"] (may change concurrently "
738 "unless 0). If it is 0 now, shall invoke dtor and SHM-dealloc now.");
739 if (prev_owner_ct == 1)
749 (handle_state->
m_obj).~Value();
758template<
typename T,
typename... Ctor_args>
764 ::new (
const_cast<void*
>
765 (
static_cast<void const volatile *
>
767 Value(std::forward<Ctor_args>(ctor_args)...);
770template<
typename Handle_name_func>
A SHM-classic interface around a single SHM pool with allocation-algorithm services by boost....
::ipc::bipc::offset_ptr< T > Pointer
SHM-storable fancy-pointer.
Pool_arena(flow::log::Logger *logger_ptr, const Shared_name &pool_name, util::Create_only mode_tag, size_t pool_sz, const util::Permissions &perms=util::Permissions(), Error_code *err_code=0)
Construct Pool_arena accessor object to non-existing named SHM pool, creating it first.
static void construct_at(T *obj, Ctor_args &&... ctor_args)
std::construct_at() equivalent; unavailable until C++20, so here it is.
bool deallocate(void *buf_not_null) noexcept
Undoes effects of local allocate() that returned buf_not_null; or another-process's allocate() that r...
boost::movelib::unique_ptr< Pool > m_pool
Attached SHM pool. If ctor fails in non-throwing fashion then this remains null. Immutable after ctor...
::ipc::bipc::managed_shared_memory Pool
The SHM pool type one instance of which is managed by *this.
boost::shared_ptr< T > Handle
Outer handle to a SHM-stored object; really a regular-looking shared_ptr but with custom deleter that...
const Shared_name m_pool_name
SHM pool name as set immutably at construction.
flow::util::Blob_sans_log_context Blob
Alias for a light-weight blob.
void * allocate(size_t n)
Allocates buffer of specified size, in bytes, in the accessed pool; returns locally-derefernceable ad...
static void for_each_persistent(const Handle_name_func &handle_name_func)
Lists all named SHM pool objects currently persisting, invoking the given handler synchronously on ea...
Handle< T > construct(Ctor_args &&... ctor_args)
Constructs an object of given type with given ctor args, having allocated space directly in attached ...
~Pool_arena()
Destroys Pool_arena accessor object.
Blob lend_object(const Handle< T > &handle)
Adds an owner process to the owner count of the given construct()-created handle, and returns an opaq...
bool is_handle_in_arena(const Handle< T > &handle) const
Returns true if and only if handle came from either this->construct<T>() or this->borrow_object<T>().
Handle< T > borrow_object(const Blob &serialization)
Completes the cross-process operation begun by lend_object() that returned serialization; to be invok...
void handle_deleter_impl(Handle_in_shm< T > *handle_state)
Identical deleter for Handle returned by both construct() and borrow_object(); invoked when a given p...
static void remove_persistent(flow::log::Logger *logger_ptr, const Shared_name &name, Error_code *err_code=0)
Removes the named SHM pool object.
RAII-style class operating a stack-like notion of a the given thread's currently active SHM-aware Are...
String-wrapping abstraction representing a name uniquely distinguishing a kernel-persistent entity fr...
ipc::shm sub-module with the SHM-classic SHM-provider. See ipc::shm doc header for introduction.
bipc::permissions Permissions
Short-hand for Unix (POSIX) permissions class.
bipc::open_only_t Open_only
Tag type indicating an ideally-atomic open-if-exists-else-fail operation.
void for_each_persistent_shm_pool(const Handle_name_func &handle_name_func)
Equivalent to shm::classic::Pool_arena::for_each_persistent().
bipc::open_or_create_t Open_or_create
Tag type indicating an atomic open-if-exists-else-create operation.
bipc::create_only_t Create_only
Tag type indicating a create-unless-exists-else-fail operation.
boost::asio::const_buffer Blob_const
Short-hand for an immutable blob somewhere in memory, stored as exactly a void const * and a size_t.
flow::Error_code Error_code
Short-hand for flow::Error_code which is very common.
The data structure stored in SHM corresponding to an original construct()-returned Handle; exactly on...
Atomic_owner_ct m_atomic_owner_ct
See Atomic_owner_ct doc header. This value is 1+; once it reaches 0 *this is destroyed in SHM.
T m_obj
The constructed object; Handle::get() returns &m_obj.
std::atomic< unsigned int > Atomic_owner_ct
Atomically accessed count of each time the following events occurs for a given Handle_in_shm in the b...