| // 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/task.h> |
| #include <async/wait.h> |
| |
| #ifdef __cplusplus |
| |
| #include <fbl/function.h> |
| #include <fbl/macros.h> |
| |
| namespace async { |
| |
| // C++ wrapper for a pending wait operation with an associated timeout. |
| // |
| // Use |ZX_TIME_INFINITE| as the deadline to wait indefinitely. |
| // |
| // This class is NOT thread-safe; it can only be used with single-threaded |
| // asynchronous dispatchers. |
| // |
| // Implementation note: The task's flags are managed internally by this object |
| // so they are not exposed to the client unlike the wait flags. |
| class WaitWithTimeout final : private async_wait_t, private async_task_t { |
| public: |
| // Handles completion of asynchronous wait operations or a timeout. |
| // |
| // Reports the |status| of the wait. If the status is |ZX_OK| then |signal| |
| // describes the signal which was received, otherwise |signal| is null. |
| // |
| // Timeouts are indicated with status |ZX_ERR_TIMED_OUT|. |
| // |
| // 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 with timeout operation. |
| explicit WaitWithTimeout(zx_handle_t object = ZX_HANDLE_INVALID, |
| zx_signals_t trigger = ZX_SIGNAL_NONE, |
| zx_time_t deadline = ZX_TIME_INFINITE, |
| uint32_t flags = 0u); |
| |
| // Destroys the wait with timeout operation. |
| // |
| // This object must not be destroyed until the wait has completed, been |
| // successfully canceled, timed out, or the asynchronous dispatcher itself |
| // has been destroyed. |
| ~WaitWithTimeout(); |
| |
| // 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; } |
| |
| // The time when the timeout should occur. |
| zx_time_t deadline() const { return async_task_t::deadline; } |
| void set_deadline(zx_time_t deadline) { async_task_t::deadline = deadline; } |
| |
| // 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 or for the timeout deadline to elapse. |
| // |
| // See |async_begin_wait()| for details. |
| zx_status_t Begin(async_t* async); |
| |
| // Cancels the wait and its associated timeout. |
| // |
| // See |async_cancel_wait()| for details. |
| zx_status_t Cancel(async_t* async); |
| |
| private: |
| static async_wait_result_t WaitHandler(async_t* async, async_wait_t* wait, |
| zx_status_t status, |
| const zx_packet_signal_t* signal); |
| static async_task_result_t TimeoutHandler(async_t* async, async_task_t* task, |
| zx_status_t status); |
| |
| Handler handler_; |
| |
| DISALLOW_COPY_ASSIGN_AND_MOVE(WaitWithTimeout); |
| }; |
| |
| } // namespace async |
| |
| #endif // __cplusplus |