Skip to content

Commit e4e4723

Browse files
committed
Add SocketDescriptor.Event.write()
1 parent 06023c7 commit e4e4723

File tree

1 file changed

+43
-11
lines changed

1 file changed

+43
-11
lines changed

Sources/Socket/System/SocketEvent.swift

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public extension SocketDescriptor.Event {
8484
@frozen
8585
struct Counter: RawRepresentable, Equatable, Hashable, Sendable {
8686

87-
public typealias RawValue = CUnsignedInt
87+
public typealias RawValue = UInt64
8888

8989
@_alwaysEmitIntoClient
9090
public var rawValue: RawValue
@@ -114,15 +114,17 @@ extension SocketDescriptor.Event.Counter: CustomStringConvertible, CustomDebugSt
114114

115115
extension SocketDescriptor.Event {
116116

117+
internal var fileDescriptor: SocketDescriptor { .init(rawValue: rawValue) }
118+
117119
/**
118120
`eventfd()` creates an "eventfd object" that can be used as an event wait/notify mechanism by user-space applications, and by the kernel to notify user-space applications of events.
119121
The object contains an unsigned 64-bit integer (uint64_t) counter that is maintained by the kernel.
120122
This counter is initialized with the value specified in the argument initval.
121123
*/
122124
@usableFromInline
123125
internal static func _events(
124-
_ counter: SocketDescriptor.Event.Counter,
125-
_ flags: SocketDescriptor.Event.Flags,
126+
_ counter: CUnsignedInt,
127+
flags: SocketDescriptor.Event.Flags,
126128
retryOnInterrupt: Bool
127129
) -> Result<SocketDescriptor.Event, Errno> {
128130
valueOrErrno(retryOnInterrupt: retryOnInterrupt) {
@@ -132,11 +134,11 @@ extension SocketDescriptor.Event {
132134

133135
@_alwaysEmitIntoClient
134136
public init(
135-
_ counter: SocketDescriptor.Event.Counter = 0,
136-
_ flags: SocketDescriptor.Event.Flags = [],
137+
_ counter: CUnsignedInt = 0,
138+
flags: SocketDescriptor.Event.Flags = [],
137139
retryOnInterrupt: Bool = true
138140
) throws(Errno) {
139-
self = try Self._events(counter, flags, retryOnInterrupt: retryOnInterrupt).get()
141+
self = try Self._events(counter.rawValue, flags: flags, retryOnInterrupt: retryOnInterrupt).get()
140142
}
141143

142144
/// Deletes a file descriptor.
@@ -151,18 +153,16 @@ extension SocketDescriptor.Event {
151153

152154
@usableFromInline
153155
internal func _close() -> Result<(), Errno> {
154-
nothingOrErrno(retryOnInterrupt: false) { system_close(self.rawValue) }
156+
fileDescriptor._close()
155157
}
156158

157159
@usableFromInline
158160
internal func _read(
159161
retryOnInterrupt: Bool
160162
) -> Result<Counter, Errno> {
161163
var counter = Counter()
162-
return withUnsafeMutableBytes(of: &counter.rawValue) { buffer in
163-
valueOrErrno(retryOnInterrupt: retryOnInterrupt) {
164-
system_read(self.rawValue, buffer.baseAddress, buffer.count)
165-
}
164+
return withUnsafeMutableBytes(of: &counter.rawValue) {
165+
fileDescriptor._read(into: $0, retryOnInterrupt: retryOnInterrupt)
166166
}.map { assert($0 == 8) }.map { _ in counter }
167167
}
168168

@@ -182,5 +182,37 @@ extension SocketDescriptor.Event {
182182
) throws(Errno) -> Counter {
183183
try _read(retryOnInterrupt: retryOnInterrupt).get()
184184
}
185+
186+
/**
187+
A write(2) call adds the 8-byte integer value supplied in
188+
its buffer to the counter. The maximum value that may be
189+
stored in the counter is the largest unsigned 64-bit value
190+
minus 1 (i.e., 0xfffffffffffffffe). If the addition would
191+
cause the counter's value to exceed the maximum, then the
192+
write(2) either blocks until a read(2) is performed on the
193+
file descriptor, or fails with the error EAGAIN if the file
194+
descriptor has been made nonblocking.
195+
196+
A write(2) fails with the error EINVAL if the size of the
197+
supplied buffer is less than 8 bytes, or if an attempt is
198+
made to write the value 0xffffffffffffffff.
199+
*/
200+
@_alwaysEmitIntoClient
201+
public func write(
202+
_ counter: Counter,
203+
retryOnInterrupt: Bool = true
204+
) throws(Errno) -> Int {
205+
try _write(buffer, retryOnInterrupt: retryOnInterrupt).get()
206+
}
207+
208+
@usableFromInline
209+
internal func _write(
210+
_ counter: Counter,
211+
retryOnInterrupt: Bool
212+
) -> Result<(), Errno> {
213+
return withUnsafeBytes(of: counter.rawValue) {
214+
fileDescriptor._write($0, retryOnInterrupt: retryOnInterrupt)
215+
}.map { assert($0 == 8) }
216+
}
185217
}
186218
#endif

0 commit comments

Comments
 (0)