// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <object/event_pair_dispatcher.h>

#include <assert.h>
#include <err.h>

#include <zircon/rights.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_lock.h>

constexpr uint32_t kUserSignalMask = ZX_EVENT_SIGNALED | ZX_USER_SIGNAL_ALL;

zx_status_t EventPairDispatcher::Create(fbl::RefPtr<Dispatcher>* dispatcher0,
                                        fbl::RefPtr<Dispatcher>* dispatcher1,
                                        zx_rights_t* rights) {
    fbl::AllocChecker ac;
    auto holder0 = fbl::AdoptRef(new (&ac) PeerHolder<EventPairDispatcher>());
    if (!ac.check())
        return ZX_ERR_NO_MEMORY;
    auto holder1 = holder0;

    auto disp0 = fbl::AdoptRef(new (&ac) EventPairDispatcher(fbl::move(holder0)));
    if (!ac.check())
        return ZX_ERR_NO_MEMORY;

    auto disp1 = fbl::AdoptRef(new (&ac) EventPairDispatcher(fbl::move(holder1)));
    if (!ac.check())
        return ZX_ERR_NO_MEMORY;

    disp0->Init(disp1);
    disp1->Init(disp0);

    *rights = ZX_DEFAULT_EVENT_PAIR_RIGHTS;
    *dispatcher0 = fbl::move(disp0);
    *dispatcher1 = fbl::move(disp1);

    return ZX_OK;
}

EventPairDispatcher::~EventPairDispatcher() {}

void EventPairDispatcher::on_zero_handles()
    TA_NO_THREAD_SAFETY_ANALYSIS {
    canary_.Assert();

    fbl::AutoLock locker(get_lock());
    DEBUG_ASSERT(peer_);

    peer_->InvalidateCookieLocked(peer_->get_cookie_jar());
    peer_->UpdateStateLocked(0u, ZX_EPAIR_PEER_CLOSED);
    peer_.reset();
}

zx_status_t EventPairDispatcher::user_signal(uint32_t clear_mask, uint32_t set_mask, bool peer)
    TA_NO_THREAD_SAFETY_ANALYSIS {
    canary_.Assert();

    if ((set_mask & ~kUserSignalMask) || (clear_mask & ~kUserSignalMask))
        return ZX_ERR_INVALID_ARGS;

    fbl::AutoLock locker(get_lock());

    if (!peer) {
        UpdateStateLocked(clear_mask, set_mask);
        return ZX_OK;
    }

    // object_signal() may race with handle_close() on another thread.
    if (!peer_)
        return ZX_ERR_PEER_CLOSED;
    peer_->UpdateStateLocked(clear_mask, set_mask);
    return ZX_OK;
}

EventPairDispatcher::EventPairDispatcher(fbl::RefPtr<PeerHolder<EventPairDispatcher>> holder)
    : PeeredDispatcher(fbl::move(holder))
{}

// This is called before either EventPairDispatcher is accessible from threads other than the one
// initializing the event pair, so it does not need locking.
void EventPairDispatcher::Init(fbl::RefPtr<EventPairDispatcher> other) TA_NO_THREAD_SAFETY_ANALYSIS {
    DEBUG_ASSERT(other);
    // No need to take |lock_| here.
    DEBUG_ASSERT(!peer_);
    peer_koid_ = other->get_koid();
    peer_ = fbl::move(other);
}
