Flow-IPC 1.0.2
Flow-IPC project: Full implementation reference.
|
Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session concept – in such a way as to make it possible for a given pair of processes A and B to set up ipc::transport structured- or unstructured-message channels for general IPC, as well as to share data in SHared Memory (SHM). More...
Namespaces | |
namespace | error |
Namespace containing the ipc::session module's extension of boost.system error conventions, so that that API can return codes/messages from within its own new set of error codes/messages. | |
namespace | shm |
ipc::session sub-namespace that groups together facilities for SHM-backed sessions, particularly augmenting Client_session, Server_session, and Session_server classes by providing SHM-backed zero-copy functionality. | |
namespace | sync_io |
sync_io -pattern counterparts to async-I/O-pattern object types in parent namespace ipc::session. | |
Classes | |
struct | App |
A description of an application in this ipc::session inter-process communication universe. More... | |
struct | Client_app |
An App that is used as a client in at least one client-server IPC split. More... | |
class | Client_session_impl |
Internal, non-movable pImpl-lite implementation of Client_session_mv class template. More... | |
class | Client_session_mv |
Implements Session concept on the Client_app end: a Session_mv that first achieves PEER state by connecting to an opposing Session_server_mv via Client_session_mv::sync_connect(). More... | |
struct | Server_app |
An App that is used as a server in at least one client-server IPC split. More... | |
class | Server_session_dtl |
This is the data-less sub-class of Server_session or any more-advanced (e.g., SHM-capable) variant thereof that exposes protected APIs hidden from public user by providing public access to them; this is used internally by Session_server. More... | |
class | Server_session_impl |
Internal, non-movable pImpl-lite implementation of Server_session_mv class template. More... | |
class | Server_session_mv |
Implements Session concept on the Server_app end: a Session that is emitted in almost-PEER state by local Session_server accepting a connection by an opposing Client_session_mv::sync_connect() . More... | |
class | Session |
A documentation-only concept defining the local side of an IPC conversation (session) with another entity (typically a separate process), also represented by a Session-implementing object, through which one can easily open IPC channels (ipc::transport::Channel), among other IPC features. More... | |
class | Session_base |
Internal type containing data and types common to internal types Server_session_impl and Client_session_impl which are the respective true cores of Server_session and Client_session respectively. More... | |
class | Session_mv |
Implements the Session concept when it is in PEER state. More... | |
class | Session_server |
To be instantiated typically once in a given process, an object of this type asynchronously listens for Client_app processes each of which wishes to establish a session with this server process; emits resulting Server_session objects locally. More... | |
class | Session_server_impl |
Internal class template comprising API/logic common to every Session_server variant, meant to be private ly sub-classed and largely forwarded. More... | |
Typedefs | |
using | Shared_name = util::Shared_name |
Convenience alias for the commonly used type util::Shared_name. More... | |
using | Session_token = transport::struc::Session_token |
Convenience alias for the commonly used type transport::struc::Session_token. More... | |
template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload = ::capnp::Void> | |
using | Server_session = Server_session_mv< Server_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload > > |
A vanilla Server_session with no optional capabilities. More... | |
template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload = ::capnp::Void> | |
using | Client_session = Client_session_mv< Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload > > |
A vanilla Client_session with no optional capabilities. More... | |
Functions | |
void | ensure_resource_owner_is_app (flow::log::Logger *logger_ptr, const fs::path &path, const App &app, Error_code *err_code=0) |
Utility, used internally but exposed in public API in case it is of general use, that checks that the owner of the given resource (at the supplied file system path) is as specified in the given App (App::m_user_id et al). More... | |
void | ensure_resource_owner_is_app (flow::log::Logger *logger_ptr, util::Native_handle handle, const App &app, Error_code *err_code=0) |
Identical to the other ensure_resource_owner_is_app() overload but operates on a pre-opened Native_handle (a/k/a handle, socket, file descriptor) to the resource in question. More... | |
std::ostream & | operator<< (std::ostream &os, const App &val) |
Prints string representation of the given App to the given ostream . More... | |
std::ostream & | operator<< (std::ostream &os, const Client_app &val) |
Prints string representation of the given Client_appp to the given ostream . More... | |
std::ostream & | operator<< (std::ostream &os, const Server_app &val) |
Prints string representation of the given Server_app to the given ostream . More... | |
template<typename Client_session_impl_t > | |
std::ostream & | operator<< (std::ostream &os, const Client_session_mv< Client_session_impl_t > &val) |
Prints string representation of the given Client_session_mv to the given ostream . More... | |
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... | |
template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload , schema::ShmType S_SHM_TYPE_OR_NONE, size_t S_SHM_MAX_HNDL_SZ, bool S_GRACEFUL_FINISH_REQUIRED_V> | |
std::ostream & | operator<< (std::ostream &os, const Server_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_SHM_MAX_HNDL_SZ, S_GRACEFUL_FINISH_REQUIRED_V > &val) |
Prints string representation of the given Server_session_impl to the given ostream . More... | |
template<typename Session_server_t , typename Server_session_t > | |
std::ostream & | operator<< (std::ostream &os, const Session_server_impl< Session_server_t, Server_session_t > &val) |
Prints string representation of the given Session_server_impl to the given ostream . More... | |
Shared_name | build_conventional_shared_name (const Shared_name &resource_type, const Shared_name &srv_app_name, const Shared_name &srv_namespace, const Shared_name &cli_app_name, const Shared_name &cli_namespace_or_sentinel=Shared_name::S_SENTINEL) |
Builds an absolute name according to the path convention explained in Shared_name class doc header; this overload applies to non-global-scope resources within the ipc::session paradigm. More... | |
Shared_name | build_conventional_shared_name (const Shared_name &resource_type, const Shared_name &srv_app_name, const Shared_name &srv_namespace_or_sentinel=Shared_name::S_SENTINEL) |
Builds an absolute name according to the path convention explained in Shared_name class doc header; this overload applies to global-scope resources within the ipc::session paradigm. More... | |
Shared_name | build_conventional_shared_name_prefix (const Shared_name &resource_type, const Shared_name &srv_app_name) |
Return the prefix common to all calls to either build_conventional_shared_name() overload with the args resource_type and srv_app_name . More... | |
bool | decompose_conventional_shared_name (const Shared_name &name, Shared_name *resource_type, Shared_name *srv_app_name, Shared_name *srv_namespace, Shared_name *cli_app_name, Shared_name *cli_namespace_or_sentinel, Shared_name *the_rest) |
Decomposes a Shared_name built as-if by build_conventional_shared_name() overload 1 (non-global-scope); setting the various component values as out-args; or returning false if the name does not follow the conventions of that build_conventional_shared_name() overload. More... | |
bool | decompose_conventional_shared_name (const Shared_name &name, Shared_name *resource_type, Shared_name *srv_app_name, Shared_name *srv_namespace_or_sentinel, Shared_name *the_rest) |
Decomposes a Shared_name built as-if by build_conventional_shared_name() overload 2 (global-scope); setting the various component values as out-args; or returning false if the name does not follow the conventions of that build_conventional_shared_name() overload. More... | |
template<typename Server_session_impl_t > | |
std::ostream & | operator<< (std::ostream &os, const Server_session_mv< Server_session_impl_t > &val) |
Prints string representation of the given Server_session_mv to the given ostream . More... | |
template<typename Session_impl_t > | |
std::ostream & | operator<< (std::ostream &os, const Session_mv< Session_impl_t > &val) |
Prints string representation of the given Session_mv to the given ostream . More... | |
template<schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload > | |
std::ostream & | operator<< (std::ostream &os, const Session_server< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload > &val) |
Prints string representation of the given Session_server to the given ostream . More... | |
Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session concept – in such a way as to make it possible for a given pair of processes A and B to set up ipc::transport structured- or unstructured-message channels for general IPC, as well as to share data in SHared Memory (SHM).
See namespace ipc doc header for an overview of Flow-IPC modules including how ipc::session relates to the others. Then return here. A synopsis follows:
It is possible to use the structured layer of ipc::transport, namely the big daddy transport::struc::Channel, without any help from ipc::session. (It's also possible to establish unstructured transport::Channel and the various lower-level IPC pipes it might comprise.) And, indeed, once a given struc::Channel
(or Channel
) is "up," one can and should simply use it to send/receive stuff. The problem that ipc::session solves is in establishing the infrastructure that makes it simple to (1) open new struc::Channel
s or Channel
s or SHM areas; and (2) properly deal with process lifecycle events such as the starting and ending (gracefully or otherwise) of the local and partner process.
Regarding (1), in particular (just to give a taste of what one means):
While ipc::transport lets one do whatever one wants, with great flexibility, ipc::session establishes conventions for all these things – typically hiding/encapsulating them away.
Regarding (2) (again, just giving a taste):
Again – ipc::session establishes conventions for these lifecycle matters and provides key utilities such as kernel-persistent resource cleanup.
An application is, at least roughly speaking, 1-1 with a distinct executable presumably interested in communicating with another such executable. A process is a/k/a instance of an application that has begun execution at some point. In the IPC universe that uses ipc, on a given machine, there is some number of distinct applications. If two processes A and B want to engage in IPC, then their apps A and B comprise a meta-application split, in that (in a sense) they are one meta-application that have been split into two.
A process that is actively operating, at least in the IPC sense, is called an active process. A zombie process in particular is not active, nor is one that has not yet initialized IPC or has shut it down, typically during graceful (or otherwise) termination.
In the ipc::session model, any two processes A-B must establish a session before engaging in IPC. This session comprises all shared resources pertaining to those two processes engaging in IPC. (Spoiler alert: at a high level these resources comprise, at least, channels of communication – see transport::Channel – between them; and may also optionally comprise SHared Memory (SHM).) The session ends when either A terminates or B terminates (gracefully or otherwise), and no earlier. The session begins at roughly the earliest time when both A and B are active simultaneously. (It is possible either process may run before IPC and after IPC, but for purposes of our discussion we'll ignore such phases are irrelevant for simplicity of exposition.) An important set of shared resources is therefore per-session shared resources. (However, as we're about to explain, it is not the only type.)
In the ipc::session model, in a given A-B split, one must be chosen as the client, the other as the server; let's by convention here assume they're always listed in server-client order. The decision must be made which one is which, at compile time. The decision as to which is which is an important one, when using ipc::session and IPC in that model. While a complete discussion of making that decision is outside the scope here, the main points are that in the A-B split (A the server, B the client):
More specifically/practically:
Suppose A is a memory cache, while B is a cache reader of objects. A starts; B1 and B2 start; so sessions A-B1 and A-B2 now exist. Now each of B1, B2 might establish channel(s) and then use it/them to issue messages and receive messages back. Now A<->B1 channel(s) and A<->B2 channel(s) are established. No B1<->B2 channel(s) can be established. (Note: transport::Channel and other ipc::transport IPC techniques are – in and of themselves – session-unaware. So B1 could speak to B2. They just cannot use ipc::session to do so. ipc::session facilitates establishing channels and SHM in an organized fashion, and that organization currently does not support channels between instances of the same client application. ipc::session is not the only option for doing so.)
Suppose, in this illustration, that A is responsible both for acquiring network objects (on behalf of B*) and memory-caching them. Then B1 might say, via an A-B1 channel, "give me object X." A does not have it in cache yet, so it loads it from network, and saves it in the per-app-B SHM area and replies (via same A-B1 channel) "here is object X: use this SHM handle X'." B1 then accesses X' directly in SHM. Say B2 also says "give me object X." It is cached, so A sends it X' again. Now, say A-B1 session ends, because B1 stops. All A-B1 channels go away – they are per-session resources – and any per-session-A-B1 SHM area (which we haven't mentioned in this illustration) also goes away similarly.
A-B2 continues. B2 could request X again, and it would work. Say B3 now starts and requests X. Again, the per-app-B SHM area persists; A would send X' to B3 as well.
Now suppose A stops, due to a restart. This ends A-B2 and A-B3 sessions; and the per-app-B SHM area goes away too. Thus the server process's lifetime encompasses all shared resources in the A-B split. Processes B2 and B3 continue, but they must await for a new active A process (instance) to appear, so that they can establish new A-B2 and A-B3 sessions. In the meantime, it is IPC no-man's-land: there is no active per-app-B shared resources (SHM in our illustration) and certainly no per-session-A-B* shared resources either. Once A-B2 and A-B3 (new) sessions are established, shared resources can begin to be acquired again.
This illustrates that:
The above discussion concerned a particular A-B split, in which by definition A is the server (only 1 active instance at a time), while B is the client (0+ active instances at a time).
Take A, in split A-B. Suppose there is app Cp also. An A-C split is also possible (as is A-D, A-E, etc.). Everything written so far applies in natural fashion. Do note, however, that the per-app scope applies to a given (client) application, not all client applications. So the per-app-B SHM area is independent of the per-app-C SHM area (both maintained by A). Once the 1st instance of B establishes a session, that SHM area is lazily created. Once the 1st instance of C does the same, that separate SHM area is lazily created. So B1, B2, ... access one per-app SHM area, while C1, C2, ... access another.
Now consider app K, in split K-A. Here K is the server, A is the client. This, also, is allowed, despite the fact A is server in splits A-B, A-C. However, there is a natural constraint on A: there can only be one active process of it at a time, because it is the server in at least 1 split. It can be a client to server K; but there would only ever be 1 instance of it establishing sessions against K.
Informally: This is not necessarily frowned upon. After all the ability to have multiple concurrently active processes of a given app is somewhat exotic in the first place. That said, very vaguely speaking, it is more flexible to design a given app to only be server in every split in which it participates.
With the above explained, here is how the ipc::session API operates over these various ideas.
The simplest items are App (description of an application, which might a client or a server or both), Client_app (description of an application in its role as a client), and Server_app (you get the idea). See their doc headers, of course, but basically these are very simple data stores describing the basic structure of the IPC universe. Each application generally shall load the same values into its master lists of these structures. References to immutable Client_app and Server_app objects are passed into actual APIs having to do with the Session concept, to establish who can establish sessions with whom and how. Basically they describe the allowed splits.
As noted at the very top, the real goal is to open channels between processes and possibly to share data in SHM between them and others. To get there for a given process pair A-B, one must establish session A-B, as described above. Having chosen which one is A (server) and which is B (client), and loaded Client_app and Server_app structures to that effect, it is time to manage the sessions.
An established session is said to be a session in PEER state and is represented on each side by an object that implements the Session concept (see its important doc header). On the client side, this impl is the class template Client_session. On the server side, this impl is the class template Server_session. Once each respective side has its PEER-state Session impl object, opening channels and operating SHM areas on a per-session basis is well documented in the Session (concept) doc header and is fully symmetrical in terms of the API.
Client_session does not begin in PEER state. One constructs it in NULL state, then invokes Client_session::sync_connect()
to connect to the server process if any exists; once it fires its handler successfully, the Client_session is a Session in PEER state. If Client_session, per Session concept requirements, indicates the session has finished (due to the other side ending session), one must create a new Client_session and start over (w/r/t IPC and relevant shared resources).
Asymmetrically, on the server side, one must be ready to open potentially multiple Server_session
s. Firstly create a Session_server (see its doc header). To open 1 Server_session, default-construct one (hence in NULL state), then pass it as the target to Session_server::async_accept(). Once it fires your handler, you have an (almost-)PEER state Server_session, and moreover you may call Server_session::client_app()
to determine the identity of the connecting client app (via Client_app) which should (in multi-split situations) help decide what to further do with this Server_session (also, as on the opposing side, now a PEER-state Session concept impl). (If A participates in splits A-B and A-C, then the types of IPC work it might do with a B1 or B2 is likely to be quite different from same with a C1 or C2 or C3. If only split A-B is relevant to A, then that is not a concern.)
As noted, in terms of per-session shared resources, most notably channel communication, a Server_session and Client_session have identical APIs with identical capabilities, each implementing the PEER-state Session concept to the letter.
Extremely important (for performance at least) functionality is provided in the sub-namespace of ipc::session: ipc::session::shm. Please read its doc header now before using the types directly within ipc::session. That will allow you to make an informed choice.
sync_io
: integrate with poll()
-ish event loopsipc::session APIs feature exactly the following asynchronous (blocking, background, not-non-blocking, long...) operations:
ipc::session::Client_session::async_conenct()
(same for other, including SHM-aware, variants).All APIs mentioned so far operation broadly in the async-I/O pattern: Each event in question is reported from some unspecified background thread; it is up to the user to "post" the true handling onto their worker thread(s) as desired.
If one desires to be informed, instead, in a fashion friendly to old-school reactor loops – centered on poll()
, epoll_wait()
, or similar – a sync_io
alternate API is available. It is no faster, but it may be more convenient for some applications.
To use the alternate sync_io
interface: Look into session::sync_io and its 3 adapter templates:
Exactly the aforementioned async APIs are affected. All other APIs are available without change.
using ipc::session::Client_session = typedef Client_session_mv<Client_session_impl<S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload> > |
A vanilla Client_session
with no optional capabilities.
See Client_session_mv (+doc header) for full API as well as its doc header for possible alternatives that add optional capabilities (such as, at least, SHM setup/access). Opposing peer object: Server_session.
The following important template parameters are knobs that control the properties of the session; the opposing Server_session must use identical settings.
S_MQ_TYPE_OR_NONE | Session::Channel_obj (channel openable via open_channel() on this or other side) type config: Enumeration constant that specifies which type of MQ to use (corresponding to all available transport::Persistent_mq_handle concept impls) or to not use one (NONE ). Note: This enum type is capnp-generated; see common.capnp for values and brief docs. |
S_TRANSMIT_NATIVE_HANDLES | Session::Channel_obj (channel openable via open_channel() on this or other side) type config: Whether it shall be possible to transmit a native handle via the channel. |
Mdt_payload | See Session concept. In addition the same type may be used for mdt or mdt_from_srv_or_null in *_connect() . (If it is used for open_channel() and/or passive-open and/or *connect() mdt and/or mdt_from_srv_or_null , recall that you can use a capnp-union internally for various purposes.) |
Definition at line 318 of file session_fwd.hpp.
using ipc::session::Server_session = typedef Server_session_mv<Server_session_impl<S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload> > |
A vanilla Server_session
with no optional capabilities.
See Server_session_mv (+doc header) for full API as well as its doc header for possible alternatives that add optional capabilities (such as, at least, SHM setup/access). Opposing peer object: Client_session. Emitted by: Session_server.
The following important template parameters are knobs that control the properties of the session; the opposing Client_session must use identical settings.
S_MQ_TYPE_OR_NONE | Identical to Client_session. |
S_TRANSMIT_NATIVE_HANDLES | Identical to Client_session. |
Mdt_payload | See Session concept. In addition the same type may be used for mdt_from_cli_or_null (and srv->cli counterpart) in Session_server::async_accept(). (Recall that you can use a capnp-union internally for various purposes.) |
Definition at line 288 of file session_fwd.hpp.
using ipc::session::Session_token = typedef transport::struc::Session_token |
Convenience alias for the commonly used type transport::struc::Session_token.
Definition at line 248 of file session_fwd.hpp.
using ipc::session::Shared_name = typedef util::Shared_name |
Convenience alias for the commonly used type util::Shared_name.
Definition at line 245 of file session_fwd.hpp.
Shared_name ipc::session::build_conventional_shared_name | ( | const Shared_name & | resource_type, |
const Shared_name & | srv_app_name, | ||
const Shared_name & | srv_namespace, | ||
const Shared_name & | cli_app_name, | ||
const Shared_name & | cli_namespace_or_sentinel = Shared_name::S_SENTINEL |
||
) |
Builds an absolute name according to the path convention explained in Shared_name class doc header; this overload applies to non-global-scope resources within the ipc::session paradigm.
Typically one would then add a util::Shared_name::S_SEPARATOR and then purpose-specific path component(s) (via /=
or similar).
Behavior is undefined if a path fragment argument is empty (assertion may trip).
resource_type | Resource type constant. Typically it is available as a S_RESOURCE_TYPE_ID constant in some class; otherwise as a Shared_name::S_RESOURCE_TYPE_ID_* constant. |
srv_app_name | Session-server application name; typically from Server_app::m_name. |
srv_namespace | The server namespace, uniquely identifying the server application instance (process) across all time, for the given srv_app_name . (I.e., it need only be unique given the particular resource_type and srv_app_name .) |
cli_app_name | Session-client application name; typically from Client_app::m_name. |
cli_namespace_or_sentinel | The client namespace, uniquely identifying the client application instance (process), for the given set of values in preceding args. (I.e., it need only be unique given the particular values combo in the preceding args.) If the name applies to all instances of cli_app_name this shall be util::Shared_name::S_SENTINEL. |
S_SEPARATOR
, typically to be appended with a S_SEPARATOR
and more component(s) by the caller. Definition at line 43 of file session_shared_name.cpp.
References build_conventional_shared_name_prefix(), ipc::util::Shared_name::empty(), and ipc::util::Shared_name::S_SENTINEL.
Referenced by ipc::session::shm::classic::Server_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::async_accept_log_in(), ipc::session::shm::classic::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::async_connect(), ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::cur_ns_store_mutex_absolute_name(), ipc::session::shm::classic::Session_server< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::init_app_shm_as_needed(), ipc::session::shm::arena_lend::jemalloc::Session_server< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::init_app_shm_as_needed(), ipc::session::shm::arena_lend::jemalloc::Session_impl< Session_impl_t >::init_shm(), ipc::session::Server_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_SHM_MAX_HNDL_SZ, S_GRACEFUL_FINISH_REQUIRED_V >::make_channel_mqs(), and ipc::session::Session_base< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::session_master_socket_stream_acceptor_absolute_name().
Shared_name ipc::session::build_conventional_shared_name | ( | const Shared_name & | resource_type, |
const Shared_name & | srv_app_name, | ||
const Shared_name & | srv_namespace_or_sentinel = Shared_name::S_SENTINEL |
||
) |
Builds an absolute name according to the path convention explained in Shared_name class doc header; this overload applies to global-scope resources within the ipc::session paradigm.
Typically one would then add a util::Shared_name::S_SEPARATOR and then purpose-specific path component(s) (via /=
or similar). Note that this overload supports both of the following situations:
srv_namespace_or_sentinel = S_SENTINEL
.Arguably the former is more common.
Behavior is undefined if a path fragment argument is empty (assertion may trip).
resource_type | Resource type constant. Typically it is available as a S_RESOURCE_TYPE_ID constant in some class; otherwise as a Shared_name::S_RESOURCE_TYPE_ID_* constant. |
srv_app_name | Session-server application name; typically from Server_app::m_name. |
srv_namespace_or_sentinel | The server namespace, uniquely identifying the server application instance (process) across all time, for the given srv_app_name . (I.e., it need only be unique given the particular resource_type and srv_app_name .) Alternatively it may equal S_SENTINEL , indicating the resource applies to all instances of srv_app_name (unique Server_app). |
S_SEPARATOR
, typically to be appended with a S_SEPARATOR
and more component(s) by the caller. Definition at line 73 of file session_shared_name.cpp.
References build_conventional_shared_name_prefix(), ipc::util::Shared_name::empty(), and ipc::util::Shared_name::S_SENTINEL.
Shared_name ipc::session::build_conventional_shared_name_prefix | ( | const Shared_name & | resource_type, |
const Shared_name & | srv_app_name | ||
) |
Return the prefix common to all calls to either build_conventional_shared_name() overload with the args resource_type
and srv_app_name
.
For example one can use a value built by this function as the util::remove_each_persistent_with_name_prefix() prefix arg.
Note that the returned value always ends with S_SEPARATOR
.
resource_type | See build_conventional_shared_name() (either overload). |
srv_app_name | See build_conventional_shared_name() (either overload). |
S_SEPARATOR
. Definition at line 93 of file session_shared_name.cpp.
References ipc::util::Shared_name::empty(), ipc::util::Shared_name::S_ROOT_MAGIC, and ipc::util::Shared_name::S_SENTINEL.
Referenced by build_conventional_shared_name(), and ipc::session::Session_server_impl< Session_server_t, Server_session_t >::Session_server_impl().
bool ipc::session::decompose_conventional_shared_name | ( | const Shared_name & | name, |
Shared_name * | resource_type, | ||
Shared_name * | srv_app_name, | ||
Shared_name * | srv_namespace, | ||
Shared_name * | cli_app_name, | ||
Shared_name * | cli_namespace_or_sentinel, | ||
Shared_name * | the_rest | ||
) |
Decomposes a Shared_name built as-if by build_conventional_shared_name() overload 1 (non-global-scope); setting the various component values as out-args; or returning false
if the name does not follow the conventions of that build_conventional_shared_name() overload.
Important: In order for this to return true
(and thus optionally set any out-args), name
must be as-if it is a concatenation of:
S_SEPARATOR
.*the_rest
if not-null).I.e., name
cannot be the result of build_conventional_shared_name() alone but also a separator and possibly more characters.
name | Name to check/decompose. |
resource_type | If not-null, pointee is set to resource_type as-if given to build_conventional_shared_name() overload 1 (non-global-scope). If null ignored. |
srv_app_name | If not-null, pointee is set to srv_app_name as-if given to build_conventional_shared_name() overload 1 (non-global-scope). If null ignored. |
srv_namespace | If not-null, pointee is set to srv_namespace as-if given to build_conventional_shared_name() overload 1 (non-global-scope). If null ignored. This will never equal S_SENTINEL . |
cli_app_name | If not-null, pointee is set to cli_app_name as-if given to build_conventional_shared_name() overload 1 (non-global-scope). If null ignored. |
cli_namespace_or_sentinel | If not-null, pointee is set to cli_namespace_or_sentinel as-if given to build_conventional_shared_name() overload 1 (non-global-scope). If null ignored. This may equal S_SENTINEL . |
the_rest | If not-null, pointee is set to whatever follows the above components (even if some or all of their out-args were null) and the S_SEPARATOR immediately following the last of the above components. To be clear: that S_SEPARATOR itself is not included as the leading character of *the_rest . If null ignored. This may be .empty() . |
true
if and only if the name could be decomposed, meaning it was built as described above. Definition at line 114 of file session_shared_name.cpp.
References ipc::util::Shared_name::ct(), ipc::util::Shared_name::S_ROOT_MAGIC, ipc::util::Shared_name::S_SENTINEL, ipc::util::Shared_name::S_SEPARATOR, and ipc::util::Shared_name::str().
Referenced by ipc::session::shm::arena_lend::jemalloc::Client_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::cleanup(), and ipc::session::shm::arena_lend::jemalloc::Session_server< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload >::cleanup().
bool ipc::session::decompose_conventional_shared_name | ( | const Shared_name & | name, |
Shared_name * | resource_type, | ||
Shared_name * | srv_app_name, | ||
Shared_name * | srv_namespace_or_sentinel, | ||
Shared_name * | the_rest | ||
) |
Decomposes a Shared_name built as-if by build_conventional_shared_name() overload 2 (global-scope); setting the various component values as out-args; or returning false
if the name does not follow the conventions of that build_conventional_shared_name() overload.
Important: In order for this to return true
(and thus optionally set any out-args), name
must be as-if it is a concatenation of:
S_SEPARATOR
.*the_rest
if not-null).I.e., name
cannot be the result of build_conventional_shared_name() alone but also a separator and possibly more characters.
name | Name to check/decompose. |
resource_type | If not-null, pointee is set to resource_type as-if given to build_conventional_shared_name() overload 2 (global-scope). If null ignored. |
srv_app_name | If not-null, pointee is set to srv_app_name as-if given to build_conventional_shared_name() overload 2 (global-scope). If null ignored. |
srv_namespace_or_sentinel | If not-null, pointee is set to srv_namespace_or_sentinel as-if given to build_conventional_shared_name() overload 2 (global-scope). If null ignored. This will may equal S_SENTINEL . |
the_rest | If not-null, pointee is set to whatever follows the above components (even if some or all of their out-args were null), the S_SENTINEL , and the S_SEPARATOR immediately following the last of the above components. To be clear: that S_SEPARATOR itself is not included as the leading character of *the_rest . If null ignored. This may be .empty() . |
true
if and only if the name could be decomposed, meaning it was built as described above. If false
none of the out-args are touched. Definition at line 183 of file session_shared_name.cpp.
References ipc::util::Shared_name::ct(), ipc::util::Shared_name::S_ROOT_MAGIC, ipc::util::Shared_name::S_SENTINEL, ipc::util::Shared_name::S_SEPARATOR, and ipc::util::Shared_name::str().
void ipc::session::ensure_resource_owner_is_app | ( | flow::log::Logger * | logger_ptr, |
const fs::path & | path, | ||
const App & | app, | ||
Error_code * | err_code = 0 |
||
) |
Utility, used internally but exposed in public API in case it is of general use, that checks that the owner of the given resource (at the supplied file system path) is as specified in the given App (App::m_user_id et al).
If the resource cannot be accessed (not found, permissions...) that system Error_code shall be emitted. If it can, but the owner does not match, error::Code::S_RESOURCE_OWNER_UNEXPECTED shall be emitted.
logger_ptr | Logger to use for logging (WARNING, on error only, including S_RESOURCE_OWNER_UNEXPECTED ). |
path | Path to resource. Symlinks are followed, and the target is the resource in question (not the symlink). |
app | Describes the app with the expected owner info prescribed therein. |
err_code | See flow::Error_code docs for error reporting semantics. Error_code generated: error::Code::S_RESOURCE_OWNER_UNEXPECTED (check did not pass), system error codes if ownership cannot be checked. |
Definition at line 31 of file app.cpp.
References ensure_resource_owner_is_app().
Referenced by ensure_resource_owner_is_app(), and ipc::session::Session_server_impl< Session_server_t, Server_session_t >::Session_server_impl().
void ipc::session::ensure_resource_owner_is_app | ( | flow::log::Logger * | logger_ptr, |
util::Native_handle | handle, | ||
const App & | app, | ||
Error_code * | err_code = 0 |
||
) |
Identical to the other ensure_resource_owner_is_app() overload but operates on a pre-opened Native_handle
(a/k/a handle, socket, file descriptor) to the resource in question.
logger_ptr | See other overload. |
handle | See above. handle.null() == true causes undefined behavior (assertion may trip). Closed/invalid/etc. handle will yield civilized Error_code emission. |
app | See other overload. |
err_code | See flow::Error_code docs for error reporting semantics. Error_code generated: error::Code::S_RESOURCE_OWNER_UNEXPECTED (check did not pass), system error codes if ownership cannot be checked (invalid descriptor, un-opened descriptor, etc.). |
Definition at line 80 of file app.cpp.
References ensure_resource_owner_is_app(), ipc::session::App::m_group_id, ipc::util::Native_handle::m_native_handle, ipc::session::App::m_user_id, ipc::util::Native_handle::null(), and ipc::session::error::S_RESOURCE_OWNER_UNEXPECTED.
std::ostream & operator<< | ( | std::ostream & | os, |
const App & | val | ||
) |
std::ostream & operator<< | ( | std::ostream & | os, |
const Client_app & | val | ||
) |
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
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 2595 of file client_session_impl.hpp.
std::ostream & operator<< | ( | std::ostream & | os, |
const Client_session_mv< Client_session_impl_t > & | val | ||
) |
Prints string representation of the given Client_session_mv
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 419 of file client_session.hpp.
std::ostream & operator<< | ( | std::ostream & | os, |
const Server_app & | val | ||
) |
Prints string representation of the given Server_app
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. std::ostream & operator<< | ( | std::ostream & | os, |
const Server_session_impl< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload, S_SHM_TYPE_OR_NONE, S_SHM_MAX_HNDL_SZ, S_GRACEFUL_FINISH_REQUIRED_V > & | val | ||
) |
Prints string representation of the given Server_session_impl
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 2207 of file server_session_impl.hpp.
std::ostream & operator<< | ( | std::ostream & | os, |
const Server_session_mv< Server_session_impl_t > & | val | ||
) |
Prints string representation of the given Server_session_mv
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 375 of file server_session.hpp.
std::ostream & operator<< | ( | std::ostream & | os, |
const Session_mv< Session_impl_t > & | val | ||
) |
Prints string representation of the given Session_mv
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 951 of file session.hpp.
std::ostream & ipc::session::operator<< | ( | std::ostream & | os, |
const Session_server< S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload > & | val | ||
) |
Prints string representation of the given Session_server
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 522 of file session_server.hpp.
std::ostream & ipc::session::operator<< | ( | std::ostream & | os, |
const Session_server_impl< Session_server_t, Server_session_t > & | val | ||
) |
Prints string representation of the given Session_server_impl
to the given ostream
.
os | Stream to which to write. |
val | Object to serialize. |
os
. Definition at line 994 of file session_server_impl.hpp.