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