template <typename Protocol>

class SharedClient

Defined at line 337 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

|SharedClient| is a client for sending and receiving wire and natural

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, |SharedClient| 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, |SharedClient| supports cloning multiple instances sharing

the same underlying endpoint.

## Lifecycle

See lifecycle notes on |Client| for general lifecycle information. Here

we note the additional subtleties and two-phase shutdown features exclusive

to |SharedClient|.

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 |SharedClient| 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 |SharedClient| 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 |SharedClient|

itself:

- Assigning a new value to the |SharedClient| variable.

- Moving the |SharedClient| to a different location.

- Destroying the |SharedClient| 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::AsyncEventHandler<Protocol>>
void SharedClient<Protocol> (fidl::ClientEnd<Protocol> client_end, async_dispatcher_t * dispatcher, std::unique_ptr<AsyncEventHandler> event_handler)

Creates an initialized |SharedClient| 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 354 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

template <typename AsyncEventHandler = fidl::AsyncEventHandler<Protocol>>
void SharedClient<Protocol> (fidl::ClientEnd<Protocol> client_end, async_dispatcher_t * dispatcher, AsyncEventHandler * event_handler, fidl::AnyTeardownObserver teardown_observer)

Creates a |SharedClient| 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 |SharedClient| above for other behavior aspects of the constructor.

Defined at line 371 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

template <typename AsyncEventHandler = fidl::AsyncEventHandler<Protocol>>
void SharedClient<Protocol> (fidl::ClientEnd<Protocol> client_end, async_dispatcher_t * dispatcher, fidl::AnyTeardownObserver teardown_observer)

Overload of |SharedClient| that omits the |event_handler|, to

workaround C++ limitations on default arguments.

See |SharedClient| above for other behavior aspects of the constructor.

Defined at line 382 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

void SharedClient<Protocol> ()

Creates an uninitialized |SharedClient|.

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 393 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

bool is_valid ()

Returns if the |SharedClient| is initialized.

Defined at line 396 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

bool operator bool ()

Defined at line 397 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

void ~SharedClient<Protocol> ()

If the current |SharedClient| is the last instance controlling the

current connection, the destructor of this |SharedClient| will trigger

teardown.

When the last |SharedClient| 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 |Client|.

See also: |AsyncTeardown|.

Defined at line 410 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

void SharedClient<Protocol> (SharedClient<Protocol> && other)

|fidl::SharedClient|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 416 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

SharedClient<Protocol> & operator= (SharedClient<Protocol> && other)

Defined at line 417 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

void Bind (fidl::ClientEnd<Protocol> client_end, async_dispatcher_t * dispatcher, std::unique_ptr<fidl::AsyncEventHandler<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

|SharedClient| to a different endpoint, simply replace the

|SharedClient| 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 432 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

void Bind (fidl::ClientEnd<Protocol> client_end, async_dispatcher_t * dispatcher, fidl::AsyncEventHandler<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 450 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

void Bind (fidl::ClientEnd<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 464 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/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 477 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

SharedClient<Protocol> Clone ()

Returns another |SharedClient| 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 484 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

const NaturalClientImpl * operator-> ()

Returns the interface for making outgoing FIDL calls using natural objects.

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

|Client| reference-counting type.

Defined at line 495 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

const NaturalClientImpl & operator* ()

Defined at line 496 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h

auto wire ()

Returns the interface for making outgoing FIDL calls using wire objects.

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

|Client| reference-counting type.

Defined at line 507 of file ../../sdk/lib/fidl/cpp/include/lib/fidl/cpp/client.h