The Pedigree Project 0.1
PipeBuffer.h
1/* Copyright (c) 2026, Pedigree Developers. */
2#ifndef VFS_PIPE_BUFFER_H
3#define VFS_PIPE_BUFFER_H
4
5#include "pedigree/kernel/Atomic.h"
6#include "pedigree/kernel/compiler.h"
7#include "pedigree/kernel/process/ConditionVariable.h"
8#include "pedigree/kernel/process/Mutex.h"
9#include "pedigree/kernel/process/TerminationDeferral.h"
10#include "pedigree/kernel/processor/types.h"
11
12class EXPORTED_PUBLIC PipeBuffer {
13 public:
14 static constexpr size_t Capacity = 4096;
15 using ChangeCallback = void (*)(void*);
16 enum class Status { Ready, Eof, WouldBlock, Interrupted, Closed, Invalid };
17 struct Result {
18 Status status;
19 size_t count;
20 };
21
22 class EXPORTED_PUBLIC ReadReservation {
23 public:
26 ReadReservation(const ReadReservation&) = delete;
27 ReadReservation& operator=(const ReadReservation&) = delete;
28 size_t size() const;
29 void copyTo(uint8_t* destination, size_t count) const;
30 void consume(size_t accepted);
31 void cancel();
32
33 private:
34 friend class PipeBuffer;
35 TerminationDeferral m_Termination;
36 PipeBuffer* m_Buffer = nullptr;
37 size_t m_Size = 0;
38 };
39
40 class EXPORTED_PUBLIC WriteReservation {
41 public:
44 WriteReservation(const WriteReservation&) = delete;
45 WriteReservation& operator=(const WriteReservation&) = delete;
46 size_t size() const;
47 Result commit(const uint8_t* source, size_t accepted);
48 void cancel();
49
50 private:
51 friend class PipeBuffer;
52 TerminationDeferral m_Termination;
53 PipeBuffer* m_Buffer = nullptr;
54 size_t m_Size = 0;
55 };
56
57 explicit PipeBuffer(ChangeCallback changed = nullptr, void* context = nullptr);
59 PipeBuffer(const PipeBuffer&) = delete;
60 PipeBuffer& operator=(const PipeBuffer&) = delete;
61
62 size_t read(uint8_t* destination, size_t count, bool block = true);
63 size_t write(const uint8_t* source, size_t count, bool block = true);
64 size_t writeAtomic(const uint8_t* source, size_t count, bool block = true);
65 bool canRead(bool block);
66 bool canWrite(bool block);
67 uint64_t readableGeneration() const;
68 uint64_t writableGeneration() const;
69 size_t getDataSize();
70
71 // These run under Pipe's endpoint lock; Pipe publishes after unlocking.
72 void disableReads();
73 void disableWrites();
74 bool enableReads();
75 bool enableWrites(bool resetIfPreviouslyDisabled = false);
76 void wipe();
77 void close();
78
79 Result reserveRead(size_t maximum, bool block, ReadReservation& reservation);
80 Result reserveWrite(size_t maximum, bool block, WriteReservation& reservation);
81 Result waitTransfer(bool writing, bool block);
82 Result transferTo(PipeBuffer& output, size_t maximum, bool consume, bool block);
83
84 private:
85 friend class PipeBufferTestPeer;
86 struct PairWaiter;
87 struct PairLink;
89 public:
90 explicit ActiveOperation(PipeBuffer& buffer);
92 explicit operator bool() const;
93 void detach();
94
95 private:
96 ActiveOperation(const ActiveOperation&) = delete;
97 ActiveOperation& operator=(const ActiveOperation&) = delete;
98 TerminationDeferral m_Termination;
99 PipeBuffer* m_Buffer;
100 };
101
102 static void lock(Mutex& mutex);
103 static bool wait(ConditionVariable& condition, Mutex& mutex);
104 static bool interrupted();
105 bool beginOperation();
106 void endOperation();
107 bool readableLocked() const;
108 bool writableLocked() const;
109 Result readyLocked(bool writing, size_t minimum = 1) const;
110 Result waitLocked(bool writing, size_t minimum, bool block);
111 void changedLocked();
112 void resetLocked();
113 void finishResetLocked();
114 void copyOutLocked(uint8_t* destination, size_t count) const;
115 void appendLocked(const uint8_t* source, size_t count);
116 void consumeLocked(size_t count);
117 void publish();
118 void wakePairsLocked();
119 void linkPairLocked(PairLink& link);
120 void unlinkPairLocked(PairLink& link);
121
122 uint8_t m_Data[Capacity];
123 size_t m_Head = 0;
124 size_t m_Size = 0;
125 bool m_ReadEnabled = true;
126 bool m_WriteEnabled = true;
127 bool m_Closing = false;
128 bool m_ResetPending = false;
129 bool m_ReadReserved = false;
130 bool m_WriteReserved = false;
131 bool m_WasReadable = false;
132 bool m_WasWritable = true;
133 size_t m_ActiveOperations = 0;
134 Atomic<uint64_t> m_ReadGeneration;
135 Atomic<uint64_t> m_WriteGeneration;
136 Mutex m_Lock;
137 ConditionVariable m_ReadCondition;
138 ConditionVariable m_WriteCondition;
139 ConditionVariable m_DrainCondition;
140 PairLink* m_PairWaiters = nullptr;
141 const ChangeCallback m_Changed;
142 void* const m_Context;
143};
144
145#endif
Definition Mutex.h:56