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