@@ -34,10 +34,9 @@ chan.write(1) // happens immediately
3434let x1 = chan.read ()
3535
3636/// But if we read from an empty Channel the read blocks until we write to the Channel again.
37- let time = dispatch_time (DISPATCH_TIME_NOW, 1 * Double (NSEC_PER_SEC))
38- dispatch_after (time, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0 ), {
39- chan.write (2 ) // Causes the read to suceed and unblocks the reading thread.
40- })
37+ DispatchQueue.global ().asyncAfter (deadline : .now () + .seconds (1 )) {
38+ chan.write (2 ) // Causes the read to suceed and unblocks the reading thread.
39+ }
4140
4241let x2 = chan.read () // Blocks until the dispatch block is executed and the Channel becomes non-empty.
4342```
@@ -48,26 +47,26 @@ be accessed concurrently in an MVar.
4847``` swift
4948import class Concurrent .MVar
5049
51- /// An MVar (Mutable Variable) is a thread-safe synchronizing variable that can be used for
50+ /// An MVar (Mutable Variable) is a thread-safe synchronizing variable that can be used for
5251/// communication between threads.
53- ///
52+ ///
5453/// This MVar is currently empty. Any reads or writes to it will block until it becomes "full".
5554let counter : MVar<Int > = MVar ()
5655
57- /// Attempt to increment the counter from 3 different threads. Because the counter is empty,
56+ /// Attempt to increment the counter from 3 different threads. Because the counter is empty,
5857/// all of these writes will block until a value is put into the MVar.
59- dispatch_async ( dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0 ), {
60- counter.modify_ ( + 1 )
61- println (" Modifier #1" )
62- })
63- dispatch_async ( dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0 ), {
64- counter.modify_ ( + 1 )
65- println (" Modifier #2" )
66- })
67- dispatch_async ( dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0 ), {
68- counter.modify_ ( + 1 )
69- println (" Modifier #3" )
70- })
58+ DispatchQueue. global (). async {
59+ counter.modify_ { $0 + 1 }
60+ print (" Modifier #1" )
61+ }
62+ DispatchQueue. global (). async {
63+ counter.modify_ { $0 + 1 }
64+ print (" Modifier #2" )
65+ }
66+ DispatchQueue. global (). async {
67+ counter.modify_ { $0 + 1 }
68+ print (" Modifier #3" )
69+ }
7170
7271/// All the writes will now proceed and unblock each thread in turn. The order of writes
7372/// is determined by the order in which each thread called `modify(_ :)`.
@@ -82,7 +81,7 @@ counter.put(0)
8281///
8382/// Because our take occured after the put, all of the modifications we made before will
8483/// complete before we read the final value.
85- println (counter.take ()) // 3
84+ print (counter.take ()) // 3
8685```
8786
8887` MVar ` s can also be used purely as a synchronization point between multiple threads:
@@ -97,19 +96,19 @@ let done = MVar<()>() // The synchronization point
9796/// Puts a value into the now-empty ping variable then blocks waiting for the
9897/// pong variable to have a value put into it. Once we have read the pong variable,
9998/// we unblock the done MVar, and in doing so, unblock the main thread.
100- dispatch_async ( dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0 )) {
101- pingvar.put (" ping" )
102- let contents = pongvar.take ()
103- done.put (())
99+ DispatchQueue. global (). async {
100+ pingvar.put (" ping" )
101+ _ = pongvar.take ()
102+ done.put (())
104103}
105104
106105/// Takes the contents of the ping variable then puts a value into the pong variable
107106/// to unblock the take we just performed.
108- dispatch_async ( dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0 )) {
109- let contents = pingvar.take ()
110- pongvar.put (" pong" )
107+ DispatchQueue. global (). async {
108+ _ = pingvar.take ()
109+ pongvar.put (" pong" )
111110}
112-
111+
113112/// Blocks until all work has completed.
114113done.take ()
115114```
@@ -123,27 +122,28 @@ typealias Account = TVar<UInt>
123122
124123/// Some atomic operations
125124func withdraw (from account : Account, amount : UInt ) -> STM<()> {
126- return account.read ().flatMap { balance in
127- if balance > amount {
128- return account.write (balance - amount)
129- }
130- return STM < () > . pure (())
131- }
125+ return account.read ().flatMap { balance in
126+ if balance > amount {
127+ return account.write (balance - amount)
128+ }
129+ throw TransactionError. insufficientFunds
130+ }
132131}
132+
133133func deposit (into account : Account, amount : UInt ) -> STM<()> {
134- return account.read ().flatMap { balance in
135- return account.write (balance + amount)
136- }
134+ return account.read ().flatMap { balance in
135+ return account.write (balance + amount)
136+ }
137137}
138138
139139func transfer (from : Account, to : Account, amount : UInt ) -> STM<()> {
140- return from.read ().flatMap { fromBalance in
141- if fromBalance > amount {
142- return withdraw (from : from, amount : amount)
143- .then (deposit (into : to, amount : amount))
144- }
145- return STM< ()> .pure (())
140+ return from.read ().flatMap { fromBalance in
141+ if fromBalance > amount {
142+ return withdraw (from : from, amount : amount)
143+ .then (deposit (into : to, amount : amount))
146144 }
145+ throw TransactionError.insufficientFunds
146+ }
147147}
148148
149149/// Here are some bank accounts represented as TVars - transactional memory
@@ -155,8 +155,8 @@ let bob = Account(100)
155155/// Either all of the effects of this transaction apply to the accounts or
156156/// everything is completely rolled back and it was as if nothing ever happened.
157157let finalStatement =
158- transfer (from : alice, to : bob, 100 )
159- .then (transfer (from : bob, to : alice, 20 ))
158+ transfer (from : alice, to : bob, amount : 100 )
159+ .then (transfer (from : bob, to : alice, amount : 20 ))
160160 .then (deposit (into : bob, amount : 1000 ))
161161 .then (transfer (from : bob, to : alice, amount : 500 ))
162162 .atomically ()
0 commit comments