template <typename Protocol>
class WireSharedClient
Defined at line 383 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
|WireSharedClient| is a client for sending and receiving wire messages. It is
suitable for systems with less defined threading guarantees, by providing the
building blocks to implement a two-phase asynchronous shutdown pattern.
During teardown, |WireSharedClient| exposes a synchronization point beyond
which it will not make any more upcalls to user code. The user may then
arrange any objects that are the recipient of client callbacks to be
destroyed after the synchronization point. As a result, when destroying an
entire subsystem, the teardown of the client may be requested from an
arbitrary thread, in parallel with any callbacks to user code, while
avoiding use-after-free of user objects.
In addition, |WireSharedClient| supports cloning multiple instances sharing
the same underlying endpoint.
## Lifecycle
See lifecycle notes on |WireClient| for general lifecycle information. Here
we note the additional subtleties and two-phase shutdown features exclusive
to |WireSharedClient|.
Teardown of the binding is an asynchronous process, to account for the
possibility of in-progress calls to user code. For example, the bindings
runtime could be invoking a response callback from a dispatcher thread, while
the user initiates teardown from an unrelated thread.
There are a number of ways to monitor the completion of teardown:
- Owned event handler: transfer the ownership of an event handler to the
bindings as a |std::unique_ptr| when binding the client. After teardown is
complete, the event handler will be destroyed. It is safe to destroy the
user objects referenced by any client callbacks from within the event
handler destructor.
- Teardown observer: provide an instance of |fidl::AnyTeardownObserver| to
the bindings. The observer will be notified when teardown is complete.
See
https://fuchsia.dev/fuchsia-src/development/languages/fidl/guides/llcpp-threading
for detailed examples.
A |WireSharedClient| may be |Clone|d, with the clone referencing the same
endpoint. Automatic teardown occurs when the last clone bound to the
endpoint is destructed.
|AsyncTeardown| may be called on a |WireSharedClient| to explicitly initiate
teardown.
## Thread safety
FIDL method calls on this class are thread-safe. |Clone| may be invoked in
parallel with FIDL method calls. However, those operations must be
synchronized with operations that consume or mutate the |WireSharedClient|
itself:
- Assigning a new value to the |WireSharedClient| variable.
- Moving the |WireSharedClient| to a different location.
- Destroying the |WireSharedClient| variable.
- Calling |AsyncTeardown|.
When teardown completes, the binding will notify the user from a |dispatcher|
thread, unless the user shuts down the |dispatcher| while there are active
clients associated with it. In that case, those clients will be synchronously
torn down, and the notification (e.g. destroying the event handler) will
happen on the thread invoking dispatcher shutdown.
Public Methods
template <typename AsyncEventHandler = fidl::WireAsyncEventHandler<Protocol>>
void WireSharedClient<Protocol> (fidl::internal::ClientEndType<Protocol> client_end, async_dispatcher_t * dispatcher, std::unique_ptr<AsyncEventHandler> event_handler)
Creates an initialized |WireSharedClient| which manages the binding of the
client end of a channel to a dispatcher.
It is a logic error to use a dispatcher that is shutting down or already
shut down. Doing so will result in a panic.
If any other error occurs during initialization, the
|event_handler->on_fidl_error| handler will be invoked asynchronously with
the reason, if specified.
|event_handler| will be destroyed when teardown completes.
Defined at line 397 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
template <typename AsyncEventHandler = fidl::WireAsyncEventHandler<Protocol>>
void WireSharedClient<Protocol> (fidl::internal::ClientEndType<Protocol> client_end, async_dispatcher_t * dispatcher, AsyncEventHandler * event_handler, fidl::AnyTeardownObserver teardown_observer)
Creates a |WireSharedClient| that supports custom behavior on teardown
completion via |teardown_observer|. Through helpers that return an
|AnyTeardownObserver|, users may link the completion of teardown to the
invocation of a callback or the lifecycle of related business objects. See
for example |fidl::ObserveTeardown| and |fidl::ShareUntilTeardown|.
This overload does not demand taking ownership of |event_handler| by
|std::unique_ptr|, hence is suitable when the |event_handler| needs to be
managed independently of the client lifetime.
See |WireSharedClient| above for other behavior aspects of the constructor.
Defined at line 415 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
template <typename AsyncEventHandler = fidl::WireAsyncEventHandler<Protocol>>
void WireSharedClient<Protocol> (fidl::internal::ClientEndType<Protocol> client_end, async_dispatcher_t * dispatcher, fidl::AnyTeardownObserver teardown_observer)
Overload of |WireSharedClient| that omits the |event_handler|, to
workaround C++ limitations on default arguments.
See |WireSharedClient| above for other behavior aspects of the constructor.
Defined at line 427 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void WireSharedClient<Protocol> ()
Creates an uninitialized |WireSharedClient|.
Prefer using the constructor overload that binds the client to a channel
atomically during construction. Use this default constructor only when the
client must be constructed first before a channel could be obtained (for
example, if the client is an instance variable).
Defined at line 439 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
bool is_valid ()
Returns if the |WireSharedClient| is initialized.
Defined at line 442 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
bool operator bool ()
Defined at line 443 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void ~WireSharedClient<Protocol> ()
If the current |WireSharedClient| is the last instance controlling the
current connection, the destructor of this |WireSharedClient| will trigger
teardown.
When the last |WireSharedClient| destructs:
- The channel will be closed.
- Pointers obtained via |get| will be invalidated.
- Teardown will be initiated. See the **Lifecycle** section from the
class documentation of |WireClient|.
See also: |AsyncTeardown|.
Defined at line 456 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void WireSharedClient<Protocol> (WireSharedClient<Protocol> && other)
|fidl::WireSharedClient|s can be safely moved without affecting any in-progress
operations. Note that calling methods on a client should be serialized with
respect to operations that consume the client, such as moving it or
destroying it.
Defined at line 462 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
WireSharedClient<Protocol> & operator= (WireSharedClient<Protocol> && other)
Defined at line 463 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void Bind (fidl::internal::ClientEndType<Protocol> client_end, async_dispatcher_t * dispatcher, std::unique_ptr<fidl::WireAsyncEventHandler<Protocol>> event_handler)
Initializes the client by binding the |client_end| endpoint to the dispatcher.
It is a logic error to invoke |Bind| on a dispatcher that is shutting down
or already shut down. Doing so will result in a panic.
It is not allowed to call |Bind| on an initialized client. To rebind a
|WireSharedClient| to a different endpoint, simply replace the
|WireSharedClient| variable with a new instance.
When other error occurs during binding, the |event_handler->on_fidl_error|
handler will be asynchronously invoked with the reason, if specified.
|event_handler| will be destroyed when teardown completes.
Defined at line 478 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void Bind (fidl::internal::ClientEndType<Protocol> client_end, async_dispatcher_t * dispatcher, fidl::WireAsyncEventHandler<Protocol> * event_handler, fidl::AnyTeardownObserver teardown_observer)
Overload of |Bind| that supports custom behavior on teardown completion via
|teardown_observer|. Through helpers that return an |AnyTeardownObserver|,
users may link the completion of teardown to the invocation of a callback
or the lifecycle of related business objects. See for example
|fidl::ObserveTeardown| and |fidl::ShareUntilTeardown|.
This overload does not demand taking ownership of |event_handler| by
|std::unique_ptr|, hence is suitable when the |event_handler| needs to be
managed independently of the client lifetime.
See |Bind| above for other behavior aspects of the function.
Defined at line 496 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void Bind (fidl::internal::ClientEndType<Protocol> client_end, async_dispatcher_t * dispatcher, fidl::AnyTeardownObserver teardown_observer)
Overload of |Bind| that omits the |event_handler|, to
workaround C++ limitations on default arguments.
See |Bind| above for other behavior aspects of the constructor.
Defined at line 509 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
void AsyncTeardown ()
Initiates asynchronous teardown of the bindings. See the **Lifecycle**
section from the class documentation.
|Bind| must have been called before this.
While it is safe to invoke |AsyncTeardown| from any thread, it is unsafe to
wait for teardown to complete from a dispatcher thread, as that will likely
deadlock.
Defined at line 522 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
WireSharedClient<Protocol> Clone ()
Returns another |WireSharedClient| instance sharing the same channel.
Prefer to |Clone| only when necessary e.g. extending the lifetime of a
|SharedClient| to a different scope. Any clone will prevent the cleanup
of the channel while the binding is alive.
Defined at line 529 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
auto operator-> ()
Returns the interface for making outgoing FIDL calls with managed memory
allocation. The client must be initialized first.
If the binding has been torn down, calls on the interface return error with
status |ZX_ERR_CANCELED| and reason |fidl::Reason::kUnbind|.
Persisting this pointer to a local variable is discouraged, since that
results in unsafe borrows. Always prefer making calls directly via the
|WireSharedClient| reference-counting type. A client may be cloned and
handed off through the |Clone| method.
Defined at line 541 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
template <typename MemoryResource>
auto buffer (MemoryResource && resource)
Returns a veneer object which exposes the caller-allocating API, using
the provided |resource| to allocate buffers necessary for each call.
See documentation on |WireClient::buffer| for detailed behavior.
Defined at line 549 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
auto sync ()
Returns a veneer object exposing synchronous calls. Example:
fidl::WireClient client(std::move(client_end), some_dispatcher);
fidl::WireResult result = client.sync()->FooMethod(args);
Defined at line 560 of file ../../sdk/lib/fidl/cpp/wire/include/lib/fidl/cpp/wire/client.h
Friends
template <typename Protocol>
class ClientChecker