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>
500 using Pool = ::ipc::bipc::managed_shared_memory;
561 template<
typename Mode_tag>
562 explicit Pool_arena(Mode_tag mode_tag, flow::log::Logger* logger_ptr,
const Shared_name& pool_name,
size_t pool_sz,
579 template<
typename T,
typename... Ctor_args>
580 static void construct_at(T* obj, Ctor_args&&... ctor_args);
613 const auto p =
reinterpret_cast<const uint8_t*
>(handle.get());
614 const auto pool_base =
static_cast<const uint8_t*
>(
m_pool->get_address());
615 return (p >= pool_base) && (p < (pool_base +
m_pool->get_size()));
618template<
typename T,
typename... Ctor_args>
623 using boost::shared_ptr;
631 const auto handle_state =
static_cast<Shm_handle*
>(
allocate(
sizeof(Value)));
637 construct_at(&handle_state->m_obj, std::forward<Ctor_args>(ctor_args)...);
640 shared_ptr<Shm_handle> real_shm_handle(handle_state, [
this](Shm_handle* handle_state)
642 handle_deleter_impl<Value>(handle_state);
646 return Handle<Value>(std::move(real_shm_handle), &handle_state->m_obj);
655 using flow::util::buffers_dump_string;
663 const auto handle_state =
reinterpret_cast<Shm_handle*
>(handle.get());
664 const auto new_owner_ct = ++handle_state->m_atomic_owner_ct;
666 const ptrdiff_t offset_from_pool_base =
reinterpret_cast<const uint8_t*
>(handle_state)
667 -
static_cast<const uint8_t*
>(
m_pool->get_address());
669 Blob serialization(
sizeof(offset_from_pool_base));
670 *(
reinterpret_cast<ptrdiff_t*
>(serialization.data())) = offset_from_pool_base;
672 FLOW_LOG_TRACE(
"SHM-classic pool [" << *
this <<
"]: Serializing SHM outer handle [" << handle <<
"] before "
673 "IPC-transmission: Owning process-count incremented to [" << new_owner_ct <<
"] "
674 "(may change concurrently). "
675 "Handle points to SHM-offset [" << offset_from_pool_base <<
"] (serialized). Serialized contents are "
676 "[" << buffers_dump_string(serialization.const_buffer(),
" ") <<
"].");
678 return serialization;
686 using flow::util::buffers_dump_string;
687 using boost::shared_ptr;
695 ptrdiff_t offset_from_pool_base;
696 assert((serialization.size() ==
sizeof(offset_from_pool_base))
697 &&
"lend_object() and borrow_object() incompatible? Bug?");
699 offset_from_pool_base = *(
reinterpret_cast<decltype(offset_from_pool_base)
const *
>
700 (serialization.const_data()));
701 const auto handle_state
702 =
reinterpret_cast<Shm_handle*
>
703 (
static_cast<uint8_t*
>(
m_pool->get_address()) + offset_from_pool_base);
707 shared_ptr<Shm_handle> real_shm_handle(handle_state, [
this](Shm_handle* handle_state)
709 handle_deleter_impl<Value>(handle_state);
712 FLOW_LOG_TRACE(
"SHM-classic pool [" << *
this <<
"]: Deserialized SHM outer handle [" << real_shm_handle <<
"] "
713 "(type [" <<
typeid(Value).name() <<
"]) "
714 "after IPC-receipt: Owner-count is at [" << handle_state->m_atomic_owner_ct <<
"] "
715 "(may change concurrently; but includes us at least hence must be 1+). "
716 "Handle points to SHM-offset [" << offset_from_pool_base <<
"] (deserialized). Serialized "
717 "contents are [" << buffers_dump_string(serialization.const_buffer(),
" ") <<
"].");
719 return Handle<Value>(std::move(real_shm_handle), &handle_state->m_obj);
730 assert((prev_owner_ct != 0) &&
"How was owner_ct=0, yet handle was still alive? Bug?");
732 FLOW_LOG_TRACE(
"SHM-classic pool [" << *
this <<
"]: Return SHM outer handle [" << handle_state <<
"] "
733 "(type [" <<
typeid(Value).name() <<
"]) "
734 "because, for a given owner, a Handle is being destroyed due to shared_ptr ref-count reaching 0: "
735 "Owner-count decremented to [" << (prev_owner_ct - 1) <<
"] (may change concurrently "
736 "unless 0). If it is 0 now, shall invoke dtor and SHM-dealloc now.");
737 if (prev_owner_ct == 1)
747 (handle_state->
m_obj).~Value();
756template<
typename T,
typename... Ctor_args>
762 ::new (
const_cast<void*
>
763 (
static_cast<void const volatile *
>
765 Value(std::forward<Ctor_args>(ctor_args)...);
768template<
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...