Flow-IPC 1.0.1
Flow-IPC project: Full implementation reference.
Classes | Public Types | Public Member Functions | Static Public Attributes | Protected Types | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | Related Functions | List of all members
ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V > Class Template Reference

Internal, non-movable pImpl-lite implementation of Client_session_mv class template. More...

#include <client_session_impl.hpp>

Inheritance diagram for ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >:
[legend]
Collaboration diagram for ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >:
[legend]

Classes

struct  Master_channel_req
 An open-channel/log-in request out-message. More...
 

Public Types

using Base = Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
 Short-hand for base type. More...
 
using Session_base_obj = Base
 Short-hand for Session_base super-class. More...
 
using Channel_obj = typename Base::Channel_obj
 See Client_session_mv counterpart. More...
 
using Channels = typename Base::Channels
 See Session_mv counterpart. More...
 
using Mdt_payload_obj = typename Base::Mdt_payload_obj
 See Client_session_mv counterpart. More...
 
using Mdt_reader_ptr = typename Base::Mdt_reader_ptr
 See Client_session_mv counterpart. More...
 
using Mdt_builder = typename Base::Mdt_builder
 See Client_session_mv counterpart. More...
 
using Mdt_builder_ptr = typename Base::Mdt_builder_ptr
 See Client_session_mv counterpart. More...
 
using Structured_msg_builder_config = typename Base::Structured_msg_builder_config
 See Session_mv counterpart. More...
 
using Structured_msg_reader_config = typename Base::Structured_msg_reader_config
 See Session_mv counterpart. More...
 
- Public Types inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
using Persistent_mq_handle_from_cfg = std::conditional_t<!S_MQS_ENABLED, transport::Null_peer, std::conditional_t< S_MQ_TYPE_OR_NONE==schema::MqType::POSIX, transport::Posix_mq_handle, transport::Bipc_mq_handle > >
 Relevant only if S_MQS_ENABLED, this is the Persistent_mq_handle-concept impl type specified by the user via S_MQ_TYPE_OR_NONE. More...
 
using Channel_obj = std::conditional_t< S_MQS_ENABLED, std::conditional_t< S_TRANSMIT_NATIVE_HANDLES, transport::Mqs_socket_stream_channel< true, Persistent_mq_handle_from_cfg >, transport::Mqs_channel< true, Persistent_mq_handle_from_cfg > >, std::conditional_t< S_TRANSMIT_NATIVE_HANDLES, transport::Socket_stream_channel< true >, transport::Socket_stream_channel_of_blobs< true > > >
 See Session_mv (or Session concept). More...
 
using Channels = std::vector< Channel_obj >
 See Session_mv. Note: If changed from vector please update those doc headers too. More...
 
using Mdt_payload_obj = Mdt_payload
 See Session_mv (or Session concept). More...
 
using Mdt_reader_ptr = boost::shared_ptr< typename transport::struc::schema::Metadata< Mdt_payload_obj >::Reader >
 See Session_mv (or Session concept). More...
 
using Mdt_builder = typename transport::struc::schema::Metadata< Mdt_payload_obj >::Builder
 See Session_mv (or Session concept). More...
 
using Mdt_builder_ptr = boost::shared_ptr< Mdt_builder >
 See Session_mv (or Session concept). More...
 
using Structured_msg_builder_config = transport::struc::Heap_fixed_builder::Config
 See Session_mv (or Session concept). More...
 
using Structured_msg_reader_config = transport::struc::Heap_reader::Config
 See Session_mv (or Session concept). More...
 

Public Member Functions

template<typename On_passive_open_channel_handler , typename Task_err >
 Client_session_impl (flow::log::Logger *logger_ptr, const Client_app &cli_app_ref, const Server_app &srv_app_ref, Task_err &&on_err_func, On_passive_open_channel_handler &&on_passive_open_channel_func)
 See Client_session_mv counterpart. More...
 
template<typename Task_err >
 Client_session_impl (flow::log::Logger *logger_ptr, const Client_app &cli_app_ref, const Server_app &srv_app_ref, Task_err &&on_err_func)
 See Client_session_mv counterpart. More...
 
 ~Client_session_impl ()
 See Client_session_mv counterpart. More...
 
Mdt_builder_ptr mdt_builder () const
 See Client_session_mv counterpart. More...
 
bool sync_connect (Error_code *err_code)
 See Client_session_mv counterpart. More...
 
bool sync_connect (const Mdt_builder_ptr &mdt, Channels *init_channels_by_cli_req_pre_sized, Mdt_reader_ptr *mdt_from_srv_or_null, Channels *init_channels_by_srv_req, Error_code *err_code)
 See Client_session_mv counterpart. More...
 
bool open_channel (Channel_obj *target_channel, const Mdt_builder_ptr &mdt, Error_code *err_code)
 See Client_session_mv counterpart. More...
 
bool open_channel (Channel_obj *target_channel, Error_code *err_code)
 See Client_session_mv counterpart. More...
 
const Session_tokensession_token () const
 See Client_session_mv counterpart. More...
 
- Public Member Functions inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
const Shared_namesrv_namespace () const
 See Server_session_impl, Client_session_impl. More...
 
const Shared_namecli_namespace () const
 See Server_session_impl, Client_session_impl. More...
 
const Client_appcli_app_ptr () const
 See Server_session_impl, Client_session_impl. More...
 
Shared_name cur_ns_store_mutex_absolute_name () const
 Computes the name of the interprocess named-mutex used to control reading/writing to the file storing (written by server, read by client) the value for srv_namespace(). More...
 
fs::path cur_ns_store_absolute_path () const
 Computes the absolute path to file storing (written by server, read by client) the value for srv_namespace(). More...
 
Shared_name session_master_socket_stream_acceptor_absolute_name () const
 Computes the absolute name at which the server shall set up a transport::Native_socket_stream_acceptor to which client shall transport::Native_socket_stream::sync_connect() in order to establish a PEER-state session. More...
 

Static Public Attributes

static constexpr schema::ShmType S_SHM_TYPE = S_SHM_TYPE_OR_NONE
 See Session_mv counterpart. More...
 
static constexpr bool S_SHM_ENABLED = S_SHM_TYPE != schema::ShmType::NONE
 See Session_mv counterpart. More...
 
static constexpr bool S_MQS_ENABLED = Base::S_MQS_ENABLED
 See Client_session_mv counterpart. More...
 
static constexpr bool S_SOCKET_STREAM_ENABLED = Base::S_SOCKET_STREAM_ENABLED
 See Client_session_mv counterpart. More...
 
static constexpr bool S_GRACEFUL_FINISH_REQUIRED = S_GRACEFUL_FINISH_REQUIRED_V
 Short-hand for template parameter knob S_GRACEFUL_FINISH_REQUIRED_V: see class template doc header. More...
 
- Static Public Attributes inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
static constexpr bool S_MQS_ENABLED = S_MQ_TYPE_OR_NONE != schema::MqType::NONE
 See Session_mv. More...
 
static constexpr bool S_SOCKET_STREAM_ENABLED = (!S_MQS_ENABLED) || S_TRANSMIT_NATIVE_HANDLES
 See Session_mv. More...
 

Protected Types

using Master_structured_channel = typename Base::Master_structured_channel
 See Session_base. More...
 
