Index: mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h |
diff --git a/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h b/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h |
index be57f20be5c68a842b0eebbc44dee60a5b62a354..16527cf747fc765646ca7f7632b1b51425468425 100644 |
--- a/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h |
+++ b/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h |
@@ -7,9 +7,12 @@ |
#include <string> |
+#include "base/callback.h" |
#include "base/macros.h" |
#include "base/memory/ref_counted.h" |
#include "base/optional.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/threading/thread_task_runner_handle.h" |
#include "mojo/public/cpp/bindings/bindings_export.h" |
#include "mojo/public/cpp/bindings/disconnect_reason.h" |
#include "mojo/public/cpp/bindings/interface_id.h" |
@@ -20,8 +23,16 @@ class AssociatedGroupController; |
// ScopedInterfaceEndpointHandle refers to one end of an interface, either the |
// implementation side or the client side. |
+// Threading: At any given time, a ScopedInterfaceEndpointHandle should only |
+// be accessed from a single thread. |
class MOJO_CPP_BINDINGS_EXPORT ScopedInterfaceEndpointHandle { |
public: |
+ // Creates a pair of handles representing the two endpoints of an interface, |
+ // which are not yet associated with a message pipe. |
+ static void CreatePairPendingAssociation( |
+ ScopedInterfaceEndpointHandle* handle0, |
+ ScopedInterfaceEndpointHandle* handle1); |
+ |
// Creates an invalid endpoint handle. |
ScopedInterfaceEndpointHandle(); |
@@ -32,43 +43,77 @@ class MOJO_CPP_BINDINGS_EXPORT ScopedInterfaceEndpointHandle { |
ScopedInterfaceEndpointHandle& operator=( |
ScopedInterfaceEndpointHandle&& other); |
- bool is_valid() const { return IsValidInterfaceId(id_); } |
+ bool is_valid() const; |
- bool is_local() const { return is_local_; } |
+ // Returns true if the interface hasn't associated with a message pipe. |
+ bool pending_association() const; |
- void reset(); |
- void ResetWithReason(uint32_t custom_reason, const std::string& description); |
+ // Returns kInvalidInterfaceId when in pending association state or the handle |
+ // is invalid. |
+ InterfaceId id() const; |
- void swap(ScopedInterfaceEndpointHandle& other); |
+ // Returns null when in pending association state or the handle is invalid. |
+ AssociatedGroupController* group_controller() const; |
- // DO NOT USE METHODS BELOW THIS LINE. These are for internal use and testing. |
+ // Returns the disconnect reason if the peer handle is closed before |
+ // association and specifies a custom disconnect reason. |
+ const base::Optional<DisconnectReason>& disconnect_reason() const; |
- InterfaceId id() const { return id_; } |
+ enum AssociationEvent { |
+ // The interface has been associated with a message pipe. |
+ ASSOCIATED, |
+ // The peer of this object has been closed before association. |
+ PEER_CLOSED_BEFORE_ASSOCIATION |
+ }; |
- AssociatedGroupController* group_controller() const { |
- return group_controller_.get(); |
- } |
+ using AssociationEventCallback = base::OnceCallback<void(AssociationEvent)>; |
+ // Note: |
+ // - |handler| won't run if the handle is invalid. Otherwise, |handler| is run |
+ // on the calling thread asynchronously, even if the interface has already |
+ // been associated or the peer has been closed before association. |
+ // - |handler| won't be called after this object is destroyed or reset. |
+ // - A null |handler| can be used to cancel the previous callback. |
+ void SetAssociationEventHandler(AssociationEventCallback handler); |
- // Releases the handle without closing it. |
- InterfaceId release(); |
+ void reset(); |
+ void ResetWithReason(uint32_t custom_reason, const std::string& description); |
private: |
friend class AssociatedGroupController; |
+ friend class AssociatedGroup; |
+ |
+ class State; |
- // This is supposed to be used by AssociatedGroupController only. |
- // |id| is the corresponding interface ID. |
- // If |is_local| is false, this handle is meant to be passed over a message |
- // pipe the remote side of the associated group. |
+ // Used by AssociatedGroupController. |
ScopedInterfaceEndpointHandle( |
InterfaceId id, |
- bool is_local, |
scoped_refptr<AssociatedGroupController> group_controller); |
+ // Used by AssociatedGroupController. |
+ // The peer of this handle will join |peer_group_controller|. |
+ bool NotifyAssociation( |
+ InterfaceId id, |
+ scoped_refptr<AssociatedGroupController> peer_group_controller); |
+ |
void ResetInternal(const base::Optional<DisconnectReason>& reason); |
- InterfaceId id_; |
- bool is_local_; |
- scoped_refptr<AssociatedGroupController> group_controller_; |
+ // Used by AssociatedGroup. |
+ // It is safe to run the returned callback on any thread, or after this handle |
+ // is destroyed. |
+ // The return value of the getter: |
+ // - If the getter is retrieved when the handle is invalid, the return value |
+ // of the getter will always be null. |
+ // - If the getter is retrieved when the handle is valid and non-pending, |
+ // the return value of the getter will be non-null and remain unchanged |
+ // even if the handle is later reset. |
+ // - If the getter is retrieved when the handle is valid but pending |
+ // asssociation, the return value of the getter will initially be null, |
+ // change to non-null when the handle is associated, and remain unchanged |
+ // ever since. |
+ base::Callback<AssociatedGroupController*()> CreateGroupControllerGetter() |
+ const; |
+ |
+ scoped_refptr<State> state_; |
DISALLOW_COPY_AND_ASSIGN(ScopedInterfaceEndpointHandle); |
}; |