blob: 2ec39fe5000838ae891df3136926237bb263a61f [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001/*
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_POLL_LOOP_H
18#define UTILS_POLL_LOOP_H
19
20#include <utils/Vector.h>
21#include <utils/threads.h>
22
23#include <poll.h>
24
25namespace android {
26
27/**
28 * A basic file descriptor polling loop based on poll() with callbacks.
29 */
30class PollLoop : public RefBase {
31protected:
32 virtual ~PollLoop();
33
34public:
35 PollLoop();
36
37 /**
38 * A callback that it to be invoked when an event occurs on a file descriptor.
39 * Specifies the events that were triggered and the user data provided when the
40 * callback was set.
41 *
42 * Returns true if the callback should be kept, false if it should be removed automatically
43 * after the callback returns.
44 */
45 typedef bool (*Callback)(int fd, int events, void* data);
46
47 /**
48 * Performs a single call to poll() with optional timeout in milliseconds.
49 * Invokes callbacks for all file descriptors on which an event occurred.
50 *
51 * If the timeout is zero, returns immediately without blocking.
52 * If the timeout is negative, waits indefinitely until awoken.
53 *
54 * Returns true if a callback was invoked or if the loop was awoken by wake().
55 * Returns false if a timeout or error occurred.
56 *
57 * This method must only be called on the main thread.
58 * This method blocks until either a file descriptor is signalled, a timeout occurs,
59 * or wake() is called.
60 * This method does not return until it has finished invoking the appropriate callbacks
61 * for all file descriptors that were signalled.
62 */
63 bool pollOnce(int timeoutMillis);
64
65 /**
66 * Wakes the loop asynchronously.
67 *
68 * This method can be called on any thread.
69 * This method returns immediately.
70 */
71 void wake();
72
73 /**
74 * Sets the callback for a file descriptor, replacing the existing one, if any.
75 * It is an error to call this method with events == 0 or callback == NULL.
76 *
77 * Note that a callback can be invoked with the POLLERR, POLLHUP or POLLNVAL events
78 * even if it is not explicitly requested when registered.
79 *
80 * This method can be called on any thread.
81 * This method may block briefly if it needs to wake the poll loop.
82 */
83 void setCallback(int fd, int events, Callback callback, void* data = NULL);
84
85 /**
86 * Removes the callback for a file descriptor, if one exists.
87 *
88 * When this method returns, it is safe to close the file descriptor since the poll loop
89 * will no longer have a reference to it. However, it is possible for the callback to
90 * already be running or for it to run one last time if the file descriptor was already
91 * signalled. Calling code is responsible for ensuring that this case is safely handled.
92 * For example, if the callback takes care of removing itself during its own execution either
93 * by returning false or calling this method, then it can be guaranteed to not be invoked
94 * again at any later time unless registered anew.
95 *
96 * This method can be called on any thread.
97 * This method may block briefly if it needs to wake the poll loop.
98 *
99 * Returns true if a callback was actually removed, false if none was registered.
100 */
101 bool removeCallback(int fd);
102
103private:
104 struct RequestedCallback {
105 Callback callback;
106 void* data;
107 };
108
109 struct PendingCallback {
110 int fd;
111 int events;
112 Callback callback;
113 void* data;
114 };
115
116 Mutex mLock;
117 Condition mAwake;
118 bool mPolling;
119
120 int mWakeReadPipeFd;
121 int mWakeWritePipeFd;
122
123 Vector<struct pollfd> mRequestedFds;
124 Vector<RequestedCallback> mRequestedCallbacks;
125
126 Vector<PendingCallback> mPendingCallbacks; // used privately by pollOnce
127
128 void openWakePipe();
129 void closeWakePipe();
130
131 ssize_t getRequestIndexLocked(int fd);
132 void wakeAndLock();
133};
134
135} // namespace android
136
137#endif // UTILS_POLL_LOOP_H