1 // Copyright 2014 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include "aemu/base/Compiler.h" 18 19 #include <stdint.h> 20 21 namespace android { 22 namespace base { 23 24 // A SocketWaiter is an abstraction that allows one to wait for i/o 25 // events on a set of socket file descriptors for a certain amount 26 // of time. Usage is: 27 // 28 // 1/ Create the waiter instance: 29 // 30 // SocketWaiter* waiter = SocketWaiter::create(); 31 // 32 // 2/ Call the update() method to indicate which I/O events you want 33 // to listen to for a given file descriptor |fd|: 34 // 35 // waiter->update(fd1, SocketWaiter::kEventRead); 36 // waiter->update(fd2, SocketWaiter::kEventWrite); 37 // 38 // 3/ Call the wait() method to wait for i/o events on the registered 39 // socket file descriptors. 40 // 41 // int ret = waiter->wait(timeout_ms); 42 // 43 // 4/ After wait() returns, call nextPendingFd() to get the list of 44 // file descriptors that have pending i/o events, and the corresponding 45 // event mask. The function returns -1 once you reach past the list: 46 // 47 // for (;;) { 48 // unsigned events = 0; 49 // int fd = waiter->nextPendingFd(&events); 50 // if (fd < 0) { 51 // break; 52 // } 53 // // Handle |events| on socket |fd|. 54 // } 55 // 56 // 5/ Which file descriptors are being watched is recorded by the waiter 57 // between several calls to wait(). You can use reset() to clear all 58 // of them at once, or call update() with 0 as the second parameter to 59 // indicate you no longer want to listen to events on a given 60 // descriptor, as in: 61 // 62 // waiter->update(fd2, 0); 63 // 64 class SocketWaiter { 65 public: 66 enum Event { 67 kEventRead = (1U << 0), 68 kEventWrite = (1U << 1), 69 }; 70 71 // Create new SocketWaiter instance. 72 static SocketWaiter* create(); 73 74 // Destroy the instance. ~SocketWaiter()75 virtual ~SocketWaiter() {} 76 77 // Reset the waiter, i.e. equivalent to calling update(fd, 0) on 78 // all previously registered socket descriptors. 79 virtual void reset() = 0; 80 81 // Return the current wanted event bitmask for a given |fd|. 82 virtual unsigned wantedEventsFor(int fd) const = 0; 83 84 // Return the pending event bitmask for a given |fd|. Only use this 85 // after calling wait(). 86 virtual unsigned pendingEventsFor(int fd) const = 0; 87 88 // Return true iff there are registered socket descriptors. 89 virtual bool hasFds() const = 0; 90 91 // Tell the waiter to look for i/o events on socket descriptor |fd|. 92 // |events| is a bitmask containing kEventRead, kEventWrite or both. 93 virtual void update(int fd, unsigned events) = 0; 94 95 // Wait at most |timeout_ms| milli-seconds for i/o events to occur 96 // on registered socket descriptors. If |timeout_ms| is 0, return 97 // immediately after polling the descriptors. If it is INT64_MAX, 98 // then wait indefinitely. 99 // 100 // Return the number of descriptors that have i/o events. 101 // In case of timeout, return 0 and sets errno to ETIMEDOUT. 102 // In case of error, return -1/errno. 103 // 104 // This function loops around EINTR as a convenience. 105 virtual int wait(int64_t timeout_ms) = 0; 106 107 // Get the next pending socket descriptor and associated i/o event mask. 108 // Return the next socket descriptor, or -1 when the end of the list 109 // is reached. On success, sets |*fdEvents| to the corresponding 110 // event mask. 111 virtual int nextPendingFd(unsigned* fdEvents) = 0; 112 113 protected: SocketWaiter()114 SocketWaiter() {} 115 116 DISALLOW_COPY_AND_ASSIGN(SocketWaiter); 117 }; 118 119 } // namespace base 120 } // namespace android 121