diff --git a/ipc_core b/ipc_core index 983df09dc..f1b6c951d 160000 --- a/ipc_core +++ b/ipc_core @@ -1 +1 @@ -Subproject commit 983df09dc622065a91c46f8b2f7a9348b1743f5c +Subproject commit f1b6c951defbab8449ae1c2038aeb059e5cc7ea1 diff --git a/ipc_shm b/ipc_shm index 01b50be91..88f63ddc0 160000 --- a/ipc_shm +++ b/ipc_shm @@ -1 +1 @@ -Subproject commit 01b50be916711d97f54b9fda695035fe3c90a3ab +Subproject commit 88f63ddc0f21c271039d3db41f28daa9ebf715b2 diff --git a/ipc_shm_arena_lend b/ipc_shm_arena_lend index c435dafee..30fbea301 160000 --- a/ipc_shm_arena_lend +++ b/ipc_shm_arena_lend @@ -1 +1 @@ -Subproject commit c435dafee38f02e397ffa652a3bb90cf5e7a8528 +Subproject commit 30fbea3017be445b8c84a6c1e268495dda5df2aa diff --git a/ipc_transport_structured b/ipc_transport_structured index d144e7811..0cd1eb32c 160000 --- a/ipc_transport_structured +++ b/ipc_transport_structured @@ -1 +1 @@ -Subproject commit d144e7811ff278fcbddb626e72603b7efebd4633 +Subproject commit 0cd1eb32c049b488b91222e022e6ca7f07f1254e diff --git a/src/doc/manual/l-transport_shm.dox.txt b/src/doc/manual/l-transport_shm.dox.txt index 35e9307d8..1a683b83b 100644 --- a/src/doc/manual/l-transport_shm.dox.txt +++ b/src/doc/manual/l-transport_shm.dox.txt @@ -412,9 +412,18 @@ Example owner/lender code: auto msg = cool_channel.create_msg(); // Ready the lend_blob-storage inside the out-message. auto widget_handle_root = msg.body_root()->initSomeMsg().initWidgetHandle(); + // Perform the lend_object() step and load the result into the out-message. + + const auto hndl_blob = session.lend_object(x); + // ATTENTION! SHM-jemalloc-backed lend_object() can fail, if right then the session got hosed (opposing process down). + if (shm_blob.empty()) + { + throw ...; // Or some other error handling technique. + } + ipc::transport::struc::shm::capnp_set_lent_shm_handle(&widget_handle_root, // Output. - session.lend_object(x)); // Input. + shm_blob); // Input. // IPC-transmit it via struc::Channel. cool_channel.send(msg); @@ -427,11 +436,19 @@ And counterpart borrower code: ipc::transport::struc::shm::capnp_get_shm_handle_to_borrow(msg->body_root().getSomeMsg().getWidgetHandle(), &lend_blob); auto x_borrowed = session.borrow_object(lend_blob); + // ATTENTION! SHM-jemalloc-backed borrow_object() can fail, if right then the session got hosed (opposing process down). + if (!x_borrowed) + { + throw ...; // Or some other error handling technique. + } + FLOW_LOG_INFO("Hey, let's read inside SHM after receiving SHM-handle: [" << x_borrowed->m_flag << "]."); ~~~ Simple! That said we opportunistically note: The borrower-side is using `Widget_brw`, a type we have not explicitly provided the code for in the actual example. Per the side-bar above, with SHM-classic it could just be `Widget` (same as in owner); but with SHM-jemalloc and generically you'd need to define a mirror of `Widget` called `Widget_brw` which would use `Session::Borrower_allocator` instead of `Session::Allocator` all-over. We'll leave that as an exercise to the reader. Tip: You do *not* need to copy paste the same type twice. Use template trickery -- perhaps `std::conditional_t` -- to conveniently pick between the two `*llocator` templates depending on a compile-time `bool S_OWN_ELSE_BRW` template parameter perhaps. +@note Regarding `session.lend_object()` and `session.borrow_object()` failing: As you can see above, your code should be ready for these to return an empty blob and null, respectively, indicating an error. In practice, assuming you're using them with proper inputs, this will not happen with SHM-classic, but it absolutely can happen with SHM-jemalloc; and SHM-provider-agnostic code should therefore assume the latter. What does it mean? Answer: It means, at least, that no further lending/borrowing shall work in this session. In practice you should assume it means the entire session is hosed in general (the opposing process is probably down). This *will* be (shortly) emitted as an error by the `Session` via its on-error handler you had to register (via ctor or `.init_handlers()`, on client and server sides respectively). Almost certainly each not-yet-hosed PEER-state `Channel` from that session shall report similarly. The safest course of action is to react to any of these signals -- including lend/borrow methods returning empty/null -- in a common way (abandon session ASAP in orderly fashion). That topic is discussed in-depth in @ref session_app_org. + ### What can you do with a borrowed (received) data structured in SHM? ### The answer to this is sprinkled throughout the above. Nevertheless it seemed prudent to put a fine point on the answer as well as perhaps provide some algorithmic tips.