- Protected Types inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
using Master_structured_channel = transport::struc::Channel_via_heap< transport::Socket_stream_channel< true >, schema::detail::SessionMasterChannelMessageBody< Mdt_payload_obj > >
 The (internally used) session master channel is a transport::struc::Channel of this concrete type. More...
 
using Master_structured_channel_ptr = boost::shared_ptr< Master_structured_channel >
 Handle to Master_structured_channel. More...
 
using Master_structured_channel_observer = boost::weak_ptr< Master_structured_channel >
 Observer of Master_structured_channel_ptr. See its doc header. More...
 
using On_passive_open_channel_func = Function< void(Channel_obj &&new_channel, Mdt_reader_ptr &&new_channel_mdt)>
 Concrete function type for the on-passive-open handler (if any), used for storage. More...
 

Protected Member Functions

bool sync_connect_impl (Error_code *err_code, Function< bool(flow::async::Task_asio_err &&)> *async_connect_impl_func)
 Utility for *this and sub-classes: Implements sync_connect() given a functor that invokes the calling class's (including Client_session_impl) async_connect() with the args passed to the calling sync_connect(). More...
 
template<typename Task_err >
bool async_connect (const Mdt_builder_ptr &mdt, Channels *init_channels_by_cli_req_pre_sized, Mdt_reader_ptr *mdt_from_srv_or_null, Channels *init_channels_by_srv_req, Task_err &&on_done_func)
 Core implementation of sync_connect(). More...
 
void cancel_peer_state_to_null ()
 Utility for sub-classes: executed from async_connect()'s on_done_func(Error_code()) (i.e., directly from handler invoked on success) – hence from thread W – this instead goes back to NULL state, essentially indicating "never mind -- this successful async_connect() actually failed.". More...
 
template<typename Task_err >
Master_structured_channelcancel_peer_state_to_connecting (Task_err &&on_done_func)
 Utility for sub-classes: executed from async_connect()'s on_done_func(Error_code()) (i.e., directly from handler invoked on success) – hence from thread W – this instead goes back to CONNECTING state, essentially indicating "yes, the vanilla async_connect() succeeded, but the true user-called async_connect() that piggybacked on the vanilla one will now do some more async stuff before reaching PEER state (or NULL on error). More...
 
void complete_async_connect_after_canceling_peer_state (const Error_code &err_code_or_success)
 Utility for sub-classes: to be invoked, only from thread W and asynchronously at that, after cancel_peer_state_to_connecting(), this indicates the completion of the sub-class's additional async-connect steps, setting state to either NULL or PEER. More...
 
flow::async::Single_thread_task_loop * async_worker ()
 Utility for sub-classes: provides ability to schedule or post tasks onto thread W. More...
 
const Master_structured_channelmaster_channel_const () const
 Utility for sub-classes: provides ability to immutably query the session master channel, particularly after our async_accept_log_in() succeeds, but before the sub-classed wrapper of its on-done handler succeeds. More...
 
void dtor_async_worker_stop ()
 Synchronously stops async_worker() loop, the post-condition being that thread W has been joined; no tasks post()ed onto it by *this or subclass shall execute after this returns. More...
 
- Protected Member Functions inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
 Session_base (const Client_app &cli_app_ref, const Server_app &srv_app_ref, flow::async::Task_asio_err &&on_err_func, On_passive_open_channel_func &&on_passive_open_channel_func_or_empty_arg)
 Constructs: Client_session_impl form (the user is the one constructing the object, though in NULL state). More...
 
 Session_base (const Server_app &srv_app_ref)
 Constructs: Server_session_impl form (Session_server is the one constructing the object, though in NULL state, before log-in has completed, but after the socket-stream connection has been established). More...
 
void set_srv_namespace (Shared_name &&srv_namespace_new)
 Sets srv_namespace() (do not call if already set). More...
 
void set_cli_namespace (Shared_name &&cli_namespace_new)
 Sets cli_namespace() (do not call if already set). More...
 
void set_cli_app_ptr (const Client_app *cli_app_ptr_new)
 Sets cli_app_ptr() (do not call if already set). More...
 
void set_on_passive_open_channel_func (On_passive_open_channel_func &&on_passive_open_channel_func)
 Sets on_passive_open_channel_func_or_empty() (do not call if already set; do not call if user intends for passive-opens to be disabled on this side). More...
 
void set_on_err_func (flow::async::Task_asio_err &&on_err_func_arg)
 Sets on_err_func() (do not call if already set). More...
 
bool on_err_func_set () const
 Returns true if and only if set_on_err_func() has been called. More...
 
const On_passive_open_channel_funcon_passive_open_channel_func_or_empty () const
 The on-passive-open handler (may be empty even in final state, meaning user wants passive-opens disabled on this side). More...
 
void hose (const Error_code &err_code)
 Marks this session as hosed for (truthy) reason err_code; and synchronously invokes on-error handler; only invoke if not already hosed(). More...
 
bool hosed () const
 Returns true if and only if hose() has been called. More...
 

Private Types

enum class  State { S_NULL , S_CONNECTING , S_PEER }
 Overall state of a Client_session_impl. More...
 
using Master_structured_channel_ptr = typename Base::Master_structured_channel_ptr
 See Session_base. More...
 
using Master_structured_channel_observer = typename Base::Master_structured_channel_observer
 See Session_base. More...
 
using Persistent_mq_handle_from_cfg = typename Base::Persistent_mq_handle_from_cfg
 See Session_base. More...
 
using On_passive_open_channel_func = typename Base::On_passive_open_channel_func
 See Session_base. More...
 
using Master_channel_req_ptr = boost::shared_ptr< Master_channel_req >
 Short-hand for ref-counted pointer to Master_channel_req. More...
 

Private Member Functions

 Client_session_impl (flow::log::Logger *logger_ptr, const Client_app &cli_app_ref, const Server_app &srv_app_ref, flow::async::Task_asio_err &&on_err_func, On_passive_open_channel_func &&on_passive_open_channel_func_or_empty_arg, std::nullptr_t tag)
 Delegated-to ctor that implements both non-default public ctors. More...
 
void on_master_channel_error (const Master_structured_channel_observer &master_channel_observer, const Error_code &err_code)
 In thread W, handler for m_master_channel indicating incoming-direction channel-hosing error. More...
 
void on_master_channel_log_in_rsp (typename Master_structured_channel::Msg_in_ptr &&log_in_rsp, Channels *init_channels_by_cli_req_pre_sized, Mdt_reader_ptr *mdt_from_srv_or_null, Channels *init_channels_by_srv_req)
 In thread W, handler for the successful receipt of log-in response (upon send()ing the log-in request), as invoked in CONNECTING state only if the low-level transport::Native_socket_stream::async_connect() succeeded. More...
 
void on_master_channel_init_open_channel (typename Master_structured_channel::Msg_in_ptr &&open_channel_msg, size_t n_init_channels, const boost::shared_ptr< Channels > &init_channels_ptr, Channels *init_channels_by_cli_req_pre_sized, Mdt_reader_ptr *mdt_from_srv_or_null, Channels *init_channels_by_srv_req, Mdt_reader_ptr &&mdt_from_srv)
 In thread W, handler for m_master_channel receiving a init-channel-open message. More...
 
