/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef UTILS_POLL_LOOP_H
#define UTILS_POLL_LOOP_H

#include <utils/Vector.h>
#include <utils/threads.h>

#include <sys/poll.h>

#include <android/looper.h>

struct ALooper : public android::RefBase {
protected:
    virtual ~ALooper() { }

public:
    ALooper() { }
};

namespace android {

/**
 * A basic file descriptor polling loop based on poll() with callbacks.
 */
class PollLoop : public ALooper {
protected:
    virtual ~PollLoop();

public:
    PollLoop(bool allowNonCallbacks);

    /**
     * A callback that it to be invoked when an event occurs on a file descriptor.
     * Specifies the events that were triggered and the user data provided when the
     * callback was set.
     *
     * Returns true if the callback should be kept, false if it should be removed automatically
     * after the callback returns.
     */
    typedef bool (*Callback)(int fd, int events, void* data);

    enum {
        POLL_CALLBACK = ALOOPER_POLL_CALLBACK,
        POLL_TIMEOUT = ALOOPER_POLL_TIMEOUT,
        POLL_ERROR = ALOOPER_POLL_ERROR,
    };
    
    /**
     * Performs a single call to poll() with optional timeout in milliseconds.
     * Invokes callbacks for all file descriptors on which an event occurred.
     *
     * If the timeout is zero, returns immediately without blocking.
     * If the timeout is negative, waits indefinitely until awoken.
     *
     * Returns ALOOPER_POLL_CALLBACK if a callback was invoked.
     *
     * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
     * timeout expired.
     *
     * Returns ALOPER_POLL_ERROR if an error occurred.
     *
     * Returns a value >= 0 containing a file descriptor if it has data
     * and it has no callback function (requiring the caller here to handle it).
     * In this (and only this) case outEvents and outData will contain the poll
     * events and data associated with the fd.
     *
     * This method must only be called on the thread owning the PollLoop.
     * This method blocks until either a file descriptor is signalled, a timeout occurs,
     * or wake() is called.
     * This method does not return until it has finished invoking the appropriate callbacks
     * for all file descriptors that were signalled.
     */
    int32_t pollOnce(int timeoutMillis, int* outEvents = NULL, void** outData = NULL);

    /**
     * Wakes the loop asynchronously.
     *
     * This method can be called on any thread.
     * This method returns immediately.
     */
    void wake();

    /**
     * Control whether this PollLoop instance allows using IDs instead
     * of callbacks.
     */
    bool getAllowNonCallbacks() const;
    
    /**
     * Sets the callback for a file descriptor, replacing the existing one, if any.
     * It is an error to call this method with events == 0 or callback == NULL.
     *
     * Note that a callback can be invoked with the POLLERR, POLLHUP or POLLNVAL events
     * even if it is not explicitly requested when registered.
     *
     * This method can be called on any thread.
     * This method may block briefly if it needs to wake the poll loop.
     */
    void setCallback(int fd, int ident, int events, Callback callback, void* data = NULL);

    /**
     * Convenience for above setCallback when ident is not used.  In this case
     * the ident is set to POLL_CALLBACK.
     */
    void setCallback(int fd, int events, Callback callback, void* data = NULL);
    
    /**
     * Like setCallback(), but for the NDK callback function.
     */
    void setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
            void* data);
    
    /**
     * Removes the callback for a file descriptor, if one exists.
     *
     * When this method returns, it is safe to close the file descriptor since the poll loop
     * will no longer have a reference to it.  However, it is possible for the callback to
     * already be running or for it to run one last time if the file descriptor was already
     * signalled.  Calling code is responsible for ensuring that this case is safely handled.
     * For example, if the callback takes care of removing itself during its own execution either
     * by returning false or calling this method, then it can be guaranteed to not be invoked
     * again at any later time unless registered anew.
     *
     * This method can be called on any thread.
     * This method may block briefly if it needs to wake the poll loop.
     *
     * Returns true if a callback was actually removed, false if none was registered.
     */
    bool removeCallback(int fd);

    /**
     * Set the given PollLoop to be associated with the
     * calling thread.  There must be a 1:1 relationship between
     * PollLoop and thread.
     */
    static void setForThread(const sp<PollLoop>& pollLoop);
    
    /**
     * Return the PollLoop associated with the calling thread.
     */
    static sp<PollLoop> getForThread();
    
private:
    struct RequestedCallback {
        Callback callback;
        ALooper_callbackFunc* looperCallback;
        int ident;
        void* data;
    };

    struct PendingCallback {
        int fd;
        int ident;
        int events;
        Callback callback;
        ALooper_callbackFunc* looperCallback;
        void* data;
    };
    
    const bool mAllowNonCallbacks;
    
    Mutex mLock;
    bool mPolling;
    uint32_t mWaiters;
    Condition mAwake;
    Condition mResume;

    int mWakeReadPipeFd;
    int mWakeWritePipeFd;

    Vector<struct pollfd> mRequestedFds;
    Vector<RequestedCallback> mRequestedCallbacks;

    Vector<PendingCallback> mPendingCallbacks; // used privately by pollOnce
    Vector<PendingCallback> mPendingFds;       // used privately by pollOnce
    size_t mPendingFdsPos;
    
    void openWakePipe();
    void closeWakePipe();

    void setCallbackCommon(int fd, int ident, int events, Callback callback,
            ALooper_callbackFunc* looperCallback, void* data);
    ssize_t getRequestIndexLocked(int fd);
    void wakeAndLock();
    static void threadDestructor(void *st);
};

} // namespace android

#endif // UTILS_POLL_LOOP_H
