The Pedigree Project 0.1
ZombieQueue.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/process/Process.h"
22#include "pedigree/kernel/utilities/ZombieQueue.h"
23#include "pedigree/kernel/utilities/new"
24
25ZombieQueue ZombieQueue::m_Instance;
26
27#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
28ZombieProcess::ReapHook ZombieProcess::m_ReapHook = nullptr;
29#endif
30
31ZombieQueue::ZombieQueue() : RequestQueue(MakeConstantString("ZombieQueue")) {
32 // Destruction publication transfers mandatory lifetime ownership. Unlike a
33 // best-effort work queue, ZombieQueue cannot discard a burst above the
34 // ordinary asynchronous backlog limit without leaking the target object.
35 m_nMaxAsyncRequests = ~static_cast<size_t>(0);
36}
37
38ZombieQueue::~ZombieQueue() {
40}
41
42ZombieQueue& ZombieQueue::instance() {
43 return m_Instance;
44}
45
46void ZombieQueue::addObject(ZombieObject* pObject) {
47 if (!pObject) {
48 FATAL("ZombieQueue cannot publish a null object.");
49 return;
50 }
51
52 if (!addAsyncRequest(1, reinterpret_cast<uint64_t>(pObject))) {
53 FATAL("ZombieQueue rejected mandatory destruction work while stopped.");
54 }
55}
56
57uint64_t ZombieQueue::executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4,
58 uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) {
59 if (!p1)
60 return 0;
61
62 delete reinterpret_cast<ZombieObject*>(p1);
63
64 return 0;
65}
66
67void ZombieQueue::cancelRequest(const Request& request) {
68 delete reinterpret_cast<ZombieObject*>(request.p1);
69}
70
71ZombieProcess::ZombieProcess(Process* pProcess) : m_pProcess(pProcess) {}
72
73ZombieProcess::~ZombieProcess() {
74#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
75 ReapHook reapHook = __atomic_load_n(&m_ReapHook, __ATOMIC_ACQUIRE);
76 if (reapHook) {
77 reapHook(m_pProcess, ReapPhase::Entered);
78 }
79#endif
80 if (!m_pProcess->waitUntilTerminationReapable()) {
81 WARNING(
82 "ZombieQueue rejected an exiting Process before its off-stack "
83 "completion; leaking it rather than deleting a live stack.");
84 return;
85 }
86#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
87 if (reapHook) {
88 reapHook(m_pProcess, ReapPhase::Reapable);
89 }
90#endif
91 m_pProcess->prepareForDestruction();
92 delete m_pProcess;
93}
94
95#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
96void ZombieProcess::setReapHook(ReapHook hook) {
97 __atomic_store_n(&m_ReapHook, hook, __ATOMIC_RELEASE);
98}
99#endif
bool waitUntilTerminationReapable()
Definition Process.cc:2270
void prepareForDestruction()
Definition Process.cc:1029
virtual void destroy()
uint64_t addAsyncRequest(size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0)
virtual uint64_t executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8)
virtual void cancelRequest(const Request &request)