0001 /* 0002 * Chan (chan.swift) - Please be Safe 0003 * 0004 * Copyright (C) 2015 ONcast, LLC. All Rights Reserved. 0005 * Created by Josh Baker (joshbaker77@gmail.com) 0006 * 0007 * This software may be modified and distributed under the terms 0008 * of the MIT license. See the LICENSE file for details. 0009 */ 0010 0011 import Foundation 0012 0013 private let idMutex= Mutex() 0014 private var idCounter
chan.swift:44 idMutex.lock()chan.swift:47 idMutex.unlock()= 0 0015 0016 0017 /** 0018 Channels are the pipes that connect concurrent operations. 0019 You can send values into channels from one operation and receive those values into another operation. 0020 0021 ``` 0022 var messages = Chan<String>() 0023 dispatch { 0024 messages <- "ping" 0025 } 0026 if let msg := <-messages { 0027 println(msg) 0028 } 0029 ``` 0030 0031 0032 */ 0033 public class Chan
chan.swift:45 idCounter += 1chan.swift:46 id = idCounter<T
chan.swift:128 public func <-<T>(l: Chan<T>, r: T){chan.swift:132 public prefix func <-<T>(r: Chan<T>) -> T? {select.swift:27 var chan : Chan<T>?select.swift:30 init(_ chan: Chan<T>?, _ caseBlock: ((T?)->())?, _ defBlock: (()->())?){select.swift:77 func addCase<T>(chan: Chan<T>, _ block: (T?)->()){select.swift:192 public func _case<T>(chan: Chan<T>, block: (T?)->()){> : SequenceType { 0034 internal let id
chan.swift:81 internal func send(msg: T) {chan.swift:97 internal func receive(wait: Bool = true) -> (msg : T?, closed : Bool, ready : Bool) {chan.swift:104 return (msg as? T, false, true)chan.swift:116 public typealias Generator = AnyGenerator<T>: Int 0035 internal let cap
chan.swift:46 id = idCounterselect.swift:78 if items[chan.id] != nil {select.swift:81 items[chan.id] = Item<T>(chan, block, nil)select.swift:82 ids.append(chan.id): Int 0036 internal let cond
chan.swift:43 cap = capacitychan.swift:51 if cap == 0 {chan.swift:60 return capchan.swift:93 while msgs.count > cap {= Cond(Mutex()) 0037 internal var msgs
chan.swift:54 cond.mutex.lock()chan.swift:55 defer { cond.mutex.unlock() }chan.swift:63 cond.broadcast()chan.swift:76 cond.mutex.lock()chan.swift:77 defer { cond.mutex.unlock() }chan.swift:82 cond.mutex.lock()chan.swift:83 defer { cond.mutex.unlock() }chan.swift:94 cond.wait()chan.swift:98 cond.mutex.lock()chan.swift:99 defer { cond.mutex.unlock() }chan.swift:112 cond.wait()select.swift:35 chan.cond.mutex.lock()select.swift:36 defer { chan.cond.mutex.unlock() }select.swift:42 chan.cond.mutex.lock()select.swift:43 defer { chan.cond.mutex.unlock() }= [Any?]() 0038 internal var closed
chan.swift:56 return msgs.countchan.swift:91 msgs.append(msg)chan.swift:93 while msgs.count > cap {chan.swift:101 if msgs.count > 0 {chan.swift:102 let msg = msgs.removeAtIndex(0)= false 0039 internal var gconds
chan.swift:78 closed = truechan.swift:84 if closed {chan.swift:106 if closed {: [Cond] = [] 0040 /// - Parameter capacity A value greater than Zero will create a buffered channel. 0041 /// - Returns a Chan object 0042 public init(_ capacity: Int = 0){ 0043 cap = capacity 0044 idMutex.lock() 0045 idCounter += 1 0046 id = idCounter 0047 idMutex.unlock() 0048 } 0049 /// The number of elements queued (unread) in the channel buffer 0050 public func count() -> Int{ 0051 if cap == 0 { 0052 return 0 0053 } 0054 cond.mutex.lock() 0055 defer { cond.mutex.unlock() } 0056 return msgs.count 0057 } 0058 /// The channel buffer capacity, in units of elements; 0059 public func capacity() -> Int{ 0060 return cap 0061 } 0062 internal func broadcast
chan.swift:64 for cond in gconds {select.swift:37 chan.gconds += [cond]select.swift:44 for i in 0..<chan.gconds.count {select.swift:45 if chan.gconds[i] === cond {select.swift:46 chan.gconds.removeAtIndex(i)() { 0063 cond.broadcast() 0064 for cond in gconds { 0065 cond.mutex.lock() 0066 cond.broadcast() 0067 cond.mutex.unlock() 0068 } 0069 } 0070 /** 0071 Closes the channel. 0072 It should be executed only by the sender, never the receiver, and has the effect of shutting down the channel after the last sent value is received. 0073 After the last value has been received from a closed channel, any receive from the channel will succeed without blocking, returning the a nil value for the channel element. 0074 */ 0075 public func close(){ 0076 cond.mutex.lock() 0077 defer { cond.mutex.unlock() } 0078 closed = true 0079 broadcast() 0080 } 0081 internal func send
chan.swift:79 broadcast()chan.swift:92 broadcast()chan.swift:103 broadcast()(msg: T) { 0082 cond.mutex.lock() 0083 defer { cond.mutex.unlock() } 0084 if closed { 0085 #if os(Linux) 0086 assertionFailure("Send on closed channel") 0087 #else 0088 NSException.raise("Exception", format: "send on closed channel", arguments: getVaList([])) 0089 #endif 0090 } 0091 msgs.append(msg) 0092 broadcast() 0093 while msgs.count > cap { 0094 cond.wait() 0095 } 0096 } 0097 internal func receive
chan.swift:129 l.send(r)(wait: Bool = true) -> (msg : T?, closed : Bool, ready : Bool) { 0098 cond.mutex.lock() 0099 defer { cond.mutex.unlock() } 0100 while true { 0101 if msgs.count > 0 { 0102 let msg = msgs.removeAtIndex(0) 0103 broadcast() 0104 return (msg as? T, false, true) 0105 } 0106 if closed { 0107 return (nil, true, true) 0108 } 0109 if !wait { 0110 return (nil, false, false) 0111 } 0112 cond.wait() 0113 } 0114 } 0115 0116 public typealias Generator
chan.swift:133 let (v, closed, _) = r.receive()select.swift:54 let (msg, closed, ready) = chan.receive(false)= AnyGenerator<T> 0117 public func generate() -> Generator { 0118 return anyGenerator { 0119 return <-self 0120 } 0121 } 0122 } 0123 0124 0125 infix operator <- { associativity right precedence 155 } 0126 prefix operator <- { } 0127 /// Send a message over a channel. Sending over a closed channel will raise a runtime exception. 0128 public func <-<T>(l: Chan<T>, r: T){ 0129 l.send(r) 0130 } 0131 /// Receive a message over a channel. Returns nil if the channel is closed 0132 public prefix func <-<T>(r: Chan<T>) -> T? { 0133 let (v, closed, _) = r.receive() 0134 if closed { 0135 return nil 0136 } 0137 return v! 0138 }
chan.swift:117 public func generate() -> Generator {