void on_master_channel_open_channel_req (typename Master_structured_channel::Msg_in_ptr &&open_channel_req)
 In thread W, handler for m_master_channel receiving a passive-open (a/k/a open-channel-to-client) request. More...
 
void create_channel_obj (const Shared_name &mq_name_c2s_or_none, const Shared_name &mq_name_s2c_or_none, util::Native_handle &&local_hndl_or_null, Channel_obj *opened_channel_ptr, bool active_else_passive, Error_code *err_code_ptr)
 In thread W, based on resources acquired on server side, creates local Channel_obj to emit to the user thus completing a channel-open. More...
 
void invoke_conn_on_done_func (const Error_code &err_code)
 Little helper that invokes m_conn_on_done_func_or_empty, passing it err_code, and – per that member's internal use semantics – empties m_conn_on_done_func_or_empty. More...
 

Private Attributes

State m_state
 The current state of *this. More...
 
transport::Protocol_negotiator m_protocol_negotiator
 Handles the protocol negotiation at the start of the pipe, as pertains to algorithms perpetuated by the vanilla ipc::session Session hierarchy. More...
 
transport::Protocol_negotiator m_protocol_negotiator_aux
 Analogous to m_protocol_negotiator but pertains to algorithms perpetuated by (if relevant) non-vanilla ipc::session Session hierarchy implemented on top of our vanilla ipc::session Session hierarchy. More...
 
flow::async::Task_asio_err m_conn_on_done_func_or_empty
 The on_done_func argument to async_connect(); .empty() except while in State::S_CONNECTING state. More...
 
unsigned int m_last_actively_opened_channel_id
 Logging-only *this-unique ID used in nicknaming the last actively-opened (via open_channel()) channel. More...
 
unsigned int m_last_passively_opened_channel_id
 A-la m_last_actively_opened_channel_id but for passively-opened channels (on_master_channel_open_channel_req()). More...
 
flow::async::Single_thread_task_loop m_async_worker
 Worker thread (a/k/a thread W). More...
 
Master_structured_channel_ptr m_master_channel
 The session master channel. More...
 
std::optional< typename Base::Graceful_finisherm_graceful_finisher
 Null until PEER state is reached, and NULL unless compile-time S_GRACEFUL_FINISH_REQUIRED is true, this is used to block at the start of dtor to synchronize with the opposing Session dtor for safety. More...
 

Related Functions

(Note that these are not member functions.)

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
std::ostream & operator<< (std::ostream &os, const Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V > &val)
 Prints string representation of the given Client_session_impl to the given ostream. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
static Structured_msg_builder_config heap_fixed_builder_config (flow::log::Logger *logger_ptr)
 See Session_mv::heap_fixed_builder_config() (1-arg). More...
 
static Structured_msg_reader_config heap_reader_config (flow::log::Logger *logger_ptr)
 See Session_mv::heap_reader_config() (1-arg). More...
 
- Public Attributes inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
const Server_appm_srv_app_ref
 Reference to Server_app (referring to local process in Server_session_impl, opposing process in Client_session_impl). More...
 
- Static Protected Attributes inherited from ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >
static constexpr util::Fine_duration S_OPEN_CHANNEL_TIMEOUT = boost::chrono::seconds(60)
 Internal timeout for open_channel(). More...
 
static constexpr size_t S_MQS_MAX_MSG_SZ = 8 * 1024
 The max sendable MQ message size as decided by Server_session_impl::make_channel_mqs() (and imposed on both sides, both directions), if S_MQS_ENABLED and Server_session_impl::S_SHM_ENABLED is false, when a channel is opened (regardless of which side did the active-open or requested pre-opening at session start). More...
 

Detailed Description

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload, schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
class ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >

Internal, non-movable pImpl-lite implementation of Client_session_mv class template.

In and of itself it would have been directly and publicly usable; however Client_session_mv adds move semantics.

See also
All discussion of the public API is in Client_session_mv doc header; that class template forwards to this one. All discussion of pImpl-lite-related notions is also there. See that doc header first please. Then come back here.

Impl design

Thread U represents all threads other than thread W: since the relevant methods are to be called by the user sans concurrency, those threads as a collection can be thought of as one thread.

Thread W is the async worker thread where most work is done; this helps us entirely avoid mutexes. Both async_connect() (from sync_connect()) and open_channel() are fairly infrequently called, so it's not necessary to avoid latency by doing work concurrently in threads U and W. So we keep it simple by posting most stuff onto thread W.

There are two distinct states (other than NULL): CONNECTING (async_connect() outstanding) and PEER (it succeeded: *this is now a Session in PEER state per concept). (As of this writing async_connect() is private and invoked by public sync_connect(); more on that jsut below.)

CONNECTING state impl

Once async_connect() is issued we must do the following:

  1. Synchronously find out the full Shared_name where the opposing Session_server is allegedly listening, which is computable by a Base helper. So that it can be computed we need to find out Session_base::srv_namespace() which we immediately do by checking the expected file that should have been written by Session_server.
  2. Issue the Native_socket_stream::sync_connect() which shall synchronously/non-blockingly connect to that abstract-address.
  3. Once that's done, go back to NULL on failure; or continue as follows on success: The Native_socket_stream, now in PEER state (connected), is upgraded to (wrapped by) a transport::Channel which is in turn upgraded to a transport::struc::Channel Client_session_impl::m_master_channel. This is the session master channel, in log-in phase (as client) (details of that API are in transport::struc::Channel docs). So we immediately issue the next async step: sending the log-in request over m_master_channel and async-await log-in response.
  4. Once that's done, go back to NULL on failure; or else yay: we're now in PEER state...
  5. ...almost. If the advanced form of sync_connect() was the one invoked, there's an additional exchange of info about init-channels, wherein the opposing Session_server sends us info about the pre-opened init-channels. If so, PEER state is reached upon receipt of this; otherwise immediately.

See session_master_channel.capnp for the schema for m_master_channel. Reading that gives a nice overview of the protocol involved, both in CONNECTING (after the socket is connected) and in PEER. Also notable is that this setup allows us to immediately "eat our own dog food" by using a struc::Channel to enable the opening of any further channels (structured or otherwise).

CONNECTING state and asynchronicity

As written, sync_connect() – as a black box – is synchronous and non-blocking. It is written trivially as invoking async_connect() (which is private); giving it a simple completion handler that fulfills a promise; sync_connect() awaits this fulfillment in the user's calling thread and then returns. This raises two key questions.

One, how is this even possible – if there's (even internally) an async step, how can sync_connect() be synchronous yet non-blocking? Answer: First we quote the Client_session_mv public doc header which explains why there is only sync_connect() but no async_connect(): "Without networking, the other side (Session_server) either exists/is listening; or no. Connecting is a synchronous, non-blocking operation; so an <tt>async_connect()</tt> API in this context only makes life harder for the user. (However, there are some serious plans to add a networking-capable counterpart (probably via TCP at least) to <tt>Native_socket_stream</tt> and therefore Client_session_mv; such a networky-client-session class will almost certainly have an <tt>async_connect()</tt>, while its <tt>sync_connect()</tt> will probably become potentially blocking.)" So that is why it works: in a local setting, the socket-connect is synchronous/fast; and upon connecting the necessary log-in/init-channel exchange is also quick.

