ios - objc_sync_enter / objc_sync_exit not working with DISPATCH_QUEUE_PRIORITY_LOW -


i need read\write lock application. i've read https://en.wikipedia.org/wiki/readers%e2%80%93writer_lock

and wrote own class, cause there no read/write lock in swift

class readwritelock {      var logging = true     var b = 0     let r = "vdsbsdbs" // string1 locking     let g = "vsdbvsdbsdbnsdn" // string2 locking      func waitandstartwriting() {         log("wait writing")         objc_sync_enter(g)         log("enter writing")     }       func finishwriting() {         objc_sync_exit(g)         log("exit writing")     }      // ждет пока все чтение завершится чтобы начать чтение     // и захватить мютекс     func waitandstartreading() {          log("wait reading")         objc_sync_enter(r)         log("enter reading")         b++         if b == 1 {             objc_sync_enter(g)             log("read lock writing")         }          print("b = \(b)")         objc_sync_exit(r)     }       func finishreading() {          objc_sync_enter(r)          b--          if b == 0 {             objc_sync_exit(g)             log("read unlock writing")         }          print("b = \(b)")         objc_sync_exit(r)     }      private func log(s: string) {         if logging {             print(s)         }     } } 

it works good, until try use gcd threads.

dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_low, 0) dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0) 

when try use class different async blocks @ moment allows write when write locked

here sample log:

wait reading enter reading read lock writing b = 1 wait reading enter reading b = 2 wait reading enter reading b = 3 wait reading enter reading b = 4 wait reading enter reading b = 5 wait reading enter reading b = 6 wait reading enter reading b = 7 wait reading enter reading b = 8 wait reading enter reading b = 9 b = 8 b = 7 b = 6 b = 5 wait writing enter writing exit writing wait writing enter writing  

so, can see g locked, objc_sync_enter(g) allows continue. why happen ?

btw checked how many times readwritelock constructed, , it's 1.

why objc_sync_exit not working , allowing objc_sync_enter(g) when it's not freed ?

ps readwirtelock defined

class userdata {      static let lock = readwritelock() 

thanks.

objc_sync_enter extremely low-level primitive, , isn't intended used directly. it's implementation detail of old @synchronized system in objc. extremely out-dated , should avoided.

synchronized access in cocoa best achieved gcd queues. example, common approach achieves reader/writer lock (concurrent reading, exclusive writing).

public class userdata {     private let mypropertyqueue = dispatch_queue_create("com.example.mygreatapp.property", dispatch_queue_concurrent)      private var _myproperty = "" // backing storage     public var myproperty: string {         {             var result = ""             dispatch_sync(mypropertyqueue) {                 result = self._myproperty             }             return result         }          set {             dispatch_barrier_async(mypropertyqueue) {                 self._myproperty = newvalue             }         }     } } 

all concurrent properties can share single queue, or can give each property own queue. depends on how contention expect (a writer lock entire queue).

the "barrier" in "dispatch_barrier_async" means thing allowed run on queue @ time, previous reads have completed, , future reads prevented until completes. scheme means can have many concurrent readers want without starving writers (since writers serviced), , writes never blocking. on reads blocking, , if there actual contention. in normal, uncontested case, extremely fast.


Comments