forked from free1139/ziron
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsuspend_token_dispatcher.cpp
More file actions
81 lines (64 loc) · 2.34 KB
/
suspend_token_dispatcher.cpp
File metadata and controls
81 lines (64 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright 2018 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/suspend_token_dispatcher.h>
#include <err.h>
#include <fbl/alloc_checker.h>
#include <fbl/unique_ptr.h>
#include <kernel/auto_lock.h>
#include <object/process_dispatcher.h>
#include <object/thread_dispatcher.h>
#include <zircon/rights.h>
namespace {
// Suspends a process or thread.
// TODO(ZX-858): Add support for jobs.
zx_status_t SuspendTask(fbl::RefPtr<Dispatcher> task) {
if (auto thread = DownCastDispatcher<ThreadDispatcher>(&task)) {
if (thread.get() == ThreadDispatcher::GetCurrent())
return ZX_ERR_NOT_SUPPORTED;
return thread->Suspend();
}
if (auto process = DownCastDispatcher<ProcessDispatcher>(&task)) {
if (process.get() == ProcessDispatcher::GetCurrent())
return ZX_ERR_NOT_SUPPORTED;
return process->Suspend();
}
return ZX_ERR_WRONG_TYPE;
}
// Resumes a process or thread.
// TODO(ZX-858): Add support for jobs.
void ResumeTask(fbl::RefPtr<Dispatcher> task) {
if (auto thread = DownCastDispatcher<ThreadDispatcher>(&task)) {
thread->Resume();
return;
}
if (auto process = DownCastDispatcher<ProcessDispatcher>(&task)) {
process->Resume();
return;
}
__UNREACHABLE;
}
} // namespace
zx_status_t SuspendTokenDispatcher::Create(fbl::RefPtr<Dispatcher> task,
fbl::RefPtr<SuspendTokenDispatcher>* dispatcher,
zx_rights_t* rights) {
fbl::AllocChecker ac;
ktl::unique_ptr<SuspendTokenDispatcher> disp(new (&ac) SuspendTokenDispatcher(task));
if (!ac.check())
return ZX_ERR_NO_MEMORY;
zx_status_t status = SuspendTask(ktl::move(task));
if (status != ZX_OK)
return status;
*rights = default_rights();
*dispatcher = fbl::AdoptRef(disp.release());
return ZX_OK;
}
SuspendTokenDispatcher::SuspendTokenDispatcher(fbl::RefPtr<Dispatcher> task)
: task_(ktl::move(task)) {}
SuspendTokenDispatcher::~SuspendTokenDispatcher() {}
void SuspendTokenDispatcher::on_zero_handles() {
// This is only called once and we're done with |task_| afterwards so we can move it out.
ResumeTask(ktl::move(task_));
}