1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_ASYNC_SOCKET_CONNECTOR_H_ 18 #define ANDROID_ASYNC_SOCKET_CONNECTOR_H_ 19 20 #include "qemu-common.h" 21 #include "android/async-io-common.h" 22 #include "android/async-utils.h" 23 24 /* 25 * Contains declaration of an API that allows asynchronous connection to a 26 * socket with retries. 27 * 28 * The typical usage of this API is as such: 29 * 30 * 1. The client creates an asynchronous connector instance by calling 31 * async_socket_connector_new routine, supplying there address of the socket 32 * to connect, and a callback to invoke on connection events. 33 * 2. The client then proceeds with calling async_socket_connector_connect that 34 * would initiate connection attempts. 35 * 36 * The main job on the client side falls on the client's callback routine that 37 * serves the connection events. Once connection has been initiated, the connector 38 * will invoke that callback to report current connection status. 39 * 40 * In general, there are three connection events passed to the callback: 41 * 1. Success. 42 * 2. Failure. 43 * 3. Retry. 44 * 45 * Typically, when client's callback is called for a successful connection, the 46 * client will pull connected socket's FD from the connector, and then this FD 47 * will be used by the client for I/O on the connected socket. 48 * 49 * When client's callback is invoked with an error (ASIO_STATE_FAILED event), the 50 * client has an opportunity to review the error (available in 'errno'), and 51 * either abort the connection by returning ASIO_ACTION_ABORT, or schedule a retry 52 * by returning ASIO_ACTION_RETRY from the callback. If client returns ASIO_ACTION_ABORT 53 * from the callback, the connector will stop connection attempts, and will 54 * self-destruct. If ASIO_ACTION_RETRY is returned from the callback, the connector 55 * will retry connection attempt after timeout that was set by the caller in the 56 * call to async_socket_connector_new routine. 57 * 58 * When client's callback is invoked with ASIO_STATE_RETRYING (indicating that 59 * connector is about to retry a connection attempt), the client has an opportunity 60 * to cancel further connection attempts by returning ASIO_ACTION_ABORT, or it 61 * can allow another connection attempt by returning ASIO_ACTION_RETRY. 62 * 63 * Since it's hard to control lifespan of an object in asynchronous environment, 64 * we make AsyncSocketConnector a referenced object, that will self-destruct when 65 * its reference count drops to zero, indicating that the last client has 66 * abandoned that object. 67 */ 68 69 /* Declares async socket connector descriptor. */ 70 typedef struct AsyncSocketConnector AsyncSocketConnector; 71 72 /* Declares callback that connector's client uses to monitor connection 73 * status / progress. 74 * Param: 75 * opaque - An opaque pointer associated with the client. 76 * connector - AsyncSocketConnector instance. 77 * event - Event that has occurred. If event is set to ASIO_STATE_FAILED, 78 * errno contains connection error. 79 * Return: 80 * One of AsyncIOAction values. 81 */ 82 typedef AsyncIOAction (*asc_event_cb)(void* opaque, 83 AsyncSocketConnector* connector, 84 AsyncIOState event); 85 86 /* Creates and initializes AsyncSocketConnector instance. 87 * Note that upon exit from this routine the reference count to the returned 88 * object is set to 1. 89 * Param: 90 * address - Initialized socket address to connect to. 91 * retry_to - Timeout to retry a failed connection attempt in milliseconds. 92 * cb, cb_opaque - Callback to invoke on connection events. This callback is 93 * required, and must not be NULL. 94 * looper - An optional (can be NULL) I/O looper to use for connection I/O. If 95 * this parameter is NULL, the connector will create its own looper. 96 * Return: 97 * Initialized AsyncSocketConnector instance. Note that AsyncSocketConnector 98 * instance returned from this routine will be destroyed by the connector itself, 99 * when its work on connecting to the socket is completed. Typically, connector 100 * will destroy its descriptor after client's callback routine returns with a 101 * status other than ASIO_ACTION_RETRY. 102 */ 103 extern AsyncSocketConnector* async_socket_connector_new(const SockAddress* address, 104 int retry_to, 105 asc_event_cb cb, 106 void* cb_opaque, 107 Looper* looper); 108 109 /* References AsyncSocketConnector object. 110 * Param: 111 * connector - Initialized AsyncSocketConnector instance. 112 * Return: 113 * Number of outstanding references to the object. 114 */ 115 extern int async_socket_connector_reference(AsyncSocketConnector* connector); 116 117 /* Releases AsyncSocketConnector object. 118 * Note that upon exit from this routine the object might be destroyed, even if 119 * the routine returns value other than zero. 120 * Param: 121 * connector - Initialized AsyncSocketConnector instance. 122 * Return: 123 * Number of outstanding references to the object. 124 */ 125 extern int async_socket_connector_release(AsyncSocketConnector* connector); 126 127 /* Initiates asynchronous connection. 128 * Note that connection result will be reported via callback set with the call to 129 * async_socket_connector_new routine. 130 * Param: 131 * connector - Initialized AsyncSocketConnector instance. Note that this 132 * connector descriptor might be destroyed asynchronously, before this 133 * routine returns. 134 */ 135 extern void async_socket_connector_connect(AsyncSocketConnector* connector); 136 137 /* Pulls socket's file descriptor from the connector. 138 * This routine should be called from the connection callback on successful 139 * connection status. This will provide the connector's client with an operational 140 * socket FD, and at the same time this will tell the connector not to close the 141 * FD when connector descriptor gets destroyed. 142 * Param: 143 * connector - Initialized AsyncSocketConnector instance. 144 * Return: 145 * File descriptor for the connected socket. 146 */ 147 extern int async_socket_connector_pull_fd(AsyncSocketConnector* connector); 148 149 #endif /* ANDROID_ASYNC_SOCKET_CONNECTOR_H_ */ 150