Skip to content

Commit 19a1f29

Browse files
committed
chore: Use fd where possible
1 parent 8d1eb76 commit 19a1f29

File tree

6 files changed

+66
-37
lines changed

6 files changed

+66
-37
lines changed

Sources/Curassow/Arbiter.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public final class Arbiter<Worker : WorkerType> {
8888
}
8989

9090
func stop(_ graceful: Bool = true) {
91-
listeners.forEach { $0.close() }
91+
listeners.forEach { _ = try? $0.close() }
9292

9393
if graceful {
9494
killWorkers(SIGTERM)
@@ -115,13 +115,13 @@ public final class Arbiter<Worker : WorkerType> {
115115
timeout = timeval(tv_sec: 30, tv_usec: 0)
116116
}
117117

118-
let fds = [signalHandler.pipe.read]
118+
let fds = [Socket(descriptor: signalHandler.pipe.reader.fileNumber)]
119119
let result = try? select(reads: fds, writes: [Socket](), errors: [Socket](), timeout: timeout)
120120
let read = result?.reads ?? []
121121

122122
if !read.isEmpty {
123123
do {
124-
while try signalHandler.pipe.read.read(1).count > 0 {}
124+
while try signalHandler.pipe.reader.read(1).count > 0 {}
125125
} catch {}
126126
}
127127
}

Sources/Curassow/DispatchWorker.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ final public class DispatchWorker : WorkerType {
106106
sendResponse(client, response: response)
107107

108108
client.shutdown()
109-
client.close()
109+
_ = try? client.close()
110110
}
111111
}
112112

@@ -120,7 +120,7 @@ extension Socket {
120120
}
121121

122122
source.setCancelHandler { [unowned self] in
123-
self.close()
123+
_ = try? self.close()
124124
}
125125

126126
source.resume()

Sources/Curassow/Signals.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import Glibc
44
import Darwin.C
55
#endif
66

7+
import fd
8+
79
var sharedHandler: SignalHandler?
810

