// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <async/dispatcher.h>

__BEGIN_CDECLS

// Return codes for |async_wait_handler_t|.
typedef enum {
    // The handler has finished waiting; it may immediately destroy or
    // reuse the associated wait context for another purpose.
    ASYNC_WAIT_FINISHED = 0,
    // The handler is requesting for the wait to be reiussed upon return;
    // it may modify the wait's properties before returning.
    ASYNC_WAIT_AGAIN = 1,
} async_wait_result_t;

// Handles completion of asynchronous wait operations.
//
// Reports the |status| of the wait.  If the status is |ZX_OK| then |signal|
// describes the signal which was received, otherwise |signal| is null.
//
// The result indicates whether the wait should be repeated; it may
// modify the wait's properties (such as the trigger) before returning.
//
// The result must be |ASYNC_WAIT_FINISHED| if |status| was not |ZX_OK|.
//
// It is safe for the handler to destroy itself when returning |ASYNC_WAIT_FINISHED|.
typedef async_wait_result_t(async_wait_handler_t)(async_t* async,
                                                  async_wait_t* wait,
                                                  zx_status_t status,
                                                  const zx_packet_signal_t* signal);

// Context for an asynchronous wait operation.
// A separate instance must be used for each wait.
//
// It is customary to aggregate (in C) or subclass (in C++) this structure
// to allow the wait context to retain additional state for its handler.
//
// See also |async::Task|.
typedef struct async_wait async_wait_t;
struct async_wait {
    // Private state owned by the dispatcher, initialize to zero with |ASYNC_STATE_INIT|.
    async_state_t state;
    // The handler to invoke on completion of the wait.
    async_wait_handler_t* handler;
    // The object to wait for signals on.
    zx_handle_t object;
    // The set of signals to wait for.
    zx_signals_t trigger;
    // Valid flags: |ASYNC_FLAG_HANDLE_SHUTDOWN|.
    uint32_t flags;
    // Reserved for future use, set to zero.
    uint32_t reserved;
};

// Begins asynchronously waiting for an object to receive one or more signals
// specified in |wait|.  Invokes the handler when the wait completes.
//
// The client is responsible for allocating and retaining the wait context
// until the handler runs or the wait is successfully canceled using
// `async_cancel_wait()`.
//
// When the dispatcher is shutting down (being destroyed), attempting to
// begin new waits will fail but previously begun waits can still be canceled
// successfully.
//
// Returns |ZX_OK| if the wait has been successfully started.
// Returns |ZX_ERR_BAD_STATE| if the dispatcher shut down.
// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
//
// See |zx_object_wait_async()|.
inline zx_status_t async_begin_wait(async_t* async, async_wait_t* wait) {
    return async->ops->begin_wait(async, wait);
}

// Cancels the wait associated with |wait|.
//
// When the dispatcher is shutting down (being destroyed), attempting to
// begin new waits will fail but previously begun waits can still be canceled
// successfully.
//
// Returns |ZX_OK| if there was a pending wait and it has been successfully
// canceled; its handler will not run again and can be released immediately.
// Returns |ZX_ERR_NOT_FOUND| if there was no pending wait either because it
// already completed, had not been started, or its completion packet has been
// dequeued and is pending delivery to its handler (perhaps on another thread).
// Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
//
// See |zx_port_cancel()|.
inline zx_status_t async_cancel_wait(async_t* async, async_wait_t* wait) {
    return async->ops->cancel_wait(async, wait);
}

__END_CDECLS

#ifdef __cplusplus

#include <fbl/function.h>
#include <fbl/macros.h>

namespace async {

// C++ wrapper for a pending wait operation.
//
// This class is thread-safe.
class Wait final : private async_wait_t {
public:
    // Handles completion of asynchronous wait operations.
    //
    // Reports the |status| of the wait.  If the status is |ZX_OK| then |signal|
    // describes the signal which was received, otherwise |signal| is null.
    //
    // The result indicates whether the wait should be repeated; it may
    // modify the wait's properties (such as the trigger) before returning.
    //
    // The result must be |ASYNC_WAIT_FINISHED| if |status| was not |ZX_OK|.
    //
    // It is safe for the handler to destroy itself when returning |ASYNC_WAIT_FINISHED|.
    using Handler = fbl::Function<async_wait_result_t(async_t* async,
                                                      zx_status_t status,
                                                      const zx_packet_signal_t* signal)>;

    // Initializes the properties of the wait operation.
    explicit Wait(zx_handle_t object = ZX_HANDLE_INVALID,
                  zx_signals_t trigger = ZX_SIGNAL_NONE, uint32_t flags = 0u);

    // Destroys the wait operation.
    //
    // This object must not be destroyed until the wait has completed, been
    // successfully canceled, or the asynchronous dispatcher itself has
    // been destroyed.
    ~Wait();

    // Gets or sets the handler to invoke when the wait completes.
    // Must be set before beginning the wait.
    const Handler& handler() const { return handler_; }
    void set_handler(Handler handler) { handler_ = fbl::move(handler); }

    // The object to wait for signals on.
    zx_handle_t object() const { return async_wait_t::object; }
    void set_object(zx_handle_t object) { async_wait_t::object = object; }

    // The set of signals to wait for.
    zx_signals_t trigger() const { return async_wait_t::trigger; }
    void set_trigger(zx_signals_t trigger) { async_wait_t::trigger = trigger; }

    // Valid flags: |ASYNC_FLAG_HANDLE_SHUTDOWN|.
    uint32_t flags() const { return async_wait_t::flags; }
    void set_flags(uint32_t flags) { async_wait_t::flags = flags; }

    // Begins asynchronously waiting for the object to receive one or more of
    // the trigger signals.
    //
    // See |async_begin_wait()| for details.
    zx_status_t Begin(async_t* async);

    // Cancels the wait.
    //
    // See |async_cancel_wait()| for details.
    zx_status_t Cancel(async_t* async);

private:
    static async_wait_result_t CallHandler(async_t* async, async_wait_t* wait,
                                           zx_status_t status, const zx_packet_signal_t* signal);

    Handler handler_;

    DISALLOW_COPY_ASSIGN_AND_MOVE(Wait);
};

} // namespace async

#endif // __cplusplus
