The Pedigree Project 0.1
SignalEvent.h
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#ifndef SIGNAL_EVENT_H
21#define SIGNAL_EVENT_H
22
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/process/Event.h"
25#include "pedigree/kernel/processor/types.h"
26#include "pedigree/kernel/utilities/SharedPointer.h"
27
28class EXPORTED_PUBLIC SignalEventState {
29 public:
30 virtual ~SignalEventState() = default;
31 virtual bool active() const = 0;
32 virtual bool timer() const = 0;
33 virtual void timerInfo(int32_t& timerId, int32_t& overrun) const = 0;
34 virtual void complete(bool delivered, int32_t overrun) = 0;
35 virtual const void* source() const {
36 return nullptr;
37 }
38};
39
40class EXPORTED_PUBLIC SignalEvent : public Event {
41 public:
42 enum class DeliveryDisposition {
43 DefaultAction,
44 CaughtHandler,
45 };
46
47 SignalEvent(uintptr_t handlerAddress, size_t signalNum, size_t specificNestingLevel = ~0UL,
48 uint64_t signalMask = 0, bool deferSignal = true, bool isDeletable = false,
49 HandlerPrivilege handlerPrivilege = HandlerPrivilege::Kernel,
50 DeliveryDisposition disposition = DeliveryDisposition::CaughtHandler,
51 bool useAlternateUserStack = false, size_t continuationEpoch = 0);
52
53 SignalEvent(const SignalEvent& other);
54 ~SignalEvent() override;
55
56 void setChildStatus(int32_t status, uint64_t userTime, uint64_t systemTime) {
57 m_ChildStatus = status;
58 m_ChildUserTime = userTime;
59 m_ChildSystemTime = systemTime;
60 }
61 int32_t childStatus() const {
62 return m_ChildStatus;
63 }
64 uint64_t childUserTime() const {
65 return m_ChildUserTime;
66 }
67 uint64_t childSystemTime() const {
68 return m_ChildSystemTime;
69 }
70 uint64_t rebindGeneration() const {
71 return m_RebindGeneration;
72 }
73 void setRebindGeneration(uint64_t value) {
74 m_RebindGeneration = value;
75 }
76 uint64_t queueSequence() const {
77 return m_QueueSequence;
78 }
79 void setQueueSequence(uint64_t value) {
80 m_QueueSequence = value;
81 }
82 bool deliveryActive() const {
83 return !m_DeliveryState || m_DeliveryState->active();
84 }
85 bool queuedIndividually() const {
86 return m_SignalNumber >= 32 || (m_DeliveryState && m_DeliveryState->timer());
87 }
88 bool hasDeliveryState() const {
89 return bool(m_DeliveryState);
90 }
91 void setDeliveryState(const SharedPointer<SignalEventState>& state) {
92 m_DeliveryState = state;
93 }
94 void transferDeliveryStateTo(SignalEvent& event) {
95 event.m_DeliveryState = pedigree_std::move(m_DeliveryState);
96 event.m_TraceBypass = m_TraceBypass;
97 }
98 const void* deliverySource() const {
99 return m_DeliveryState ? m_DeliveryState->source() : nullptr;
100 }
101 void timerInfo(int32_t& timerId, int32_t& overrun) const {
102 timerId = 0;
103 overrun = 0;
104 if (m_DeliveryState) {
105 m_DeliveryState->timerInfo(timerId, overrun);
106 }
107 }
108 void rejectSignalDelivery() const {
109 if (m_DeliveryState)
110 m_DeliveryState->complete(false, -1);
111 }
112 void completeSignalDelivery(int32_t overrun = 0) const {
113 if (m_DeliveryState) {
114 m_DeliveryState->complete(true, overrun);
115 }
116 }
117
118 void setTraceBypass(bool value = true) {
119 m_TraceBypass = value;
120 }
121 bool consumeTraceBypass() {
122 bool value = m_TraceBypass;
123 m_TraceBypass = false;
124 return value;
125 }
126 virtual size_t serialize(uint8_t* pBuffer);
127 static bool unserialize(uint8_t* pBuffer, Event& event);
128
129 virtual bool isSignalEvent() const {
130 return true;
131 }
132
133 virtual bool prefersAlternateUserStack() const {
134 return m_UseAlternateUserStack;
135 }
136
138 // Signal 9 is SIGKILL on every ABI which uses SignalEvent.
139 return m_SignalNumber == 9;
140 }
141
142 virtual Event* cloneForDelivery();
143
145 virtual SignalEvent* cloneForDisposition();
146
147 void setProcessDirected(bool processDirected) {
148 m_ProcessDirected = processDirected;
149 }
150
151 bool isProcessDirected() const {
152 return m_ProcessDirected;
153 }
154
156 void setSignalOrigin(int32_t signalCode, int32_t senderProcess, uint32_t senderUser) {
157 m_SignalCode = signalCode;
158 m_SenderProcess = senderProcess;
159 m_SenderUser = senderUser;
160 }
161
162 int32_t getSignalCode() const {
163 return m_SignalCode;
164 }
165
166 int32_t getSenderProcess() const {
167 return m_SenderProcess;
168 }
169
170 void setSignalValue(uint64_t value) {
171 m_SignalValue = value;
172 }
173 uint64_t getSignalValue() const {
174 return m_SignalValue;
175 }
176
177 uint32_t getSenderUser() const {
178 return m_SenderUser;
179 }
180
181 uint64_t getDeliverySignalMask() const {
182 return m_SignalMask;
183 }
184
185 bool defersDeliveredSignal() const {
186 return m_DeferSignal;
187 }
188
190 void setContinuationEpoch(size_t continuationEpoch) {
191 m_ContinuationEpoch = continuationEpoch;
192 }
193
194 size_t getContinuationEpoch() const {
195 return m_ContinuationEpoch;
196 }
197
198 virtual size_t getNumber() {
199 return m_SignalNumber;
200 }
201
202 protected:
203 SignalEvent(const SignalEvent& other, bool isDeletable);
204
205 private:
208
210 uint64_t m_SignalMask;
211
214
217
219 DeliveryDisposition m_Disposition;
220
223
226
229 int32_t m_SenderProcess;
230 uint32_t m_SenderUser;
231 uint64_t m_SignalValue;
232 SharedPointer<SignalEventState> m_DeliveryState;
233 bool m_TraceBypass = false;
234 uint64_t m_RebindGeneration = 0;
235 uint64_t m_QueueSequence = 0;
236 int32_t m_ChildStatus = 0;
237 uint64_t m_ChildUserTime = 0, m_ChildSystemTime = 0;
238};
239
240#endif
Definition Event.h:49
HandlerPrivilege
Definition Event.h:52
bool m_DeferSignal
virtual bool isSignalEvent() const
size_t m_SignalNumber
uint64_t m_SignalMask
bool m_ProcessDirected
int32_t m_SignalCode
virtual size_t getNumber()
size_t m_ContinuationEpoch
void setSignalOrigin(int32_t signalCode, int32_t senderProcess, uint32_t senderUser)
void setContinuationEpoch(size_t continuationEpoch)
virtual bool prefersAlternateUserStack() const
virtual bool isDeliverableWhileProcessSuspended() const
DeliveryDisposition m_Disposition
bool m_UseAlternateUserStack