1// Copyright 2018 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#include <object/suspend_token_dispatcher.h>
8
9#include <err.h>
10
11#include <kernel/auto_lock.h>
12#include <object/thread_dispatcher.h>
13#include <zircon/rights.h>
14#include <fbl/alloc_checker.h>
15
16zx_status_t SuspendTokenDispatcher::Create(fbl::RefPtr<ThreadDispatcher> thread,
17                                           fbl::RefPtr<Dispatcher>* dispatcher,
18                                           zx_rights_t* rights) {
19    zx_status_t status = thread->Suspend();
20    if (status != ZX_OK)
21        return ZX_ERR_BAD_STATE;
22
23    fbl::AllocChecker ac;
24    fbl::unique_ptr<SuspendTokenDispatcher> disp(
25        new (&ac) SuspendTokenDispatcher(fbl::move(thread)));
26    if (!ac.check())
27        return ZX_ERR_NO_MEMORY;
28
29    *rights = ZX_DEFAULT_SUSPEND_TOKEN_RIGHTS;
30    *dispatcher = fbl::AdoptRef<Dispatcher>(disp.release());
31    return ZX_OK;
32}
33
34SuspendTokenDispatcher::SuspendTokenDispatcher(fbl::RefPtr<ThreadDispatcher> thread)
35    : thread_(fbl::move(thread)) {}
36
37SuspendTokenDispatcher::~SuspendTokenDispatcher() {}
38
39void SuspendTokenDispatcher::on_zero_handles() {
40    thread_->Resume();
41}
42