/* Ċ Ġ* ĠCopyright Ġ 2 0 1 6 - 2 0 2 0 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense . Ċ Ġ*/ Ċ Ċ package Ġkotlinx . coroutines . sync Ċ Ċ import Ġkotlinx . atomic fu .* Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . internal .* Ċ import Ġkotlinx . coroutines . intr insics .* Ċ import Ġkotlinx . coroutines . select s .* Ċ import Ġkotlin . contracts .* Ċ import Ġkotlin . coroutines .* Ċ import Ġkotlin . jvm .* Ċ import Ġkotlin . native . concurrent .* Ċ Ċ /** Ċ Ġ* ĠMut ual Ġex clusion Ġfor Ġcor outines . Ċ Ġ* Ċ Ġ* ĠMutex Ġhas Ġtwo Ġstates : Ġ_ locked _ Ġand Ġ_ unlocked _. Ċ Ġ* ĠIt Ġis Ġ** non - re entrant **, Ġthat Ġis Ġinvoking Ġ[ lock ] Ġeven Ġfrom Ġthe Ġsame Ġthread / coroutine Ġthat Ġcurrently Ġholds Ċ Ġ* Ġthe Ġlock Ġstill Ġsus p ends Ġthe Ġinvok er . Ċ Ġ* Ċ Ġ* ĠJVM ĠAPI Ġnote : Ċ Ġ* ĠMemory Ġsemantic Ġof Ġthe Ġ[ Mutex ] Ġis Ġsimilar Ġto Ġ` synchronized ` Ġblock Ġon ĠJVM : Ċ Ġ* ĠAn Ġunlock Ġon Ġa Ġ[ Mutex ] Ġhappens - before Ġevery Ġsubsequent Ġsuccessful Ġlock Ġon Ġthat Ġ[ Mutex ]. Ċ Ġ* ĠUn successful Ġcall Ġto Ġ[ try Lock ] Ġdo Ġnot Ġhave Ġany Ġmemory Ġeffects . Ċ Ġ*/ Ċ public Ġinterface ĠMutex Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġ` true ` Ġwhen Ġthis Ġmutex Ġis Ġlocked . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġval Ġis Locked : ĠBoolean ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠT ries Ġto Ġlock Ġthis Ġmutex , Ġreturning Ġ` false ` Ġif Ġthis Ġmutex Ġis Ġalready Ġlocked . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġowner ĠOptional Ġowner Ġtoken Ġfor Ġdebugging . ĠWhen Ġ` owner ` Ġis Ġspecified Ġ( non - null Ġvalue ) Ġand Ġthis Ġmutex ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠ Ġis Ġalready Ġlocked Ġwith Ġthe Ġsame Ġtoken Ġ( same Ġidentity ), Ġthis Ġfunction Ġthrows Ġ[ IllegalStateException ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġtry Lock ( owner : ĠAny ? Ġ= Ġnull ): ĠBoolean ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLock s Ġthis Ġmutex , Ġsus pending Ġcaller Ġwhile Ġthe Ġmutex Ġis Ġlocked . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġsus pending Ġfunction Ġis Ġcancell able . ĠIf Ġthe Ġ[ Job ] Ġof Ġthe Ġcurrent Ġcoroutine Ġis Ġcancelled Ġor Ġcompleted Ġwhile Ġthis ĊĠĠĠĠ Ġ* Ġfunction Ġis Ġsus pended , Ġthis Ġfunction Ġimmediately Ġresume s Ġwith Ġ[ Cancellation Exception ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ* Cancellation Ġof Ġsus pended Ġlock Ġinvocation Ġis Ġatomic * Ġ-- Ġwhen Ġthis Ġfunction ĊĠĠĠĠ Ġ* Ġthrows Ġ[ Cancellation Exception ] Ġit Ġmeans Ġthat Ġthe Ġmutex Ġwas Ġnot Ġlocked . ĊĠĠĠĠ Ġ* ĠAs Ġa Ġside - effect Ġof Ġatomic Ġcancellation , Ġa Ġthread - bound Ġcoroutine Ġ( to Ġsome ĠUI Ġthread , Ġfor Ġexample ) Ġmay ĊĠĠĠĠ Ġ* Ġcontinue Ġto Ġexecute Ġeven Ġafter Ġit Ġwas Ġcancelled Ġfrom Ġthe Ġsame Ġthread Ġin Ġthe Ġcase Ġwhen Ġthis Ġlock Ġoperation ĊĠĠĠĠ Ġ* Ġwas Ġalready Ġres umed Ġand Ġthe Ġcontinuation Ġwas Ġposted Ġfor Ġexecution Ġto Ġthe Ġthread 's Ġqueue . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠNote Ġthat Ġthis Ġfunction Ġdoes Ġnot Ġcheck Ġfor Ġcancellation Ġwhen Ġit Ġis Ġnot Ġsus pended . ĊĠĠĠĠ Ġ* ĠUse Ġ[ yield ] Ġor Ġ[ Coroutine Scope . isActive ] Ġto Ġperiodically Ġcheck Ġfor Ġcancellation Ġin Ġtight Ġloops Ġif Ġneeded . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġfunction Ġcan Ġbe Ġused Ġin Ġ[ select ] Ġinvocation Ġwith Ġ[ on Lock ] Ġclause . ĊĠĠĠĠ Ġ* ĠUse Ġ[ try Lock ] Ġto Ġtry Ġacquire Ġlock Ġwithout Ġwaiting . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġfunction Ġis Ġfair ; Ġsus pended Ġcall ers Ġare Ġres umed Ġin Ġfirst - in - first - out Ġorder . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġowner ĠOptional Ġowner Ġtoken Ġfor Ġdebugging . ĠWhen Ġ` owner ` Ġis Ġspecified Ġ( non - null Ġvalue ) Ġand Ġthis Ġmutex ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠ Ġis Ġalready Ġlocked Ġwith Ġthe Ġsame Ġtoken Ġ( same Ġidentity ), Ġthis Ġfunction Ġthrows Ġ[ IllegalStateException ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġsuspend Ġfun Ġlock ( owner : ĠAny ? Ġ= Ġnull ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠClause Ġfor Ġ[ select ] Ġexpression Ġof Ġ[ lock ] Ġsus pending Ġfunction Ġthat Ġselects Ġwhen Ġthe Ġmutex Ġis Ġlocked . ĊĠĠĠĠ Ġ* ĠAdditional Ġparameter Ġfor Ġthe Ġclause Ġin Ġthe Ġ` owner ` Ġ( see Ġ[ lock ]) Ġand Ġwhen Ġthe Ġclause Ġis Ġselected ĊĠĠĠĠ Ġ* Ġthe Ġreference Ġto Ġthis Ġmutex Ġis Ġpassed Ġinto Ġthe Ġcorresponding Ġblock . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġval Ġon Lock : ĠSelect Clause 2 < Any ?, ĠMutex > ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġmutex Ġlocked Ġby Ġowner ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġ` true ` Ġon Ġmutex Ġlock Ġby Ġowner , Ġ` false ` Ġif Ġnot Ġlock er Ġor Ġit Ġis Ġlocked Ġby Ġdifferent Ġowner ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġholds Lock ( owner : ĠAny ): ĠBoolean ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUn locks Ġthis Ġmutex . ĠThrows Ġ[ IllegalStateException ] Ġif Ġinvoked Ġon Ġa Ġmutex Ġthat Ġis Ġnot Ġlocked Ġor ĊĠĠĠĠ Ġ* Ġwas Ġlocked Ġwith Ġa Ġdifferent Ġowner Ġtoken Ġ( by Ġidentity ). ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġowner ĠOptional Ġowner Ġtoken Ġfor Ġdebugging . ĠWhen Ġ` owner ` Ġis Ġspecified Ġ( non - null Ġvalue ) Ġand Ġthis Ġmutex ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠ Ġwas Ġlocked Ġwith Ġthe Ġdifferent Ġtoken Ġ( by Ġidentity ), Ġthis Ġfunction Ġthrows Ġ[ IllegalStateException ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġunlock ( owner : ĠAny ? Ġ= Ġnull ) Ċ } Ċ Ċ /** Ċ Ġ* ĠCreates Ġa Ġ[ Mutex ] Ġinstance . Ċ Ġ* ĠThe Ġmutex Ġcreated Ġis Ġfair : Ġlock Ġis Ġgranted Ġin Ġfirst Ġcome , Ġfirst Ġserved Ġorder . Ċ Ġ* Ċ Ġ* Ġ@ param Ġlocked Ġinitial Ġstate Ġof Ġthe Ġmutex . Ċ Ġ*/ Ċ @ Suppress (" FunctionName ") Ċ public Ġfun ĠMutex ( locked : ĠBoolean Ġ= Ġfalse ): ĠMutex Ġ= ĊĠĠĠ ĠMutex Impl ( locked ) Ċ Ċ /** Ċ Ġ* ĠExec utes Ġthe Ġgiven Ġ[ action ] Ġunder Ġthis Ġmutex 's Ġlock . Ċ Ġ* Ċ Ġ* Ġ@ param Ġowner ĠOptional Ġowner Ġtoken Ġfor Ġdebugging . ĠWhen Ġ` owner ` Ġis Ġspecified Ġ( non - null Ġvalue ) Ġand Ġthis Ġmutex Ċ Ġ* ĠĠĠĠĠĠĠ Ġis Ġalready Ġlocked Ġwith Ġthe Ġsame Ġtoken Ġ( same Ġidentity ), Ġthis Ġfunction Ġthrows Ġ[ IllegalStateException ]. Ċ Ġ* Ċ Ġ* Ġ@ return Ġthe Ġreturn Ġvalue Ġof Ġthe Ġaction . Ċ Ġ*/ Ċ @ Opt In ( Experimental Contracts :: class ) Ċ public Ġsuspend Ġinline Ġfun Ġ< T > ĠMutex . with Lock ( owner : ĠAny ? Ġ= Ġnull , Ġaction : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠ Ġcontract Ġ{ ĠĊĠĠĠĠĠĠĠ Ġcalls In Place ( action , ĠInvocation Kind . EX ACT LY _ ON CE ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġlock ( owner ) ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġaction () ĊĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġunlock ( owner ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Shared Immutable Ċ private Ġval ĠLOCK _ FAIL Ġ= ĠSymbol (" LOCK _ FAIL ") Ċ @ Shared Immutable Ċ private Ġval ĠEN QUEUE _ FAIL Ġ= ĠSymbol (" EN QUEUE _ FAIL ") Ċ @ Shared Immutable Ċ private Ġval ĠUN LOCK _ FAIL Ġ= ĠSymbol (" UNLOCK _ FAIL ") Ċ @ Shared Immutable Ċ private Ġval ĠSELECT _ SUCCESS Ġ= ĠSymbol (" SELECT _ SUCCESS ") Ċ @ Shared Immutable Ċ private Ġval ĠLOCK ED Ġ= ĠSymbol (" LOCK ED ") Ċ @ Shared Immutable Ċ private Ġval ĠUN LOCK ED Ġ= ĠSymbol (" UNLOCK ED ") Ċ Ċ @ Shared Immutable Ċ private Ġval ĠEMPTY _ LOCK ED Ġ= ĠEmpty ( LOCK ED ) Ċ @ Shared Immutable Ċ private Ġval ĠEMPTY _ UNLOCK ED Ġ= ĠEmpty ( UNLOCK ED ) Ċ Ċ private Ġclass ĠEmpty ( ĊĠĠĠ Ġ@ Jvm Field Ġval Ġlocked : ĠAny Ċ ) Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Empty [$ locked ]" Ċ } Ċ Ċ internal Ġclass ĠMutex Impl ( locked : ĠBoolean ) Ġ: ĠMutex , ĠSelect Clause 2 < Any ?, ĠMutex > Ġ{ ĊĠĠĠ Ġ// ĠState Ġis : ĠEmpty Ġ| ĠLocked Queue Ġ| ĠOp Descriptor ĊĠĠĠ Ġ// Ġshared Ġobjects Ġwhile Ġwe Ġhave Ġno Ġwait ers ĊĠĠĠ Ġprivate Ġval Ġ_ state Ġ= Ġatomic < Any ? >( if Ġ( locked ) ĠEMPTY _ LOCK ED Ġelse ĠEMPTY _ UNLOCK ED ) ĊĊĠĠĠ Ġpublic Ġoverride Ġval Ġis Locked : ĠBoolean Ġget () Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ state . loop Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġreturn Ġstate . locked Ġ!== ĠUN LOCK ED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOp Descriptor Ġ-> Ġstate . perform ( this ) Ġ// Ġhelp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Illegal Ġstate Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġfor Ġtests ĠONLY ĊĠĠĠ Ġinternal Ġval Ġis Locked Empty Queue State : ĠBoolean Ġget () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġ_ state . value ĊĠĠĠĠĠĠĠ Ġreturn Ġstate Ġis ĠLocked Queue Ġ&& Ġstate . isEmpty ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġoverride Ġfun Ġtry Lock ( owner : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ state . loop Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . locked Ġ!== ĠUN LOCK ED ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate Ġ= Ġif Ġ( owner Ġ== Ġnull ) ĠEMPTY _ LOCK ED Ġelse ĠEmpty ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġowner ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(_ state . compare AndSet ( state , Ġupdate )) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( state . owner Ġ!== Ġowner ) Ġ{ Ġ" Already Ġlocked Ġby Ġ$ owner " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOp Descriptor Ġ-> Ġstate . perform ( this ) Ġ// Ġhelp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Illegal Ġstate Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġoverride Ġsuspend Ġfun Ġlock ( owner : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġfast - path Ġ-- Ġtry Ġlock ĊĠĠĠĠĠĠĠ Ġif Ġ( try Lock ( owner )) Ġreturn ĊĠĠĠĠĠĠĠ Ġ// Ġslow - path Ġ-- Ġsuspend ĊĠĠĠĠĠĠĠ Ġreturn Ġlock Suspend ( owner ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġlock Suspend ( owner : ĠAny ?) Ġ= Ġsuspend Atomic C ancellable Coroutine Re usable < Unit > Ġsc @ Ġ{ Ġcont Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġwait er Ġ= ĠLock Cont ( owner , Ġcont ) ĊĠĠĠĠĠĠĠ Ġ_ state . loop Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . locked Ġ!== ĠUN LOCK ED ) Ġ{ Ġ Ġ// Ġtry Ġupgrade Ġto Ġqueue Ġ& Ġretry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ state . compare AndSet ( state , ĠLocked Queue ( state . locked )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġlock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate Ġ= Ġif Ġ( owner Ġ== Ġnull ) ĠEMPTY _ LOCK ED Ġelse ĠEmpty ( owner ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(_ state . compare AndSet ( state , Ġupdate )) Ġ{ Ġ// Ġlocked ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcont . resume ( Unit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ sc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcur Owner Ġ= Ġstate . owner ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( cur Owner Ġ!== Ġowner ) Ġ{ Ġ" Already Ġlocked Ġby Ġ$ owner " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . add Last If ( wait er ) Ġ{ Ġ_ state . value Ġ=== Ġstate Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġadded Ġto Ġwait er Ġlist ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcont . remove On Cancellation ( wait er ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ sc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOp Descriptor Ġ-> Ġstate . perform ( this ) Ġ// Ġhelp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Illegal Ġstate Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġon Lock : ĠSelect Clause 2 < Any ?, ĠMutex > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġthis ĊĊĠĠĠ Ġ// Ġregister Select Lock ĊĠĠĠ Ġ@ Suppress (" PARAMETER _ NAME _ CHANGED _ ON _ OVERRIDE ") ĊĠĠĠ Ġoverride Ġfun Ġ< R > Ġregister Select Clause 2 ( select : ĠSelect Instance < R >, Ġowner : ĠAny ?, Ġblock : Ġsuspend Ġ( Mutex ) Ġ-> ĠR ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ Ġ// Ġlock - free Ġloop Ġon Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( select . isSelected ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġstate Ġ= Ġ_ state . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . locked Ġ!== ĠUN LOCK ED ) Ġ{ Ġ// Ġtry Ġupgrade Ġto Ġqueue Ġ& Ġretry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ state . compare AndSet ( state , ĠLocked Queue ( state . locked )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġlock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= Ġselect . perform Atomic Try Select ( Try Lock Desc ( this , Ġowner )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ== Ġnull Ġ-> Ġ{ Ġ// Ġsuccess ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock . start Coroutine Un intercept ed ( receiver Ġ= Ġthis , Ġcompletion Ġ= Ġselect . completion ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ=== ĠAL READY _ SELECTED Ġ-> Ġreturn Ġ// Ġalready Ġselected Ġ-- Ġbail Ġout ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ=== ĠLOCK _ FAIL Ġ-> Ġ{} Ġ// Ġretry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ=== ĠRET RY _ ATOMIC Ġ-> Ġ{} Ġ// Ġretry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" perform Atomic Try Select ( Try Lock Desc ) Ġreturned Ġ$ failure ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( state . owner Ġ!== Ġowner ) Ġ{ Ġ" Already Ġlocked Ġby Ġ$ owner " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Ġ= ĠLock Select ( owner , Ġthis , Ġselect , Ġblock ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . add Last If ( node ) Ġ{ Ġ_ state . value Ġ=== Ġstate Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsuccessfully Ġen queued ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselect . dispose On Select ( node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOp Descriptor Ġ-> Ġstate . perform ( this ) Ġ// Ġhelp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Illegal Ġstate Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠTry Lock Desc ( ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġmutex : ĠMutex Impl , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġowner : ĠAny ? ĊĠĠĠ Ġ) Ġ: ĠAtomic Desc () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġis ĠH arris 's ĠR DC SS Ġ( Restricted ĠDouble - Compare ĠSingle ĠSwap ) Ġoperation ĊĠĠĠĠĠĠĠ Ġprivate Ġinner Ġclass ĠPrepare Op ( override Ġval Ġatomic Op : ĠAtomic Op <* >) Ġ: ĠOp Descriptor () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġperform ( affected : ĠAny ?): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate : ĠAny Ġ= Ġif Ġ( atomic Op . is Dec ided ) ĠEMPTY _ UNLOCK ED Ġelse Ġatomic Op Ġ// Ġrestore Ġif Ġwas Ġalready Ġdecided ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( affected Ġas ĠMutex Impl )._ state . compare AndSet ( this , Ġupdate ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull Ġ// Ġok ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġprepare ( op : ĠAtomic Op < *> ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprepare Ġ= ĠPrepare Op ( op ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! mutex ._ state . compare AndSet ( EMPTY _ UNLOCK ED , Ġprepare )) Ġreturn ĠLOCK _ FAIL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġprepare . perform ( mutex ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcomplete ( op : ĠAtomic Op <* >, Ġfailure : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate Ġ= Ġif Ġ( failure Ġ!= Ġnull ) ĠEMPTY _ UNLOCK ED Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( owner Ġ== Ġnull ) ĠEMPTY _ LOCK ED Ġelse ĠEmpty ( owner ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmutex ._ state . compare AndSet ( op , Ġupdate ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġoverride Ġfun Ġholds Lock ( owner : ĠAny ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ state . value . let Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġstate . locked Ġ=== Ġowner ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġstate . owner Ġ=== Ġowner ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġoverride Ġfun Ġunlock ( owner : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ state . loop Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( owner Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( state . locked Ġ!== ĠUN LOCK ED ) Ġ{ Ġ" Mutex Ġis Ġnot Ġlocked " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( state . locked Ġ=== Ġowner ) Ġ{ Ġ" Mutex Ġis Ġlocked Ġby Ġ${ state . locked } Ġbut Ġexpected Ġ$ owner " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(_ state . compare AndSet ( state , ĠEMPTY _ UNLOCK ED )) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOp Descriptor Ġ-> Ġstate . perform ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( owner Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( state . owner Ġ=== Ġowner ) Ġ{ Ġ" Mutex Ġis Ġlocked Ġby Ġ${ state . owner } Ġbut Ġexpected Ġ$ owner " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwait er Ġ= Ġstate . remove First OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( wait er Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġop Ġ= ĠUn lock Op ( state ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(_ state . compare AndSet ( state , Ġop ) Ġ&& Ġop . perform ( this ) Ġ== Ġnull ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġ( wait er Ġas ĠLock Wait er ). try Resume Lock Wait er () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( token Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . owner Ġ= Ġwait er . owner Ġ?: ĠLOCK ED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwait er . complete Resume Lock Wait er ( token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Illegal Ġstate Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ state . loop Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Ġ-> Ġreturn Ġ" Mutex [ ${ state . locked }] " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠOp Descriptor Ġ-> Ġstate . perform ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLocked Queue Ġ-> Ġreturn Ġ" Mutex [ ${ state . owner }] " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Illegal Ġstate Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠLocked Queue ( ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġvar Ġowner : ĠAny ĊĠĠĠ Ġ) Ġ: ĠLock Free LinkedList Head () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Locked Queue [$ owner ]" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġabstract Ġclass ĠLock Wait er ( ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġowner : ĠAny ? ĊĠĠĠ Ġ) Ġ: ĠLock Free LinkedList Node (), ĠDis posable Handle Ġ{ ĊĠĠĠĠĠĠĠ Ġfinal Ġoverride Ġfun Ġdispose () Ġ{ Ġremove () Ġ} ĊĠĠĠĠĠĠĠ Ġabstract Ġfun Ġtry Resume Lock Wait er (): ĠAny ? ĊĠĠĠĠĠĠĠ Ġabstract Ġfun Ġcomplete Resume Lock Wait er ( token : ĠAny ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠLock Cont ( ĊĠĠĠĠĠĠĠ Ġowner : ĠAny ?, ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġcont : ĠC ancellable Continuation < Unit > ĊĠĠĠ Ġ) Ġ: ĠLock Wait er ( owner ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġtry Resume Lock Wait er () Ġ= Ġcont . try Resume ( Unit ) ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcomplete Resume Lock Wait er ( token : ĠAny ) Ġ= Ġcont . complete Resume ( token ) ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Lock Cont [$ owner , Ġ$ cont ]" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠLock Select < R >( ĊĠĠĠĠĠĠĠ Ġowner : ĠAny ?, ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġmutex : ĠMutex , ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġselect : ĠSelect Instance < R >, ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġblock : Ġsuspend Ġ( Mutex ) Ġ-> ĠR ĊĠĠĠ Ġ) Ġ: ĠLock Wait er ( owner ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġtry Resume Lock Wait er (): ĠAny ? Ġ= Ġif Ġ( select . try Select ()) ĠSELECT _ SUCCESS Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcomplete Resume Lock Wait er ( token : ĠAny ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert Ġ{ Ġtoken Ġ=== ĠSELECT _ SUCCESS Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock . start Coroutine ( receiver Ġ= Ġmutex , Ġcompletion Ġ= Ġselect . completion ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Lock Select [$ owner , Ġ$ mutex , Ġ$ select ]" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġatomic Ġunlock Ġoperation Ġthat Ġchecks Ġthat Ġwait ers Ġqueue Ġis Ġempty ĊĠĠĠ Ġprivate Ġclass ĠUn lock Op ( ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field Ġval Ġqueue : ĠLocked Queue ĊĠĠĠ Ġ) Ġ: ĠAtomic Op < Mutex Impl >() Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġprepare ( affected : ĠMutex Impl ): ĠAny ? Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( queue . isEmpty ) Ġnull Ġelse ĠUN LOCK _ FAIL ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcomplete ( affected : ĠMutex Impl , Ġfailure : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate : ĠAny Ġ= Ġif Ġ( failure Ġ== Ġnull ) ĠEMPTY _ UNLOCK ED Ġelse Ġqueue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaffected ._ state . compare AndSet ( this , Ġupdate ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