The Pedigree Project 0.1
queued-signal.h
1/* Copyright (c) 2026, Pedigree Developers. */
2#ifndef POSIX_QUEUED_SIGNAL_H
3#define POSIX_QUEUED_SIGNAL_H
4
5#include "pedigree/kernel/Log.h"
6#include "pedigree/kernel/Spinlock.h"
7#include "pedigree/kernel/process/ConditionVariable.h"
8#include "pedigree/kernel/process/Event.h"
9#include "pedigree/kernel/process/Mutex.h"
10#include "pedigree/kernel/process/Process.h"
11#include "pedigree/kernel/process/Readiness.h"
12#include "pedigree/kernel/processor/types.h"
13#include "pedigree/kernel/utilities/List.h"
14#include "pedigree/kernel/utilities/SharedPointer.h"
15
16class Process;
17class Thread;
22
23struct alignas(8) LinuxQueuedSiginfo {
24 uint8_t bytes[128];
25};
26static_assert(sizeof(LinuxQueuedSiginfo) == 128, "Linux amd64 siginfo layout");
27
29 int32_t number = 0, code = 0, pid = 0;
30 uint32_t uid = 0;
31 uint64_t value = 0;
32 int32_t timerId = 0, overrun = 0, status = 0;
33 uint64_t userTime = 0, systemTime = 0;
34};
35
37 public:
38 Thread* thread = nullptr;
39 bool alive = true;
40 uint64_t generations[64] = {};
41};
42
45 public:
46 void attach(Process* process);
47 void close();
48 void retireThread(Thread* thread);
50 ReadyMask query(const SharedPointer<PendingSignalBinding>& binding, uint64_t mask,
51 ReadinessGenerations* generations = nullptr);
52 void recordChange(size_t signal = 0, Thread* target = nullptr, bool processDirected = false);
53 void publish();
54 void wake();
55 uint64_t version() const {
56 return __atomic_load_n(&m_Version, __ATOMIC_ACQUIRE);
57 }
58 Mutex lock;
59 ConditionVariable changed;
60
61 private:
62 Process* m_Process = nullptr;
63 bool m_Closed = false;
64 uint64_t m_Version = 0;
65 uint64_t m_ProcessGenerations[64] = {};
67};
68
71 public:
73 : m_Context(context), m_Version(0) {
74 PendingSignalContext* retained = m_Context.get();
75 if (!retained) {
76 FATAL("Pending signal notification has no context.");
77 return;
78 }
79 m_Version = retained->version();
80 }
82 PendingSignalContext* retained = m_Context.get();
83 if (!retained) {
84 FATAL("Pending signal notification lost its context.");
85 return;
86 }
87 if (retained->version() != m_Version)
88 retained->publish();
89 }
90
91 private:
93 uint64_t m_Version;
94};
95
98 public:
99 PendingSignalReservation() = default;
101 bool reserve(Thread* caller, uint64_t mask);
102 PendingSignalRecord record() const;
103 void commit(int32_t overrun);
104 void rollback();
105
106 private:
108 PendingSignalReservation& operator=(const PendingSignalReservation&) = delete;
109 Thread* m_Caller = nullptr;
110 Process::ThreadLease m_Selected;
111 Event::Delivery m_Delivery;
112};
113
114bool posix_matching_pending(Thread* caller, uint64_t mask);
115void posix_signal_record_siginfo(const PendingSignalRecord&, LinuxQueuedSiginfo&);
116
118 public:
121 bool addExpirations(uint64_t count);
122 void queueFailed();
123 int getDeliveredOverrun();
124 int32_t timerId;
125
126 private:
127 friend class QueuedSignalState;
128 friend bool posix_signal_reserve_timer(Process*, SharedPointer<PosixTimerSignalToken>&);
129 friend int posix_signal_queue_timer(Process*, Thread*, int, uint64_t,
131 friend void posix_signal_reset_timer(Process*, const SharedPointer<PosixTimerSignalToken>&);
132 friend void posix_signal_cancel_timer(Process*, const SharedPointer<PosixTimerSignalToken>&);
133 Spinlock m_Lock;
134 bool m_Active, m_Pending;
135 uint64_t m_Generation, m_Expirations;
136 int32_t m_DeliveredOverrun;
138};
139
140SharedPointer<SignalEventState> posix_signal_reserve_queue(Process*);
141bool posix_signal_reserve_timer(Process*, SharedPointer<PosixTimerSignalToken>&);
142int posix_signal_queue_timer(Process*, Thread* target, int signal, uint64_t value,
144void posix_signal_reset_timer(Process*, const SharedPointer<PosixTimerSignalToken>&);
145void posix_signal_cancel_timer(Process*, const SharedPointer<PosixTimerSignalToken>&);
146
147int posix_rt_sigpending(uint64_t* signals, size_t signalSetSize);
148int posix_rt_sigtimedwait(const uint64_t* signals, LinuxQueuedSiginfo* info,
149 const LinuxKernelTimespec* timeout, size_t signalSetSize);
150int posix_rt_sigqueueinfo(int pid, int signal, const LinuxQueuedSiginfo* info);
151
152#endif
Definition List.h:61
Definition Mutex.h:56
T * get() const
Definition tracee.c:26