| // Copyright 2014 The Android Open Source Project |
| // |
| // This software is licensed under the terms of the GNU General Public |
| // License version 2, as published by the Free Software Foundation, and |
| // may be copied, distributed, and modified under those terms. |
| // |
| // This program is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| #pragma once |
| |
| #include <android/base/Compiler.h> |
| #include <android/base/files/Stream.h> |
| |
| #include <inttypes.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| namespace android { |
| namespace base { |
| |
| // A Looper is an abstraction for an event loop that can wait for either |
| // I/O events on file descriptors, or timers. |
| // |
| // One can call Looper::create() to create a new instance, create |
| // Looper::Timer and Looper::FdWatch instances, then call Looper::run() |
| // to run the loop until there is nothing more to do. |
| // |
| // It's possible to stop a Looper from running by calling |
| // Looper::forceQuit() from within the event loop. |
| // |
| class Looper { |
| public: |
| typedef int64_t Duration; |
| typedef uint64_t DurationNs; |
| |
| enum { |
| kDurationInfinite = INT64_MAX, |
| }; |
| |
| // ClockTypes have to mimic the LooperClockType enum from utils/ |
| enum class ClockType { |
| kRealtime, |
| kVirtual, |
| kHost |
| }; |
| |
| static const char* clockTypeToString(ClockType clock); |
| |
| // Create a new generic Looper instance. |
| static Looper* create(); |
| |
| virtual ~Looper(); |
| |
| // Return the current time as seen by this looper instance in |
| // milliseconds and nanoseconds. |
| virtual Duration nowMs(ClockType clockType = ClockType::kHost) = 0; |
| virtual DurationNs nowNs(ClockType clockType = ClockType::kHost) = 0; |
| |
| // Run the event loop until forceQuit() is called or there is no |
| // more registered watchers or timers in the looper. |
| void run(); |
| |
| // A variant of run() that allows to run the event loop only until |
| // a fixed deadline has passed. |deadlineMs| is a deadline in |
| // milliseconds relative to the current clock used by nowMs(). |
| // If can be kDurationInfinite to indicate no deadline. |
| // Return the reason why the looper stopped: |
| // 0 -> normal exit through forceQuit() |
| // EWOULDBLOCK -> no more watchers and timers registered. |
| // ETIMEOUT -> timeout reached. |
| virtual int runWithDeadlineMs(Duration deadlineMs) = 0; |
| |
| // A variant of run() that allows to run the event loop only until |
| // a certain timeout is milliseconds has passed. Return the reason |
| // why the looper stopped: |
| // 0 -> normal exit through forceQuit() |
| // EWOULDBLOCK -> no more watchers and timers registered. |
| // ETIMEOUT -> timeout reached. |
| int runWithTimeoutMs(Duration timeoutMs); |
| |
| // Call this function from within the event loop to force it to quit |
| // as soon as possible. runWithDeadlineMS() and runWithTimeoutMs() will |
| // return 0. |
| virtual void forceQuit() = 0; |
| |
| // Interface class for timers implemented by a Looper instance. |
| // Use createTimer() to create these. |
| class Timer { |
| public: |
| // Type of callback function called when the timer expires. |
| typedef void (*Callback)(void* opaque, Timer* timer); |
| |
| virtual ~Timer(); |
| |
| // Get the parent looper object |
| Looper* parentLooper() const; |
| |
| // Start, or restart the timer to expire after |timeout_ms| |
| // milliseconds. |
| virtual void startRelative(Duration timeout_ms) = 0; |
| |
| // Start, or restart the timer to expire at |deadline_ms| |
| // milliseconds. |
| virtual void startAbsolute(Duration deadline_ms) = 0; |
| |
| // Stop the timer. |
| virtual void stop() = 0; |
| |
| // Returns true iff this timer is active. |
| virtual bool isActive() const = 0; |
| |
| // Serialization to/from streams |
| virtual void save(android::base::Stream* stream) const = 0; |
| virtual void load(android::base::Stream* stream) = 0; |
| |
| protected: |
| Timer(Looper* looper, Callback callback, void* opaque, |
| ClockType clock); |
| |
| Looper* mLooper; |
| Callback mCallback; |
| void* mOpaque; |
| ClockType mClockType; |
| }; |
| |
| // Create a new timer for this Looper instance. |
| virtual Timer* createTimer(Timer::Callback callback, void* opaque, |
| ClockType clock = ClockType::kHost) = 0; |
| |
| // Interface class for I/O event watchers on a given file descriptor |
| // implemented by this Looper instance. |
| class FdWatch { |
| public: |
| enum { |
| kEventRead = (1 << 0), |
| kEventWrite = (1 << 1), |
| |
| kEventMask = (kEventRead | kEventWrite), |
| }; |
| |
| // Type of function called when an I/O event occurs. |
| // |opaque| is the opaque pointer passed at creation. |
| // |fd| is the file descriptor. |
| // |events| is an event bitmask. |
| typedef void (*Callback)(void* opaque, int fd, unsigned events); |
| |
| virtual ~FdWatch(); |
| |
| virtual void addEvents(unsigned events) = 0; |
| |
| virtual void removeEvents(unsigned events) = 0; |
| |
| inline void wantRead() { |
| addEvents(FdWatch::kEventRead); |
| } |
| inline void wantWrite() { |
| addEvents(FdWatch::kEventWrite); |
| } |
| inline void dontWantRead() { |
| removeEvents(FdWatch::kEventRead); |
| } |
| inline void dontWantWrite() { |
| removeEvents(FdWatch::kEventWrite); |
| } |
| |
| virtual unsigned poll() const = 0; |
| |
| int fd() const; |
| |
| protected: |
| FdWatch(Looper* looper, int fd, Callback callback, void* opaque); |
| |
| Looper* mLooper; |
| int mFd; |
| Callback mCallback; |
| void* mOpaque; |
| }; |
| |
| // Create a new FdWatch instance from this looper. |
| virtual FdWatch* createFdWatch(int fd, |
| FdWatch::Callback callback, |
| void* opaque) = 0; |
| |
| protected: |
| // Default constructor is protected. Use create() method to create |
| // new generic Looper instances. |
| Looper(); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(Looper); |
| }; |
| |
| } // namespace base |
| } // namespace android |