Two: Why is it written like this? Wouldn't the internal code be simpler, if it lacked asynchronicity? The answer is two-fold:

A related aspect is that on_done_func completion handler we pass to async_connect() currently will fire before sync_connect() returns; so there's no contract for the dtor to fire it with operation-aborted error code, and we can just assert() on this in dtor and not worry about it further. Yet if async_connect() becomes public, then there's no longer that guarantee, and we'll need to fire it as needed from dtor.

In the code itself we sometimes refer to the above discussion to hopefully make maintenance/future development easier.

Note
If some form of *this becomes network-enabled, open_channel() too will need an async form most likely, while existing open_channel() would become potentially-blocking.

Protocol negotiation

First please see transport::struc::sync_io::Channel doc header section of the same name. (There is involved discussion there which we definitely don't want to repeat.) Then come back here.

How we're similar: Channel decided to divide the protocols into 2: one in struc::sync_io::Channel code itself, and the rest in whatever extra stuff might be involved in the (likely SHM-related, optionally used) non-vanilla transport::struc::Struct_builder and transport::struc::Struct_reader concept impls (namely most likely transport::struc::shm::Builder and transport::struc::shm::Reader). So essentially there's the ipc_transport_structured part, and the (other) part (likely but not necessarily from ipc_shm). We do something vaguely similar conceptually:

So we, too, maintain two Protocol_negotiators: the main one and the "aux" one for those two bullet points respectively. As of this writing there is only version 1 of everything; but if this changes for one of the "aux" Session hierarchies – e.g., SHM-jemalloc's internally used ipc_session_message.capnp channel/schema – then that guy's "aux" protocol-version can be bumped up. (In the case of ipc_session_message.capnp specifically, and I say this only for exposition, that code can – if it wants – do its own protocol negotiation along its own channel; but by leveraging the "aux" Protocol_negotiator version infrastructure, they do not have to. Good for perf and, in this case more importantly, good for keeping code complexity down.)

How we're different: The mechanics of protocol-version exchange are simpler for us, because we have a built-in SYN/SYN-ACK like exchange at the start (log-in-request, log-in-response) via the session master channel. So we piggy-back (piggy-front?) the protocol-negotiation info onto those 2 messages which exist anyway. You can see that now by looking at session_master_channel.capnp and noting how ProtocolNegotiation fields sit up-top in LogInReq and LogInRsp. As Protocol_version doc header discussion suggests, it is important to verify the ProtocolNegotiation fields before interpreting any other part of the incoming LogInReq and LogInRsp by server and client respectively (and in that chronological order, as guaranteed by the handshake setup).

(In contrast to this: struc::sync_io::Channel does not itself have a mandatory built-in handshake phase. Hence each side has to send a special ProtocolNegotiation message ASAP and expect one – in each pipe of up-to-2 – to come in as well. No handshake/client/server => the two exchanges are full-duplex, that is mutually independent, in nature.)

If you're keeping score: as of this writing, the most complex/full-featured setup for a session is the SHM-jemalloc session setup. Excluding any structured channels opened within the session, the following transport::Protocol_negotiator negotiations shall occur:

Unrelated to sessions, consider the most complex/full-featured setup for a user transport::struc::Channel operating over a 2-pipe transport::Channel (1 pipe for blobs, 1 pipe for Native_handles):

PEER state impl

Here our algorithm is complementary to the PEER state algorithm in Server_session_impl. Namely we expect passive-opens via an appropriate transport::struc::Channel::expect_msgs(); and we allow active-opens via open_channel(). The details of how these work is best understood just by reading that code inline.

open_channel(), similarly to Server_session_impl::open_channel(), has one interesting quirk which is: To the user it is presented as synchronous and blocking with the aim of being non-blockingly fast, as long as the other side is in PEER state. It uses transport::struc::Channel::sync_request() with a generous timeout, while knowing that if both sides in PEER state in practice the call will complete rather swiftly; the generous timeout aimed making it clear that open_channel() is failing not due to some overly tight internal timeout but more likely due to some application problem such as not calling Server_session::init_handlers() quickly enough.

Once PEER state is reached, the Session-concept error emission semantics come into play. See its doc header.

Template Parameters
S_MQ_TYPE_OR_NONESee Client_session counterpart.
S_TRANSMIT_NATIVE_HANDLESSee Client_session counterpart.
Mdt_payloadSee Client_session counterpart.
S_SHM_TYPE_OR_NONEIdentical to opposing Server_session_impl counterpart.
S_GRACEFUL_FINISH_REQUIRED_Vtrue if and only if Session_base::Graceful_finisher must be used. See its doc header for explanation when that would be the case.

Definition at line 217 of file client_session_impl.hpp.

Member Typedef Documentation

◆ Base

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Base = Session_base<S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload>

Short-hand for base type.

Definition at line 225 of file client_session_impl.hpp.

◆ Channel_obj

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Channel_obj = typename Base::Channel_obj

See Client_session_mv counterpart.

Definition at line 231 of file client_session_impl.hpp.

◆ Channels

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Channels = typename Base::Channels

See Session_mv counterpart.

Definition at line 234 of file client_session_impl.hpp.

◆ Master_channel_req_ptr

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_channel_req_ptr = boost::shared_ptr<Master_channel_req>
private

Short-hand for ref-counted pointer to Master_channel_req.

See also
Master_channel_req doc header for info on the true nature of such shared_ptr as returned by us.

Definition at line 618 of file client_session_impl.hpp.

◆ Master_structured_channel

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_structured_channel = typename Base::Master_structured_channel
protected

See Session_base.

Definition at line 390 of file client_session_impl.hpp.

◆ Master_structured_channel_observer

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_structured_channel_observer = typename Base::Master_structured_channel_observer
private

See Session_base.

Definition at line 539 of file client_session_impl.hpp.

◆ Master_structured_channel_ptr

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_structured_channel_ptr = typename Base::Master_structured_channel_ptr
private

See Session_base.

Definition at line 536 of file client_session_impl.hpp.

◆ Mdt_builder

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Mdt_builder = typename Base::Mdt_builder

See Client_session_mv counterpart.

Definition at line 243 of file client_session_impl.hpp.

◆ Mdt_builder_ptr

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Mdt_builder_ptr = typename Base::Mdt_builder_ptr

See Client_session_mv counterpart.

Definition at line 246 of file client_session_impl.hpp.

◆ Mdt_payload_obj

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Mdt_payload_obj = typename Base::Mdt_payload_obj

See Client_session_mv counterpart.

Definition at line 237 of file client_session_impl.hpp.

◆ Mdt_reader_ptr

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Mdt_reader_ptr = typename Base::Mdt_reader_ptr

See Client_session_mv counterpart.

Definition at line 240 of file client_session_impl.hpp.

◆ On_passive_open_channel_func

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::On_passive_open_channel_func = typename Base::On_passive_open_channel_func
private

See Session_base.

Definition at line 545 of file client_session_impl.hpp.

◆ Persistent_mq_handle_from_cfg

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Persistent_mq_handle_from_cfg = typename Base::Persistent_mq_handle_from_cfg
private

See Session_base.

Definition at line 542 of file client_session_impl.hpp.

◆ Session_base_obj

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Session_base_obj = Base

Short-hand for Session_base super-class.

Definition at line 228 of file client_session_impl.hpp.

◆ Structured_msg_builder_config

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Structured_msg_builder_config = typename Base::Structured_msg_builder_config

See Session_mv counterpart.

Definition at line 249 of file client_session_impl.hpp.

◆ Structured_msg_reader_config

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
using ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Structured_msg_reader_config = typename Base::Structured_msg_reader_config

See Session_mv counterpart.

Definition at line 252 of file client_session_impl.hpp.

Member Enumeration Documentation

◆ State

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
enum class ipc::session::Client_session_impl::State
strongprivate

Overall state of a Client_session_impl.

Enumerator
S_NULL 

Not a peer.

Initial state; goes to CONNECTING (via async_connect()). Only async_connect() is possible in this state (other public mutators return immediately).

S_CONNECTING 

Not a peer but async_connect() in progress to try to make it a peer.

Barring moves-from/moves-to: Entry from NULL; goes to PEER or NULL.

S_PEER 

Is or was a connected peer.

Entry from CONNECTING; does not transition to any other state (once a PEER, always a PEER). *_connect() is not possible in this state (it returns immediately); all other mutating public methods are possible.

Definition at line 548 of file client_session_impl.hpp.

Constructor & Destructor Documentation

◆ Client_session_impl() [1/3]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
template<typename On_passive_open_channel_handler , typename Task_err >
ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Client_session_impl ( flow::log::Logger *  logger_ptr,
const Client_app cli_app_ref,
const Server_app srv_app_ref,
Task_err &&  on_err_func,
On_passive_open_channel_handler &&  on_passive_open_channel_func 
)
explicit

See Client_session_mv counterpart.

Parameters
logger_ptrSee Client_session_mv counterpart.
cli_app_refSee Client_session_mv counterpart.
srv_app_refSee Client_session_mv counterpart.
on_err_funcSee Client_session_mv counterpart.
on_passive_open_channel_funcSee Client_session_mv counterpart.

Definition at line 931 of file client_session_impl.hpp.

◆ Client_session_impl() [2/3]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
template<typename Task_err >
ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Client_session_impl ( flow::log::Logger *  logger_ptr,
const Client_app cli_app_ref,
const Server_app srv_app_ref,
Task_err &&  on_err_func 
)
explicit

See Client_session_mv counterpart.

Parameters
logger_ptrSee Client_session_mv counterpart.
cli_app_refSee Client_session_mv counterpart.
srv_app_refSee Client_session_mv counterpart.
on_err_funcSee Client_session_mv counterpart.

Definition at line 944 of file client_session_impl.hpp.

◆ ~Client_session_impl()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::~Client_session_impl

See Client_session_mv counterpart.

Definition at line 1042 of file client_session_impl.hpp.

◆ Client_session_impl() [3/3]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Client_session_impl ( flow::log::Logger *  logger_ptr,
const Client_app cli_app_ref,
const Server_app srv_app_ref,
flow::async::Task_asio_err &&  on_err_func,
On_passive_open_channel_func &&  on_passive_open_channel_func_or_empty_arg,
std::nullptr_t  tag 
)
explicitprivate

Delegated-to ctor that implements both non-default public ctors.

Parameters
logger_ptrSee public ctors.
cli_app_refSee public ctors.
srv_app_refSee public ctors.
on_err_funcSee public ctors. This is the concretely-typed version of that arg.
on_passive_open_channel_func_or_empty_argSee public ctors. This is the concretely-typed version of that arg; .empty() if the version without this arg was used.
tagCtor-selecting tag.

Definition at line 901 of file client_session_impl.hpp.

References ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_async_worker.

Member Function Documentation

◆ async_connect()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
template<typename Task_err >
bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::async_connect ( const Mdt_builder_ptr mdt,
Channels init_channels_by_cli_req_pre_sized,
Mdt_reader_ptr mdt_from_srv_or_null,
Channels init_channels_by_srv_req,
Task_err &&  on_done_func 
)
protected

Core implementation of sync_connect().

See "CONNECTING state and asynchronicity" in class doc header for key background.

Returns
See sync_conect().
Parameters
mdtSee sync_conect().
init_channels_by_cli_req_pre_sizedSee sync_conect().
mdt_from_srv_or_nullSee sync_conect().
init_channels_by_srv_reqSee sync_conect().
on_done_funcWhat to invoke in thread W on completion of the async-connect. As of this writing this is supplied by sync_connect_impl() internal code.

Definition at line 1127 of file client_session_impl.hpp.

References ipc::util::Shared_name::ct(), ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_channel_req::m_req_msg, ipc::util::op_with_possible_bipc_exception(), ipc::util::OPEN_OR_CREATE, ipc::util::Process_credentials::own_group_id(), ipc::util::Process_credentials::own_process_id(), ipc::util::Process_credentials::own_user_id(), ipc::transport::Socket_stream_channel< SIO >::remote_peer_process_credentials(), ipc::session::error::S_CLIENT_NAMESPACE_STORE_BAD_FORMAT, ipc::session::error::S_MUTEX_BIPC_MISC_LIBRARY_ERROR, ipc::transport::struc::Channel_base::S_SERIALIZE_VIA_HEAP, ipc::util::shared_resource_permissions(), and ipc::transport::sync_io::Native_socket_stream::sync_connect().

Here is the call graph for this function:

◆ async_worker()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
flow::async::Single_thread_task_loop * ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::async_worker
protected

Utility for sub-classes: provides ability to schedule or post tasks onto thread W.

Returns
See above.

Definition at line 2583 of file client_session_impl.hpp.

◆ cancel_peer_state_to_connecting()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
template<typename Task_err >
Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_structured_channel * ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::cancel_peer_state_to_connecting ( Task_err &&  on_done_func)
protected

Utility for sub-classes: executed from async_connect()'s on_done_func(Error_code()) (i.e., directly from handler invoked on success) – hence from thread W – this instead goes back to CONNECTING state, essentially indicating "yes, the vanilla async_connect() succeeded, but the true user-called async_connect() that piggybacked on the vanilla one will now do some more async stuff before reaching PEER state (or NULL on error).

"

As on_done_func was already invoked (and thus forgotten), the caller must supply a new one to execute once either PEER or NULL state is reached again. Since *this has completed its vanilla async_connect() work already, the responsibility for reaching one of those 2 states is now on the caller. Therefore whatever async processing follows our invocation is required to call complete_async_connect_after_canceling_peer_state(). That said, if a master-session-channel error occurs before that has a chance to be called, then:

The session master channel is returned, so that the sub-class can take over operation as needed until either complete_async_connect_after_canceling_peer_state() or that channel becoming hosed (either way on_done_func() will be invoked). This avoids providing unrestricted protected access to it all times. See also async_worker().

Template Parameters
Task_errSee async_connect().
Parameters
on_done_funcSee async_connect().
Returns
See above.

Definition at line 2530 of file client_session_impl.hpp.

◆ cancel_peer_state_to_null()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::cancel_peer_state_to_null
protected

Utility for sub-classes: executed from async_connect()'s on_done_func(Error_code()) (i.e., directly from handler invoked on success) – hence from thread W – this instead goes back to NULL state, essentially indicating "never mind -- this successful async_connect() actually failed.".

This... um... highly specific utility is intended for overriding async_connect() impl that performs synchronous post-processing in its own on_done_func() wrapper from sub-class's async_connect() that calls this class's async_connect().

Definition at line 2511 of file client_session_impl.hpp.

◆ complete_async_connect_after_canceling_peer_state()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::complete_async_connect_after_canceling_peer_state ( const Error_code err_code_or_success)
protected

Utility for sub-classes: to be invoked, only from thread W and asynchronously at that, after cancel_peer_state_to_connecting(), this indicates the completion of the sub-class's additional async-connect steps, setting state to either NULL or PEER.

Invoke only in CONNECTING state; else undefined behavior (assertion may trip).

The handler given to cancel_peer_state_to_connecting() will execute.

Take care to check Session_base::hosed() as needed before calling this; if hosed then do not call.

Parameters
err_code_or_successState will proceed to PEER if falsy else to NULL; in the latter case the given code shall be passed to handler as the reason for failure to ultimately async-connect.

Definition at line 2549 of file client_session_impl.hpp.

◆ create_channel_obj()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::create_channel_obj ( const Shared_name mq_name_c2s_or_none,
const Shared_name mq_name_s2c_or_none,
util::Native_handle &&  local_hndl_or_null,
Channel_obj opened_channel_ptr,
bool  active_else_passive,
Error_code err_code_ptr 
)
private

In thread W, based on resources acquired on server side, creates local Channel_obj to emit to the user thus completing a channel-open.

If active-open on our part, we do this upon receiving server response to our open-channel-to-server request. If passive-open, we do this upon receiving server's open-channel-to-client request, before replying with our OK. Either way the in-message from server contained the handle(s) to the resource(s) it acquired for this channel; these are args to this method.

Parameters
mq_name_c2s_or_noneIf S_MQS_ENABLED this is the (non-empty) name of the client->server unidirectional MQ for the channel. Else empty/ignored.
mq_name_s2c_or_noneLike the preceding but opposite-direction (server->client).
local_hndl_or_nullIf S_SOCKET_STREAM_ENABLED this is our pre-connected Native_handle; the server did connect_pair() and sent us 1/2 of the pair. Else null/ignored.
opened_channel_ptrTarget Channel_obj we shall try to move-to PEER state. It'll be left unmodified if error is emitted.
active_else_passivetrue if this is from open_channel(); false if from on_master_channel_open_channel_req().
err_code_ptrNon-null pointer to Error_code; deref shall be untouched on success (and must be falsy at entry); else deref shall be set to reason for failure. As of this writing the only possible path to failure is if S_MQS_ENABLED, and we're unable to open an MQ handle or transport::Blob_stream_mq_sender or transport::Blob_stream_mq_receiver to 1 of the MQs. This is highly unlikely, since the server was able to do it fine, but we leave it to caller to deal with the implications.
Todo:
As of this writing the eventuality where Client_session_impl::create_channel_obj() yields an error is treated as assertion-trip-worthy by its caller; hence consider just tripping assertion inside instead and no out-arg. For now it is left this way in case we'd want the (internal) caller to do something more graceful in the future, and in the meantime it's a decently reusable chunk of code to use in that alleged contingency.

Definition at line 2397 of file client_session_impl.hpp.

References ipc::util::Shared_name::empty(), and ipc::util::OPEN_ONLY.

Here is the call graph for this function:

◆ dtor_async_worker_stop()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::dtor_async_worker_stop
protected

Synchronously stops async_worker() loop, the post-condition being that thread W has been joined; no tasks post()ed onto it by *this or subclass shall execute after this returns.

  • If *this is not being subclassed, or if it never posts onto async_worker(): Our own dtor shall call this first-thing; no need for subclass to worry.
  • If *this is being subclassed, and it does post onto async_worker(): The terminal subclass's dtor must call this ~first-thing (our own dtor, once it is soon called, shall know not to re-execute the same thing).

Call at most once; otherwise undefined behavior (assertion may trip).

This exists to avoid a race, however unlikely, between a subclass's asynchronous accept-log-in code posted onto thread W, and that same class's dtor being invoked by the user in thread U. There is a short time period, when thread W (m_async_worker) is active – *this is still intact – but the subclass's members are being destroyed by its dtor. In that case dtor_async_worker_stop() would be called by the subclass dtor to put an end to async shenanigans in thread W, so it can continue destroying self in peace. When there is no subclass, our own dtor does so.

Definition at line 955 of file client_session_impl.hpp.

References ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::Graceful_finisher::on_dtor_start().

Here is the call graph for this function:

◆ invoke_conn_on_done_func()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::invoke_conn_on_done_func ( const Error_code err_code)
private

Little helper that invokes m_conn_on_done_func_or_empty, passing it err_code, and – per that member's internal use semantics – empties m_conn_on_done_func_or_empty.

A key property is that the emptying occurs just before invoking it (obviously first saving it). This allows the handler to itself un-empty m_conn_on_done_func_or_empty, as required by cancel_peer_state_to_connecting() at least. (That, in turn, may be used by sub-classes that implement async_connect() by piggybacking onto our vanilla one.)

m_conn_on_done_func_or_empty must not be empty; or behavior is undefined.

Parameters
err_codeArg to m_conn_on_done_func_or_empty().

Definition at line 1931 of file client_session_impl.hpp.

◆ master_channel_const()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
const Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Master_structured_channel & ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::master_channel_const
protected

Utility for sub-classes: provides ability to immutably query the session master channel, particularly after our async_accept_log_in() succeeds, but before the sub-classed wrapper of its on-done handler succeeds.

For example one can harmlessly query transport::struc::Channel::session_token().

protected but const access does not much bother me (ygoldfel) stylistically.

Returns
See above.

Definition at line 2589 of file client_session_impl.hpp.

◆ mdt_builder()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Mdt_builder_ptr ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::mdt_builder

See Client_session_mv counterpart.

Reminder: it can be used not only in PEER state (for open_channel()) but also NULL state (for async_connect()).

Returns
See Client_session_mv counterpart.

Definition at line 2052 of file client_session_impl.hpp.

References ipc::transport::sync_io::Native_socket_stream::S_MAX_META_BLOB_LENGTH.

◆ on_master_channel_error()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::on_master_channel_error ( const Master_structured_channel_observer master_channel_observer,
const Error_code err_code 
)
private

In thread W, handler for m_master_channel indicating incoming-direction channel-hosing error.

It is possible that m_master_channel has been .reset() in the meantime, by seeing log-in failure in on_master_channel_log_in_rsp(), and no longer exists. This is tested via the observer arg.

Parameters
master_channel_observerweak_ptr observer of m_master_channel at the time it was constructed. master_channel_observer.lock() is either null (we've destroyed m_master_channel due to another error condition) or equals m_master_channel.
err_codeThe non-success Error_code from struc::Channel.

Definition at line 1946 of file client_session_impl.hpp.

◆ on_master_channel_init_open_channel()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::on_master_channel_init_open_channel ( typename Master_structured_channel::Msg_in_ptr &&  open_channel_msg,
size_t  n_init_channels,
const boost::shared_ptr< Channels > &  init_channels_ptr,
Channels init_channels_by_cli_req_pre_sized,
Mdt_reader_ptr mdt_from_srv_or_null,
Channels init_channels_by_srv_req,
Mdt_reader_ptr &&  mdt_from_srv 
)
private

In thread W, handler for m_master_channel receiving a init-channel-open message.

This is similar to on_master_channel_open_channel_req(), except:

  • It occurs in CONNECTING state, after log-in, if server is required to open init-channels on our behalf or its behalf or both.
  • It uses the same in-message, but it is not treated as a request; rather just a notification of the info regarding 1 of the requested channels...
  • ...except for the last one, which is treated as a request:
    • we set up the regular passive-open-channel handler (on_master_channel_open_channel_req());
    • we move to PEER state (emit to m_conn_on_done_func_or_empty);
    • we respond with an OK; so server knows it too can move to PEER state.
      • If that send() fails we move to NULL instead of PEER state (still invoke on-connect-done handler).

So this method is invoked n_init_channels times (assuming all goes well); and each time *init_channels_ptr grows by 1 element; once it is n_init_channels long – that's the last one, and we do those last 3 sub-bullet points.

Parameters
open_channel_msgThe in-message from struc::Channel.
n_init_channels1+, the count of clients local async_connect() requested plus same from opposing async_accept().
init_channels_ptrIntermediate PEER-state Channel_obj results list; first empty, next time with 1 elements, then 2, .... If .size() == n_init_channels, we shall move to PEER state.
init_channels_by_cli_req_pre_sizedSee advanced async_connect() features.
mdt_from_srv_or_nullSee advanced async_connect() features.
init_channels_by_srv_reqSee advanced async_connect() features.
mdt_from_srvValue to which to set *mdt_from_srv_or_null, if the latter is not null, and this is the last invocation of this method.

Definition at line 1770 of file client_session_impl.hpp.

References ipc::util::Shared_name::ct().

Here is the call graph for this function:

◆ on_master_channel_log_in_rsp()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::on_master_channel_log_in_rsp ( typename Master_structured_channel::Msg_in_ptr &&  log_in_rsp,
Channels init_channels_by_cli_req_pre_sized,
Mdt_reader_ptr mdt_from_srv_or_null,
Channels init_channels_by_srv_req 
)
private

In thread W, handler for the successful receipt of log-in response (upon send()ing the log-in request), as invoked in CONNECTING state only if the low-level transport::Native_socket_stream::async_connect() succeeded.

Post-condition:

  • If no init-channels requested by client (async_connect() advanced-use) nor by server (as indicated in log_in_rsp itself): m_state changed from CONNECTING to either NULL or PEER, depending on whether the log-in response log_in_rsp indicates server side OKed the log-in. Per the invariant in m_master_channel doc header: m_master_channel is null (state became NULL) or non-null (state became PEER). In the former case async_connect() can be attempted again.
  • Otherwise (if 1+ such channels, in total, requested): m_state unchanged from CONNECTING; on_master_channel_init_open_channel() shall be executed once per requested (by either side) init-channel generated by opposing server.
Parameters
log_in_rspThe response in-message from struc::Channel.
init_channels_by_cli_req_pre_sizedSee advanced async_connect() features.
mdt_from_srv_or_nullSee advanced async_connect() features.
init_channels_by_srv_reqSee advanced async_connect() features.

Definition at line 1527 of file client_session_impl.hpp.

References ipc::util::Shared_name::ct(), ipc::session::error::S_CLIENT_MASTER_LOG_IN_RESPONSE_BAD, ipc::session::error::S_INVALID_ARGUMENT, and ipc::util::Shared_name::S_SENTINEL.

Here is the call graph for this function:

◆ on_master_channel_open_channel_req()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
void ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::on_master_channel_open_channel_req ( typename Master_structured_channel::Msg_in_ptr &&  open_channel_req)
private

In thread W, handler for m_master_channel receiving a passive-open (a/k/a open-channel-to-client) request.

If there is no issue with this request, and we're able to sync-send the open-channel response to that effect, this shall fire on-passive-open handler, giving it a new Channel_obj in PEER state + metadata. If there is a problem, then it's not a session-hosing situation; local user is none-the-wiser; except that if the send() reveals a new error, then it is a session-hosing situation, and local user is informed via on-error handler.

Parameters
open_channel_reqThe request in-message from struc::Channel.

Definition at line 2278 of file client_session_impl.hpp.

References ipc::util::Shared_name::ct().

Here is the call graph for this function:

◆ open_channel() [1/2]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::open_channel ( Channel_obj target_channel,
const Mdt_builder_ptr mdt,
Error_code err_code 
)

See Client_session_mv counterpart.

Parameters
target_channelSee Client_session_mv counterpart.
mdtSee Client_session_mv counterpart.
err_codeSee Client_session_mv counterpart.
Returns
See Client_session_mv counterpart.

Definition at line 2105 of file client_session_impl.hpp.

References ipc::util::Shared_name::ct(), ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::open_channel(), ipc::session::error::S_SESSION_OPEN_CHANNEL_ACTIVE_TIMEOUT, ipc::session::error::S_SESSION_OPEN_CHANNEL_REMOTE_PEER_REJECTED_PASSIVE_OPEN, ipc::session::error::S_SESSION_OPEN_CHANNEL_SERVER_CANNOT_PROCEED_RESOURCE_UNAVAILABLE, and ipc::transport::error::S_TIMEOUT.

Referenced by ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::open_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_channel() [2/2]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::open_channel ( Channel_obj target_channel,
Error_code err_code 
)

See Client_session_mv counterpart.

Parameters
target_channelSee Client_session_mv counterpart.
err_codeSee Client_session_mv counterpart.
Returns
See Client_session_mv counterpart.

Definition at line 2271 of file client_session_impl.hpp.

◆ session_token()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
const Session_token & ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::session_token

See Client_session_mv counterpart.

Returns
See Client_session_mv counterpart.

Definition at line 2014 of file client_session_impl.hpp.

References ipc::transport::struc::NULL_SESSION_TOKEN.

◆ sync_connect() [1/2]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::sync_connect ( const Mdt_builder_ptr mdt,
Channels init_channels_by_cli_req_pre_sized,
Mdt_reader_ptr mdt_from_srv_or_null,
Channels init_channels_by_srv_req,
Error_code err_code 
)

See Client_session_mv counterpart.

Parameters
mdtSee Client_session_mv counterpart.
init_channels_by_cli_req_pre_sizedSee Client_session_mv counterpart.
mdt_from_srv_or_nullSee Client_session_mv counterpart.
init_channels_by_srv_reqSee Client_session_mv counterpart.
err_codeSee Client_session_mv counterpart.
Returns
See Client_session_mv counterpart.

Definition at line 1068 of file client_session_impl.hpp.

◆ sync_connect() [2/2]

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::sync_connect ( Error_code err_code)

See Client_session_mv counterpart.

Parameters
err_codeSee Client_session_mv counterpart.
Returns
See Client_session_mv counterpart.

Definition at line 1062 of file client_session_impl.hpp.

◆ sync_connect_impl()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::sync_connect_impl ( Error_code err_code,
Function< bool(flow::async::Task_asio_err &&)> *  async_connect_impl_func 
)
protected

Utility for *this and sub-classes: Implements sync_connect() given a functor that invokes the calling class's (including Client_session_impl) async_connect() with the args passed to the calling sync_connect().

This allows sub-classes to reuse our straightforward promise-based implementation of sync_connect() in terms of async_connect(). Otherwise they'd need to copy/paste that stuff or something. E.g., see shm::classic::Client_session_impl and/or shm::arena_lend::jemalloc::Client_session_impl. If sub-classes were not an issue, sync_connect_impl() would not be needed; we'd just call our async_connect() directly.

Parameters
err_codeSee sync_connect().
async_connect_impl_funcNon-null pointer to a function that (1) calls async_connect()-like method, forwarding to it the args to the calling sync_connect()-like method, except (2) the last arg is to be a forward of the on_done_func-signature-matching arg to async_connect_impl_func.
Returns
See sync_connect().

Definition at line 1092 of file client_session_impl.hpp.

References ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::sync_connect_impl().

Referenced by ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::sync_connect_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ operator<<()

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
std::ostream & operator<< ( std::ostream &  os,
const Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V > &  val 
)
related

Prints string representation of the given Client_session_impl to the given ostream.

Parameters
osStream to which to write.
valObject to serialize.
Returns
os.

Definition at line 2595 of file client_session_impl.hpp.

Member Data Documentation

◆ m_async_worker

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
flow::async::Single_thread_task_loop ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_async_worker
mutableprivate

Worker thread (a/k/a thread W).

Ordering: Should be declared before m_master_channel: It should destruct before the Task_engine onto which its queued-up handlers might post() items destructs prematurely.

Why mutable?

Well, session_token() is const to the user but must .post() which is non-const. This fits the spirit of mutable. I (ygoldfel) think.

Definition at line 853 of file client_session_impl.hpp.

Referenced by ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::Client_session_impl().

◆ m_conn_on_done_func_or_empty

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
flow::async::Task_asio_err ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_conn_on_done_func_or_empty
private

The on_done_func argument to async_connect(); .empty() except while in State::S_CONNECTING state.

In other words it is assigned at entry to CONNECTING and .clear()ed at subsequent entry to State::S_PEER or State::S_NULL (depending on success/failure of the connect op).

Definition at line 832 of file client_session_impl.hpp.

◆ m_graceful_finisher

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
std::optional<typename Base::Graceful_finisher> ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_graceful_finisher
private

Null until PEER state is reached, and NULL unless compile-time S_GRACEFUL_FINISH_REQUIRED is true, this is used to block at the start of dtor to synchronize with the opposing Session dtor for safety.

See also
Session_base::Graceful_finisher doc header for all the background ever.

Definition at line 884 of file client_session_impl.hpp.

◆ m_last_actively_opened_channel_id

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
unsigned int ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_last_actively_opened_channel_id
private

Logging-only *this-unique ID used in nicknaming the last actively-opened (via open_channel()) channel.

It is incremented each time. Accessed in thread W only (not protected by mutex).

Definition at line 838 of file client_session_impl.hpp.

◆ m_last_passively_opened_channel_id

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
unsigned int ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_last_passively_opened_channel_id
private

A-la m_last_actively_opened_channel_id but for passively-opened channels (on_master_channel_open_channel_req()).

Definition at line 841 of file client_session_impl.hpp.

◆ m_master_channel

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
Master_structured_channel_ptr ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_master_channel
private

The session master channel.

Accessed in thread W only (not protected by mutex).

  • When m_state is NULL, this is null.
  • When m_state is CONNECTING:
  • When m_state is PEER: It remains non-null and immutable until dtor.

Rationale for above invariant

Generally it is a pain in the butt to deal with a struc::Channel being destroyed, as it has non-boost.asio-style handler semantics wherein one must be ready for a handler for channel C to fire in our thread W, even after we destroy C in a preceding thread W task. So, here as in other classes, we aim to keep it non-null and immutable once it's been constructed. (E.g., that's the case in Server_session_impl.) However, since we allow async_connect() to be retried on failure, we do need to get back to a coherent state when m_state is NULL. So in that case only, it is renullified.

Because it is renullified, there's the "observer" thing used in on_master_channel_error() to deal with it. It's a fairly small section of code though.

Definition at line 876 of file client_session_impl.hpp.

◆ m_protocol_negotiator

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
transport::Protocol_negotiator ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_protocol_negotiator
private

Handles the protocol negotiation at the start of the pipe, as pertains to algorithms perpetuated by the vanilla ipc::session Session hierarchy.

Reset essentially at start of each async_connect().

Outgoing-direction state is touched when assembling LogInReq to send to opposing Server_session. Incoming-direction state is touched/verified at the start of interpreting LogInRsp receiver from there.

See also
transport::Protocol_negotiator doc header for key background on the topic.

Definition at line 815 of file client_session_impl.hpp.

◆ m_protocol_negotiator_aux

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
transport::Protocol_negotiator ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_protocol_negotiator_aux
private

Analogous to m_protocol_negotiator but pertains to algorithms perpetuated by (if relevant) non-vanilla ipc::session Session hierarchy implemented on top of our vanilla ipc::session Session hierarchy.

For example, ipc::session::shm hierarchies can use this to version whatever additional protocol is required to establish SHM things.

See also
transport::Protocol_negotiator doc header for key background on the topic.

Definition at line 825 of file client_session_impl.hpp.

◆ m_state

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
State ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::m_state
private

The current state of *this.

Accessed in thread W only (not protected by mutex).

Note
I (ygoldfel) considered just relying on Native_socket_stream itself to just return false, and then we'd forward to its state detection. It would've been nice, but ultimately it just seemed a bit too sloppy and hard to reason about... I ~duplicated this here instead.

Definition at line 804 of file client_session_impl.hpp.

◆ S_GRACEFUL_FINISH_REQUIRED

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
constexpr bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::S_GRACEFUL_FINISH_REQUIRED = S_GRACEFUL_FINISH_REQUIRED_V
staticconstexpr

Short-hand for template parameter knob S_GRACEFUL_FINISH_REQUIRED_V: see class template doc header.

Definition at line 272 of file client_session_impl.hpp.

◆ S_MQS_ENABLED

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
constexpr bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::S_MQS_ENABLED = Base::S_MQS_ENABLED
staticconstexpr

See Client_session_mv counterpart.

Definition at line 266 of file client_session_impl.hpp.

◆ S_SHM_ENABLED

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
constexpr bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::S_SHM_ENABLED = S_SHM_TYPE != schema::ShmType::NONE
staticconstexpr

See Session_mv counterpart.

Definition at line 263 of file client_session_impl.hpp.

◆ S_SHM_TYPE

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
constexpr schema::ShmType ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::S_SHM_TYPE = S_SHM_TYPE_OR_NONE
staticconstexpr

See Session_mv counterpart.

Definition at line 260 of file client_session_impl.hpp.

◆ S_SOCKET_STREAM_ENABLED

template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, bool S_GRACEFUL_FINISH_REQUIRED_V>
constexpr bool ipc::session::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_GRACEFUL_FINISH_REQUIRED_V >::S_SOCKET_STREAM_ENABLED = Base::S_SOCKET_STREAM_ENABLED
staticconstexpr

See Client_session_mv counterpart.

Definition at line 269 of file client_session_impl.hpp.


The documentation for this class was generated from the following files: