1 /* 2 * Copyright (C) 2010 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 UTILS_LOOPER_H 18 #define UTILS_LOOPER_H 19 20 #include <utils/threads.h> 21 #include <utils/RefBase.h> 22 #include <utils/KeyedVector.h> 23 #include <utils/Timers.h> 24 25 #include <android/looper.h> 26 27 // When defined, uses epoll_wait() for polling, otherwise uses poll(). 28 #define LOOPER_USES_EPOLL 29 30 // When defined, logs performance statistics for tuning and debugging purposes. 31 //#define LOOPER_STATISTICS 32 33 #ifdef LOOPER_USES_EPOLL 34 #include <sys/epoll.h> 35 #else 36 #include <sys/poll.h> 37 #endif 38 39 /* 40 * Declare a concrete type for the NDK's looper forward declaration. 41 */ 42 struct ALooper { 43 }; 44 45 namespace android { 46 47 /** 48 * A message that can be posted to a Looper. 49 */ 50 struct Message { 51 Message() : what(0) { } 52 Message(int what) : what(what) { } 53 54 /* The message type. (interpretation is left up to the handler) */ 55 int what; 56 }; 57 58 59 /** 60 * Interface for a Looper message handler. 61 * 62 * The Looper holds a strong reference to the message handler whenever it has 63 * a message to deliver to it. Make sure to call Looper::removeMessages 64 * to remove any pending messages destined for the handler so that the handler 65 * can be destroyed. 66 */ 67 class MessageHandler : public virtual RefBase { 68 protected: 69 virtual ~MessageHandler() { } 70 71 public: 72 /** 73 * Handles a message. 74 */ 75 virtual void handleMessage(const Message& message) = 0; 76 }; 77 78 79 /** 80 * A simple proxy that holds a weak reference to a message handler. 81 */ 82 class WeakMessageHandler : public MessageHandler { 83 public: 84 WeakMessageHandler(const wp<MessageHandler>& handler); 85 virtual void handleMessage(const Message& message); 86 87 private: 88 wp<MessageHandler> mHandler; 89 }; 90 91 92 /** 93 * A polling loop that supports monitoring file descriptor events, optionally 94 * using callbacks. The implementation uses epoll() internally. 95 * 96 * A looper can be associated with a thread although there is no requirement that it must be. 97 */ 98 class Looper : public ALooper, public RefBase { 99 protected: 100 virtual ~Looper(); 101 102 public: 103 /** 104 * Creates a looper. 105 * 106 * If allowNonCallbaks is true, the looper will allow file descriptors to be 107 * registered without associated callbacks. This assumes that the caller of 108 * pollOnce() is prepared to handle callback-less events itself. 109 */ 110 Looper(bool allowNonCallbacks); 111 112 /** 113 * Returns whether this looper instance allows the registration of file descriptors 114 * using identifiers instead of callbacks. 115 */ 116 bool getAllowNonCallbacks() const; 117 118 /** 119 * Waits for events to be available, with optional timeout in milliseconds. 120 * Invokes callbacks for all file descriptors on which an event occurred. 121 * 122 * If the timeout is zero, returns immediately without blocking. 123 * If the timeout is negative, waits indefinitely until an event appears. 124 * 125 * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before 126 * the timeout expired and no callbacks were invoked and no other file 127 * descriptors were ready. 128 * 129 * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. 130 * 131 * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given 132 * timeout expired. 133 * 134 * Returns ALOOPER_POLL_ERROR if an error occurred. 135 * 136 * Returns a value >= 0 containing an identifier if its file descriptor has data 137 * and it has no callback function (requiring the caller here to handle it). 138 * In this (and only this) case outFd, outEvents and outData will contain the poll 139 * events and data associated with the fd, otherwise they will be set to NULL. 140 * 141 * This method does not return until it has finished invoking the appropriate callbacks 142 * for all file descriptors that were signalled. 143 */ 144 int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); 145 inline int pollOnce(int timeoutMillis) { 146 return pollOnce(timeoutMillis, NULL, NULL, NULL); 147 } 148 149 /** 150 * Like pollOnce(), but performs all pending callbacks until all 151 * data has been consumed or a file descriptor is available with no callback. 152 * This function will never return ALOOPER_POLL_CALLBACK. 153 */ 154 int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); 155 inline int pollAll(int timeoutMillis) { 156 return pollAll(timeoutMillis, NULL, NULL, NULL); 157 } 158 159 /** 160 * Wakes the poll asynchronously. 161 * 162 * This method can be called on any thread. 163 * This method returns immediately. 164 */ 165 void wake(); 166 167 /** 168 * Adds a new file descriptor to be polled by the looper. 169 * If the same file descriptor was previously added, it is replaced. 170 * 171 * "fd" is the file descriptor to be added. 172 * "ident" is an identifier for this event, which is returned from ALooper_pollOnce(). 173 * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback. 174 * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT. 175 * "callback" is the function to call when there is an event on the file descriptor. 176 * "data" is a private data pointer to supply to the callback. 177 * 178 * There are two main uses of this function: 179 * 180 * (1) If "callback" is non-NULL, then this function will be called when there is 181 * data on the file descriptor. It should execute any events it has pending, 182 * appropriately reading from the file descriptor. The 'ident' is ignored in this case. 183 * 184 * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce 185 * when its file descriptor has data available, requiring the caller to take 186 * care of processing it. 187 * 188 * Returns 1 if the file descriptor was added, 0 if the arguments were invalid. 189 * 190 * This method can be called on any thread. 191 * This method may block briefly if it needs to wake the poll. 192 */ 193 int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data); 194 195 /** 196 * Removes a previously added file descriptor from the looper. 197 * 198 * When this method returns, it is safe to close the file descriptor since the looper 199 * will no longer have a reference to it. However, it is possible for the callback to 200 * already be running or for it to run one last time if the file descriptor was already 201 * signalled. Calling code is responsible for ensuring that this case is safely handled. 202 * For example, if the callback takes care of removing itself during its own execution either 203 * by returning 0 or by calling this method, then it can be guaranteed to not be invoked 204 * again at any later time unless registered anew. 205 * 206 * Returns 1 if the file descriptor was removed, 0 if none was previously registered. 207 * 208 * This method can be called on any thread. 209 * This method may block briefly if it needs to wake the poll. 210 */ 211 int removeFd(int fd); 212 213 /** 214 * Enqueues a message to be processed by the specified handler. 215 * 216 * The handler must not be null. 217 * This method can be called on any thread. 218 */ 219 void sendMessage(const sp<MessageHandler>& handler, const Message& message); 220 221 /** 222 * Enqueues a message to be processed by the specified handler after all pending messages 223 * after the specified delay. 224 * 225 * The time delay is specified in uptime nanoseconds. 226 * The handler must not be null. 227 * This method can be called on any thread. 228 */ 229 void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 230 const Message& message); 231 232 /** 233 * Enqueues a message to be processed by the specified handler after all pending messages 234 * at the specified time. 235 * 236 * The time is specified in uptime nanoseconds. 237 * The handler must not be null. 238 * This method can be called on any thread. 239 */ 240 void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 241 const Message& message); 242 243 /** 244 * Removes all messages for the specified handler from the queue. 245 * 246 * The handler must not be null. 247 * This method can be called on any thread. 248 */ 249 void removeMessages(const sp<MessageHandler>& handler); 250 251 /** 252 * Removes all messages of a particular type for the specified handler from the queue. 253 * 254 * The handler must not be null. 255 * This method can be called on any thread. 256 */ 257 void removeMessages(const sp<MessageHandler>& handler, int what); 258 259 /** 260 * Prepares a looper associated with the calling thread, and returns it. 261 * If the thread already has a looper, it is returned. Otherwise, a new 262 * one is created, associated with the thread, and returned. 263 * 264 * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0. 265 */ 266 static sp<Looper> prepare(int opts); 267 268 /** 269 * Sets the given looper to be associated with the calling thread. 270 * If another looper is already associated with the thread, it is replaced. 271 * 272 * If "looper" is NULL, removes the currently associated looper. 273 */ 274 static void setForThread(const sp<Looper>& looper); 275 276 /** 277 * Returns the looper associated with the calling thread, or NULL if 278 * there is not one. 279 */ 280 static sp<Looper> getForThread(); 281 282 private: 283 struct Request { 284 int fd; 285 int ident; 286 ALooper_callbackFunc callback; 287 void* data; 288 }; 289 290 struct Response { 291 int events; 292 Request request; 293 }; 294 295 struct MessageEnvelope { 296 MessageEnvelope() : uptime(0) { } 297 298 MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler, 299 const Message& message) : uptime(uptime), handler(handler), message(message) { 300 } 301 302 nsecs_t uptime; 303 sp<MessageHandler> handler; 304 Message message; 305 }; 306 307 const bool mAllowNonCallbacks; // immutable 308 309 int mWakeReadPipeFd; // immutable 310 int mWakeWritePipeFd; // immutable 311 Mutex mLock; 312 313 Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock 314 bool mSendingMessage; // guarded by mLock 315 316 #ifdef LOOPER_USES_EPOLL 317 int mEpollFd; // immutable 318 319 // Locked list of file descriptor monitoring requests. 320 KeyedVector<int, Request> mRequests; // guarded by mLock 321 #else 322 // The lock guards state used to track whether there is a poll() in progress and whether 323 // there are any other threads waiting in wakeAndLock(). The condition variables 324 // are used to transfer control among these threads such that all waiters are 325 // serviced before a new poll can begin. 326 // The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake 327 // until mPolling becomes false, then decrements mWaiters again. 328 // The poll() method blocks on mResume until mWaiters becomes 0, then sets 329 // mPolling to true, blocks until the poll completes, then resets mPolling to false 330 // and signals mResume if there are waiters. 331 bool mPolling; // guarded by mLock 332 uint32_t mWaiters; // guarded by mLock 333 Condition mAwake; // guarded by mLock 334 Condition mResume; // guarded by mLock 335 336 Vector<struct pollfd> mRequestedFds; // must hold mLock and mPolling must be false to modify 337 Vector<Request> mRequests; // must hold mLock and mPolling must be false to modify 338 339 ssize_t getRequestIndexLocked(int fd); 340 void wakeAndLock(); 341 #endif 342 343 #ifdef LOOPER_STATISTICS 344 static const int SAMPLED_WAKE_CYCLES_TO_AGGREGATE = 100; 345 static const int SAMPLED_POLLS_TO_AGGREGATE = 1000; 346 347 nsecs_t mPendingWakeTime; 348 int mPendingWakeCount; 349 350 int mSampledWakeCycles; 351 int mSampledWakeCountSum; 352 nsecs_t mSampledWakeLatencySum; 353 354 int mSampledPolls; 355 int mSampledZeroPollCount; 356 int mSampledZeroPollLatencySum; 357 int mSampledTimeoutPollCount; 358 int mSampledTimeoutPollLatencySum; 359 #endif 360 361 // This state is only used privately by pollOnce and does not require a lock since 362 // it runs on a single thread. 363 Vector<Response> mResponses; 364 size_t mResponseIndex; 365 nsecs_t mNextMessageUptime; // set to LLONG_MAX when none 366 367 int pollInner(int timeoutMillis); 368 void awoken(); 369 void pushResponse(int events, const Request& request); 370 371 static void initTLSKey(); 372 static void threadDestructor(void *st); 373 }; 374 375 } // namespace android 376 377 #endif // UTILS_LOOPER_H 378