0001
0010
0011 #if os(Linux)
0012 import Glibc
0013 #endif
0014
0015 import Foundation
0016
0017 private protocol ItemAny| select.swift:24 | private class Item<T> : ItemAny { |
| select.swift:75 | var items = [Int: ItemAny]() |
| select.swift:92 | var citems = [ItemAny]() |
| select.swift:98 | var ret : ItemAny? |
{
0018 func register| select.swift:100 | item.register(cond) |
(cond: Cond)
0019 func unregister| select.swift:104 | item.unregister(cond) |
(cond: Cond)
0020 func get| select.swift:112 | if item.get() { |
() -> Bool;
0021 func call| select.swift:107 | item.call() |
()
0022 }
0023
0024 private class Item| select.swift:81 | items[chan.id] = Item<T>(chan, block, nil) |
| select.swift:88 | items[0] = Item<Void>(nil, nil, block) |
<T| select.swift:26 | var msg : T? |
| select.swift:27 | var chan : Chan<T>? |
| select.swift:28 | var caseBlock : ((T?)->())? |
| select.swift:30 | init(_ chan: Chan<T>?, _ caseBlock: ((T?)->())?, _ defBlock: (()->())?){ |
| select.swift:30 | init(_ chan: Chan<T>?, _ caseBlock: ((T?)->())?, _ defBlock: (()->())?){ |
> : ItemAny {
0025 var closed| select.swift:57 | self.closed = closed |
= false
0026 var msg| select.swift:56 | self.msg = msg |
| select.swift:65 | block(msg) |
: T?
0027 var chan| select.swift:31 | (self.chan, self.caseBlock, self.defBlock) = (chan, caseBlock, defBlock) |
| select.swift:34 | if let chan = chan { |
| select.swift:41 | if let chan = chan { |
| select.swift:53 | if let chan = chan { |
: Chan<T>?
0028 var caseBlock| select.swift:31 | (self.chan, self.caseBlock, self.defBlock) = (chan, caseBlock, defBlock) |
| select.swift:64 | if let block = caseBlock { |
: ((T?)->())?
0029 var defBlock| select.swift:31 | (self.chan, self.caseBlock, self.defBlock) = (chan, caseBlock, defBlock) |
| select.swift:66 | } else if let block = defBlock { |
: (()->())?
0030 init(_ chan: Chan<T>?, _ caseBlock: ((T?)->())?, _ defBlock: (()->())?){
0031 (self.chan, self.caseBlock, self.defBlock) = (chan, caseBlock, defBlock)
0032 }
0033 func register(cond: Cond){
0034 if let chan = chan {
0035 chan.cond.mutex.lock()
0036 defer { chan.cond.mutex.unlock() }
0037 chan.gconds += [cond]
0038 }
0039 }
0040 func unregister(cond: Cond){
0041 if let chan = chan {
0042 chan.cond.mutex.lock()
0043 defer { chan.cond.mutex.unlock() }
0044 for i in 0..<chan.gconds.count {
0045 if chan.gconds[i] === cond {
0046 chan.gconds.removeAtIndex(i)
0047 return
0048 }
0049 }
0050 }
0051 }
0052 func get() -> Bool {
0053 if let chan = chan {
0054 let (msg, closed, ready) = chan.receive(false)
0055 if ready {
0056 self.msg = msg
0057 self.closed = closed
0058 return true
0059 }
0060 }
0061 return false
0062 }
0063 func call() {
0064 if let block = caseBlock {
0065 block(msg)
0066 } else if let block = defBlock {
0067 block()
0068 }
0069 }
0070
0071 }
0072
0073 private class ChanGroup| select.swift:148 | private var selectStack : [ChanGroup] = [] |
| select.swift:181 | let group = ChanGroup() |
{
0074 var cond| select.swift:100 | item.register(cond) |
| select.swift:104 | item.unregister(cond) |
| select.swift:121 | cond.mutex.lock() |
| select.swift:122 | cond.wait(0.25) |
| select.swift:123 | cond.mutex.unlock() |
= Cond(Mutex())
0075 var items| select.swift:78 | if items[chan.id] != nil { |
| select.swift:81 | items[chan.id] = Item<T>(chan, block, nil) |
| select.swift:85 | if items[0] != nil { |
| select.swift:88 | items[0] = Item<Void>(nil, nil, block) |
| select.swift:94 | if let item = items[ids[i]] { |
| select.swift:117 | if items[0] != nil { |
| select.swift:118 | ret = items[0] |
= [Int: ItemAny]()
0076 var ids| select.swift:82 | ids.append(chan.id) |
| select.swift:91 | let rids = randomInts(ids.count) |
| select.swift:94 | if let item = items[ids[i]] { |
= [Int]()
0077 func addCase| select.swift:194 | group.addCase(chan, block) |
<T>(chan: Chan<T>, _ block: (T?)->()){
0078 if items[chan.id] != nil {
0079 fatalError("selecting channel twice")
0080 }
0081 items[chan.id] = Item<T>(chan, block, nil)
0082 ids.append(chan.id)
0083 }
0084 func addDefault| select.swift:202 | group.addDefault(block) |
(block: ()->()){
0085 if items[0] != nil {
0086 fatalError("selecting default twice")
0087 }
0088 items[0] = Item<Void>(nil, nil, block)
0089 }
0090 func select| select.swift:187 | group.select() |
(){
0091 let rids = randomInts(ids.count)
0092 var citems = [ItemAny]()
0093 for i in rids {
0094 if let item = items[ids[i]] {
0095 citems.append(item)
0096 }
0097 }
0098 var ret : ItemAny?
0099 for item in citems {
0100 item.register(cond)
0101 }
0102 defer {
0103 for item in citems {
0104 item.unregister(cond)
0105 }
0106 if let item = ret {
0107 item.call()
0108 }
0109 }
0110 while true {
0111 for item in citems {
0112 if item.get() {
0113 ret = item
0114 return
0115 }
0116 }
0117 if items[0] != nil {
0118 ret = items[0]
0119 return
0120 }
0121 cond.mutex.lock()
0122 cond.wait(0.25)
0123 cond.mutex.unlock()
0124 }
0125 }
0126 func randomInts| select.swift:91 | let rids = randomInts(ids.count) |
(count : Int) -> [Int]{
0127 var ints = [Int](count: count, repeatedValue:0)
0128 for i in 0..<count {
0129 ints[i] = i
0130 }
0131 for i in 0..<count {
0132 #if os(Linux)
0133 let r = Int(random()) % count
0134 #else
0135 let r = Int(arc4random()) % count
0136 #endif
0137
0138 let t = ints[i]
0139 ints[i] = ints[r]
0140 ints[r] = t
0141 }
0142 return ints
0143 }
0144 }
0145
0146
0147 private let selectMutex| select.swift:182 | selectMutex.lock() |
| select.swift:186 | selectMutex.unlock() |
= Mutex()
0148 private var selectStack| select.swift:183 | selectStack += [group] |
| select.swift:185 | selectStack.removeLast() |
| select.swift:193 | if let group = selectStack.last{ |
| select.swift:201 | if let group = selectStack.last{ |
: [ChanGroup] = []
0149
0180 public func _select(block: ()->()){
0181 let group = ChanGroup()
0182 selectMutex.lock()
0183 selectStack += [group]
0184 block()
0185 selectStack.removeLast()
0186 selectMutex.unlock()
0187 group.select()
0188 }
0189
0192 public func _case<T>(chan: Chan<T>, block: (T?)->()){
0193 if let group = selectStack.last{
0194 group.addCase(chan, block)
0195 }
0196 }
0197
0200 public func _default(block: ()->()){
0201 if let group = selectStack.last{
0202 group.addDefault(block)
0203 }
0204 }
0205
0206
0207