911
class SignalHandler {
@@ -34,20 +36,20 @@ class SignalHandler {
3436
signal(SIGCHLD, SIG_DFL)
3537
}
3638

37-
let pipe: (read: Socket, write: Socket)
39+
let pipe: (reader: ReadableFileDescriptor, writer: WritableFileDescriptor)
3840
var signalQueue: [Signal] = []
3941

4042
init() throws {
41-
pipe = try Socket.pipe()
42-
pipe.read.closeOnExec = true
43-
pipe.read.blocking = false
44-
pipe.write.closeOnExec = true
45-
pipe.write.blocking = false
43+
pipe = try fd.pipe()
44+
pipe.reader.closeOnExec = true
45+
pipe.reader.blocking = false
46+
pipe.writer.closeOnExec = true
47+
pipe.writer.blocking = false
4648
}
4749

4850
// Wake up the process by writing to the pipe
4951
func wakeup() {
50-
pipe.write.send(".")
52+
_ = try? pipe.writer.write([46])
5153
}
5254

5355
func handle(_ signal: Signal) {

Sources/Curassow/Socket.swift

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ private let sock_stream = Int32(SOCK_STREAM.rawValue)
55

66
private let system_accept = Glibc.accept
77
private let system_bind = Glibc.bind
8-
private let system_close = Glibc.close
98
private let system_listen = Glibc.listen
10-
private let system_read = Glibc.read
119
private let system_send = Glibc.send
1210
private let system_write = Glibc.write
1311
private let system_shutdown = Glibc.shutdown
@@ -20,9 +18,7 @@ private let sock_stream = SOCK_STREAM
2018

2119
private let system_accept = Darwin.accept
2220
private let system_bind = Darwin.bind
23-
private let system_close = Darwin.close
2421
private let system_listen = Darwin.listen
25-
private let system_read = Darwin.read
2622
private let system_send = Darwin.send
2723
private let system_write = Darwin.write
2824
private let system_shutdown = Darwin.shutdown
@@ -78,7 +74,7 @@ class Unreader : Readable {
7874

7975

8076
/// Represents a TCP AF_INET/AF_UNIX socket
81-
final public class Socket : Readable, FileDescriptor, Listener, Connection {
77+
final public class Socket : Readable, FileDescriptor, ReadableFileDescriptor, Listener, Connection {
8278
typealias Port = UInt16
8379

8480
public let fileNumber: FileNumber
@@ -172,10 +168,6 @@ final public class Socket : Readable, FileDescriptor, Listener, Connection {
172168
return Socket(descriptor: descriptor)
173169
}
174170

175-
func close() {
176-
_ = system_close(fileNumber)
177-
}
178-
179171
func shutdown() {
180172
_ = system_shutdown(fileNumber, Int32(SHUT_RDWR))
181173
}
@@ -206,15 +198,6 @@ final public class Socket : Readable, FileDescriptor, Listener, Connection {
206198
}
207199
}
208200

209-
func read(_ bytes: Int) throws -> [CChar] {
210-
let data = Data(capacity: bytes)
211-
let bytes = system_read(fileNumber, data.bytes, data.capacity)
212-
guard bytes != -1 else {
213-
throw SocketError()
214-
}
215-
return Array(data.characters[0..<bytes])
216-
}
217-
218201
/// Returns whether the socket is set to non-blocking or blocking
219202
var blocking: Bool {
220203
get {
@@ -261,3 +244,47 @@ final public class Socket : Readable, FileDescriptor, Listener, Connection {
261244
return (value << 8) + (value >> 8)
262245
}
263246
}
247+
248+
extension FileDescriptor {
249+
/// Returns whether the socket is set to non-blocking or blocking
250+
var blocking: Bool {
251+
get {
252+
let flags = fcntl(fileNumber, F_GETFL, 0)
253+
return flags & O_NONBLOCK == 0
254+
}
255+
256+
set {
257+
let flags = fcntl(fileNumber, F_GETFL, 0)
258+
let newFlags: Int32
259+
260+
if newValue {
261+
newFlags = flags & ~O_NONBLOCK
262+
} else {
263+
newFlags = flags | O_NONBLOCK
264+
}
265+
266+
let _ = fcntl(fileNumber, F_SETFL, newFlags)
267+
}
268+
}
269+
270+
/// Returns whether the socket is has the FD_CLOEXEC flag set
271+
var closeOnExec: Bool {
272+
get {
273+
let flags = fcntl(fileNumber, F_GETFL, 0)
274+
return flags & FD_CLOEXEC == 1
275+
}
276+
277+
set {
278+
let flags = fcntl(fileNumber, F_GETFL, 0)
279+
let newFlags: Int32
280+
281+
if newValue {
282+
newFlags = flags ^ FD_CLOEXEC
283+
} else {
284+
newFlags = flags | FD_CLOEXEC
285+
}
286+
287+
let _ = fcntl(fileNumber, F_SETFL, newFlags)
288+
}
289+
}
290+
}

Sources/Curassow/SynchronousWorker.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public final class SynchronousWorker : WorkerType {
9191
notify()
9292

9393
let sockets = wait().filter {
94-
$0.fileNumber != sharedHandler!.pipe.read.fileNumber
94+
$0.fileNumber != sharedHandler!.pipe.reader.fileNumber
9595
}
9696

9797
sockets.forEach(accept)
@@ -121,7 +121,7 @@ public final class SynchronousWorker : WorkerType {
121121
timeout = timeval(tv_sec: 120, tv_usec: 0)
122122
}
123123

124-
let socks = listeners + [sharedHandler!.pipe.read]
124+
let socks = listeners + [Socket(descriptor: sharedHandler!.pipe.reader.fileNumber)]
125125
let result = try? fd.select(reads: socks, writes: [Socket](), errors: [Socket](), timeout: timeout)
126126
return result?.reads ?? []
127127
}
@@ -153,7 +153,7 @@ public final class SynchronousWorker : WorkerType {
153153
sendResponse(client, response: response)
154154

155155
client.shutdown()
156-
client.close()
156+
_ = try? client.close()
157157
}
158158
}
159159

Tests/CurassowTests/HTTPParserSpec.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ func testHTTPParser() {
4646
}
4747

4848
$0.after {
49-
inSocket?.close()
50-
outSocket?.close()
49+
try! inSocket?.close()
50+
try! outSocket?.close()
5151
}
5252

5353
$0.it("can parse a HTTP request") {
@@ -98,15 +98,15 @@ func testHTTPParser() {
9898
}
9999

100100
$0.it("throws an error when the client disconnects before sending an HTTP request") {
101-
outSocket.close()
101+
try outSocket.close()
102102
outSocket = nil
103103

104104
try expect(try parser.parse()).toThrow()
105105
}
106106

107107
$0.it("throws an error when the client disconnects before sending the entire message body") {
108108
outSocket.write("GET / HTTP/1.1\r\nContent-Length: 42\r\n")
109-
outSocket.close()
109+
try outSocket.close()
110110
outSocket = nil
111111

112112
try expect(try parser.parse()).toThrow()

0 commit comments

Comments
 (0)