// 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.

#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <lib/zx/timer.h>

#include <dispatcher-pool/dispatcher-execution-domain.h>
#include <dispatcher-pool/dispatcher-wakeup-event.h>

#include <utility>

namespace dispatcher {

// static
fbl::RefPtr<WakeupEvent> WakeupEvent::Create() {
    fbl::AllocChecker ac;

    auto ptr = new (&ac) WakeupEvent();
    if (!ac.check())
        return nullptr;

    return fbl::AdoptRef(ptr);
}

zx_status_t WakeupEvent::Activate(fbl::RefPtr<ExecutionDomain> domain,
                                  ProcessHandler process_handler) {
    if (process_handler == nullptr)
        return ZX_ERR_INVALID_ARGS;

    fbl::AutoLock obj_lock(&obj_lock_);
    zx::event event;
    zx_status_t res = zx::event::create(0, &event);
    if (res != ZX_OK)
        return res;

    res = ActivateLocked(std::move(event), std::move(domain));
    if (res != ZX_OK)
        return res;

    res = WaitOnPortLocked();
    if (res != ZX_OK) {
        InternalDeactivateLocked();
        return res;
    }

    process_handler_ = std::move(process_handler);

    return ZX_OK;
}

void WakeupEvent::Deactivate() {
    ProcessHandler old_process_handler;

    {
        fbl::AutoLock obj_lock(&obj_lock_);
        InternalDeactivateLocked();

        // If we were previously signalled, we are not any more.
        signaled_ = false;

        // If we are in the process of actively dispatching, do not discard our
        // handler just yet.  It is currently being used by the dispatch thread.
        // Instead, wait until the dispatch thread unwinds and allow it to clean
        // up the handler.
        //
        // Otherwise, transfer the handler state into local storage and let it
        // destruct after we have released the object lock.
        if (dispatch_state() != DispatchState::Dispatching) {
            ZX_DEBUG_ASSERT((dispatch_state() == DispatchState::Idle) ||
                            (dispatch_state() == DispatchState::WaitingOnPort));
            old_process_handler = std::move(process_handler_);
        }
    }
}

zx_status_t WakeupEvent::Signal() {
    fbl::AutoLock obj_lock(&obj_lock_);


    // If we are no longer active, we cannot signal the event.
    if (!is_active())
        return ZX_ERR_BAD_HANDLE;

    // If we are still active, then our handle had better be valid.
    ZX_DEBUG_ASSERT(handle_.is_valid());

    // Update our internal bookkeeping.
    signaled_ = true;

    // If we have already fired and are in the process of dispatching, don't
    // bother to actually signal the event at the kernel level.
    if ((dispatch_state() == DispatchState::DispatchPending) ||
        (dispatch_state() == DispatchState::Dispatching)) {
        return ZX_OK;
    }

    zx_status_t res = zx_object_signal(handle_.get(), 0u, ZX_USER_SIGNAL_0);
    ZX_DEBUG_ASSERT(res == ZX_OK);  // I cannot think of any reason that this should ever fail.

    return res;
}

void WakeupEvent::Dispatch(ExecutionDomain* domain) {
    ZX_DEBUG_ASSERT(domain != nullptr);
    ZX_DEBUG_ASSERT(process_handler_ != nullptr);

    {
        // Clear the signalled flag.  Someone might signal us again during the
        // dispatch operation.
        fbl::AutoLock obj_lock(&obj_lock_);
        ZX_DEBUG_ASSERT(dispatch_state() == DispatchState::Dispatching);
        signaled_ = false;
    }

    zx_status_t res = process_handler_(this);
    ProcessHandler old_process_handler;
    {
        fbl::AutoLock obj_lock(&obj_lock_);
        ZX_DEBUG_ASSERT(dispatch_state() == DispatchState::Dispatching);
        dispatch_state_ = DispatchState::Idle;

        // Was there a problem during processing?  If so, make sure that we
        // de-activate ourselves.
        if (res != ZX_OK) {
            InternalDeactivateLocked();
        }

        // Are we still active?  If so, either setup the next port wait
        // operation, or re-queue ourselves if we were signalled during the
        // dispatch operation.
        if (is_active()) {
            if (signaled_) {
                dispatch_state_ = DispatchState::WaitingOnPort;
                res = domain->AddPendingWork(this);
            } else {
                res = zx_object_signal(handle_.get(), ZX_USER_SIGNAL_0, 0u);
                if (res == ZX_OK)
                    res = WaitOnPortLocked();
            }

            if (res != ZX_OK) {
                dispatch_state_ = DispatchState::Idle;
                InternalDeactivateLocked();
            }
        }

        // Have we become deactivated (either during dispatching or just now)?
        // If so, move our process handler state outside of our lock so that it
        // can safely destruct.
        if (!is_active()) {
            old_process_handler = std::move(process_handler_);
        }
    }
}

}  // namespace dispatcher
