0001 #if os(Linux) 0002 import Glibc 0003 #else 0004 import Darwin.C 0005 #endif 0006 0007 import Nest 0008 import Inquiline 0009 0010 0011 public typealias Application = RequestType -> ResponseType 0012 0013 0014 public protocol WorkerType{ 0015 /*** Initialises the worker 0016 - Parameters: 0017 - configuration 0018 - logger 0019 - listeners 0020 - notify: A notify callback, this should be retained and invoked to notify the arbiter of your existance to prevent timeouts 0021 - application: The users Nest application 0022 0023 NOTE: This is invoked from the master process 0024 */ 0025 init(configuration: Configuration, logger: Logger, listeners: [Socket], notify: Void -> Void, application: Application) 0026 0027 /*** Runs the worker 0028 The implementation should start listening for requests on the listeners, 0029 and invoke the notify callback before `configuration.timeout` happens. 0030 0031 NOTE: This is invoked from the workers fork 0032 **/ 0033 func run() 0034 } 0035 0036 0037 // Represents a worker 0038 final class WorkerProcess
SynchronousWorker.swift:11 public final class SynchronousWorker : WorkerType {{ 0039 /// Indicates when the worker has been aborted, used by the arbiter 0040 var aborted
Arbiter.swift:52 var workers: [pid_t: WorkerProcess] = [:]Arbiter.swift:253 let workerProcess = WorkerProcess(): Bool = false 0041 let temp
Arbiter.swift:215 if worker.aborted {Arbiter.swift:220 worker.aborted = true= WorkerTemp() 0042 0043 func notify() { 0044 temp.notify() 0045 } 0046 } 0047 0048 0049 func getenv
Arbiter.swift:212 let lastUpdate = currentTime.tv_sec - worker.temp.lastUpdate.tv_secWorker.swift:44 temp.notify()(key: String, `default`: String) -> String { 0050 let result = getenv(key) 0051 if result != nil { 0052 if let value = String.fromCString(result) { 0053 return value 0054 } 0055 } 0056 0057 return `default` 0058 } 0059 0060 0061 class WorkerTemp
Worker.swift:67 var tempdir = getenv("TMPDIR", default: "/tmp/"){ 0062 let descriptor
Worker.swift:41 let temp = WorkerTemp(): Int32 0063 var state
Worker.swift:76 descriptor = withUnsafeMutablePointer(&templateChars[0]) { buffer -> Int32 inWorker.swift:80 if descriptor == -1 {Worker.swift:91 if fcntl(descriptor, F_GETPATH, filename.bytes) == -1 {Worker.swift:101 close(descriptor)Worker.swift:111 fchmod(descriptor, state)Worker.swift:116 fstat(descriptor, &stats): mode_t = 0 0064 0065 init
Worker.swift:105 if state == 1 {Worker.swift:106 state = 0Worker.swift:108 state = 1Worker.swift:111 fchmod(descriptor, state)() { 0066 0067 var tempdir = getenv("TMPDIR", default: "/tmp/") 0068 #if !os(Linux) 0069 if !tempdir.hasSuffix("/") { 0070 tempdir += "/" 0071 } 0072 #endif 0073 0074 let template = "\(tempdir)/curassow.XXXXXXXX" 0075 var templateChars = Array(template.utf8).map { Int8($0) } + [0] 0076 descriptor = withUnsafeMutablePointer(&templateChars[0]) { buffer -> Int32 in 0077 return mkstemp(buffer) 0078 } 0079 0080 if descriptor == -1 { 0081 fatalError("mkstemp(\(template)) failed") 0082 } 0083 0084 // Find the filename 0085 #if os(Linux) 0086 let filename = Data(capacity: Int(PATH_MAX)) 0087 let size = readlink("/proc/self/fd/\(descriptor)", filename.bytes, filename.capacity) 0088 filename.bytes[size] = 0 0089 #else 0090 let filename = Data(capacity: Int(MAXPATHLEN)) 0091 if fcntl(descriptor, F_GETPATH, filename.bytes) == -1 { 0092 fatalError("fcntl failed") 0093 } 0094 #endif 0095 0096 // Unlink, so once last close is done, it gets deleted 0097 unlink(filename.string!) 0098 } 0099 0100 deinit { 0101 close(descriptor) 0102 } 0103 0104 func notify
Worker.swift:41 let temp = WorkerTemp()() { 0105 if state == 1 { 0106 state = 0 0107 } else { 0108 state = 1 0109 } 0110 0111 fchmod(descriptor, state) 0112 } 0113 0114 var lastUpdate
Worker.swift:44 temp.notify(): timespec { 0115 var stats = stat() 0116 fstat(descriptor, &stats) 0117 #if os(Linux) 0118 return stats.st_ctim 0119 #else 0120 return stats.st_ctimespec 0121 #endif 0122 } 0123 } 0124
Arbiter.swift:212 let lastUpdate = currentTime.tv_sec - worker.temp.lastUpdate.tv_sec