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...