1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_ 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#define MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_ 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 86d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/c/environment/async_waiter.h" 9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/bindings/lib/message_queue.h" 10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/bindings/message.h" 116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/cpp/environment/environment.h" 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace mojo { 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ErrorHandler; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace internal { 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The Connector class is responsible for performing read/write operations on a 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// MessagePipe. It writes messages it receives through the MessageReceiver 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// interface that it subclasses, and it forwards messages it reads through the 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// MessageReceiver interface assigned as its incoming receiver. 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// NOTE: MessagePipe I/O is non-blocking. 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Connector : public MessageReceiver { 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The Connector takes ownership of |message_pipe|. 296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) explicit Connector( 306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ScopedMessagePipeHandle message_pipe, 316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()); 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~Connector(); 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Sets the receiver to handle messages read from the message pipe. The 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Connector will read messages from the pipe regardless of whether or not an 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // incoming receiver has been set. 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void set_incoming_receiver(MessageReceiver* receiver) { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) incoming_receiver_ = receiver; 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Errors from incoming receivers will force the connector into an error 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // state, where no more messages will be processed. This method is used 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // during testing to prevent that from happening. 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void set_enforce_errors_from_incoming_receiver(bool enforce) { 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) enforce_errors_from_incoming_receiver_ = enforce; 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sets the error handler to receive notifications when an error is 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // encountered while reading from the pipe or waiting to read from the pipe. 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void set_error_handler(ErrorHandler* error_handler) { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_handler_ = error_handler; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns true if an error was encountered while reading from the pipe or 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // waiting to read from the pipe. 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool encountered_error() const { return error_; } 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // Closes the pipe, triggering the error state. Connector is put into a 590de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // quiescent state. 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void CloseMessagePipe(); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // Releases the pipe, not triggering the error state. Connector is put into 630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // a quiescent state. 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedMessagePipeHandle PassMessagePipe(); 650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Waits for the next message on the pipe, blocking until one arrives or an 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // error happens. Returns |true| if a message has been delivered, |false| 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // otherwise. 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool WaitForIncomingMessage(); 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // MessageReceiver implementation: 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual bool Accept(Message* message) MOJO_OVERRIDE; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void CallOnHandleReady(void* closure, MojoResult result); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnHandleReady(MojoResult result); 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void WaitToReadMore(); 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Returns false if |this| was destroyed during message dispatch. 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOJO_WARN_UNUSED_RESULT bool ReadSingleMessage(MojoResult* read_result); 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // |this| can be destroyed during message dispatch. 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void ReadAllAvailableMessages(); 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void NotifyError(); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Cancels any calls made to |waiter_|. 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void CancelWait(); 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ErrorHandler* error_handler_; 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const MojoAsyncWaiter* waiter_; 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ScopedMessagePipeHandle message_pipe_; 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MessageReceiver* incoming_receiver_; 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoAsyncWaitID async_wait_id_; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool error_; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool drop_writes_; 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool enforce_errors_from_incoming_receiver_; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If non-null, this will be set to true when the Connector is destroyed. We 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // use this flag to allow for the Connector to be destroyed as a side-effect 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // of dispatching an incoming message. 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool* destroyed_flag_; 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MOJO_DISALLOW_COPY_AND_ASSIGN(Connector); 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace internal 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace mojo 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_ 114