/* Ċ Ġ* ĠCopyright Ġ 2 0 1 6 - 2 0 2 1 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense . Ċ Ġ*/ Ċ Ċ package Ġkotlinx . coroutines . channels Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . internal .* Ċ import Ġkotlinx . coroutines . select s .* Ċ Ċ /** Ċ Ġ* ĠChannel Ġthat Ġbuffers Ġat Ġmost Ġone Ġelement Ġand Ġcon fl ates Ġall Ġsubsequent Ġ` send ` Ġand Ġ` try Send ` Ġinv ocations , Ċ Ġ* Ġso Ġthat Ġthe Ġreceiver Ġalways Ġgets Ġthe Ġmost Ġrecently Ġsent Ġelement . Ċ Ġ* ĠBack - to - send Ġsent Ġelements Ġare Ġ_ con fl ated _ Ġ-- Ġonly Ġthe Ġmost Ġrecently Ġsent Ġelement Ġis Ġreceived , Ċ Ġ* Ġwhile Ġpreviously Ġsent Ġelements Ġ** are Ġlost **. Ċ Ġ* ĠSender Ġto Ġthis Ġchannel Ġnever Ġsus p ends Ġand Ġ[ try Send ] Ġalways Ġsucceeds . Ċ Ġ* Ċ Ġ* ĠThis Ġchannel Ġis Ġcreated Ġby Ġ` Channel ( Channel . CON FL ATED )` Ġfactory Ġfunction Ġinvocation . Ċ Ġ*/ Ċ internal Ġopen Ġclass ĠCon fl ated Channel < E >( on Un deliver ed Element : ĠOn Un deliver ed Element < E > ?) Ġ: ĠAbstract Channel < E >( on Un deliver ed Element ) Ġ{ ĊĠĠĠ Ġprotected Ġfinal Ġoverride Ġval Ġis Buffer Always Empty : ĠBoolean Ġget () Ġ= Ġfalse ĊĠĠĠ Ġprotected Ġfinal Ġoverride Ġval Ġis Buffer Empty : ĠBoolean Ġget () Ġ= Ġvalue Ġ=== ĠEMPTY ĊĠĠĠ Ġprotected Ġfinal Ġoverride Ġval Ġis Buffer Always Full : ĠBoolean Ġget () Ġ= Ġfalse ĊĠĠĠ Ġprotected Ġfinal Ġoverride Ġval Ġis Buffer Full : ĠBoolean Ġget () Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġval ĠisEmpty : ĠBoolean Ġget () Ġ= Ġlock . with Lock Ġ{ ĠisEmpty Impl Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġlock Ġ= ĠRe entrant Lock () ĊĊĠĠĠ Ġprivate Ġvar Ġvalue : ĠAny ? Ġ= ĠEMPTY ĊĊĠĠĠ Ġ// Ġresult Ġis Ġ` OFF ER _ SUCCESS Ġ| ĠClosed ` ĊĠĠĠ Ġprotected Ġoverride Ġfun Ġoffer Internal ( element : ĠE ): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġreceive : ĠReceive Or Closed < E >? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed For Send ?. let Ġ{ Ġreturn Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġthere Ġis Ġno Ġelement Ġwritten Ġin Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ=== ĠEMPTY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġfor Ġreceiv ers Ġthat Ġwere Ġwaiting Ġon Ġthe Ġempty Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloop @ Ġwhile ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreceive Ġ= Ġtake First Receive Or Peek Closed () Ġ?: Ġbreak @ loop Ġ// Ġbreak Ġwhen Ġno Ġreceiv ers Ġqueued ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( receive Ġis ĠClosed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġreceive !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġreceive !!. try Resume Receive ( element , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( token Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert Ġ{ Ġtoken Ġ=== ĠRES UME _ TOKEN Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Lock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Value Locked ( element )?. let Ġ{ Ġthrow Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠO FFER _ SUCCESS ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġbreaks Ġhere Ġif Ġoffer Ġme ets Ġreceiver ĊĠĠĠĠĠĠĠ Ġreceive !!. complete Resume Receive ( element ) ĊĠĠĠĠĠĠĠ Ġreturn Ġreceive !!. offer Result ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġresult Ġis Ġ` AL READY _ SELECTED Ġ| ĠO FFER _ SUCCESS Ġ| ĠClosed ` ĊĠĠĠ Ġprotected Ġoverride Ġfun Ġoffer Select Internal ( element : ĠE , Ġselect : ĠSelect Instance < *> ): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġreceive : ĠReceive Or Closed < E >? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed For Send ?. let Ġ{ Ġreturn Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ=== ĠEMPTY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloop @ Ġwhile ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoffer Op Ġ= Ġdescribe Try Offer ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= Ġselect . perform Atomic Try Select ( offer Op ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ== Ġnull Ġ-> Ġ{ Ġ// Ġoffered Ġsuccessfully ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreceive Ġ= Ġoffer Op . result ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Lock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ=== ĠO FFER _ FAILED Ġ-> Ġbreak @ loop Ġ// Ġcannot Ġoffer Ġ-> ĠOk Ġto Ġqueue Ġto Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ=== ĠRET RY _ ATOMIC Ġ-> Ġ{} Ġ// Ġretry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailure Ġ=== ĠAL READY _ SELECTED Ġ|| Ġfailure Ġis ĠClosed < *> Ġ-> Ġreturn Ġfailure ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" perform Atomic Try Select ( describe Try Offer ) Ġreturned Ġ$ failure ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġto Ġselect Ġsending Ġthis Ġelement Ġto Ġbuffer ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! select . try Select ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠAL READY _ SELECTED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Value Locked ( element )?. let Ġ{ Ġthrow Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠO FFER _ SUCCESS ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġbreaks Ġhere Ġif Ġoffer Ġme ets Ġreceiver ĊĠĠĠĠĠĠĠ Ġreceive !!. complete Resume Receive ( element ) ĊĠĠĠĠĠĠĠ Ġreturn Ġreceive !!. offer Result ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġresult Ġis Ġ` E Ġ| ĠPOL L _ FAILED Ġ| ĠClosed ` ĊĠĠĠ Ġprotected Ġoverride Ġfun Ġpoll Internal (): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult : ĠAny ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ=== ĠEMPTY ) Ġreturn Ġclosed For Send Ġ?: ĠPOL L _ FAILED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= ĠEMPTY ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġresult Ġis Ġ` E Ġ| ĠPOL L _ FAILED Ġ| ĠClosed ` ĊĠĠĠ Ġprotected Ġoverride Ġfun Ġpoll Select Internal ( select : ĠSelect Instance < *> ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult : ĠAny ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ=== ĠEMPTY ) Ġreturn Ġclosed For Send Ġ?: ĠPOL L _ FAILED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! select . try Select ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠAL READY _ SELECTED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= ĠEMPTY ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġoverride Ġfun Ġon Cancel Ide mpot ent ( was Closed : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġun deliver ed ElementException : ĠUn deliver ed ElementException ? Ġ= Ġnull Ġ// Ġresource Ġcancel Ġexception ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun deliver ed ElementException Ġ= Ġupdate Value Locked ( EMPTY ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsuper . on Cancel Ide mpot ent ( was Closed ) ĊĠĠĠĠĠĠĠ Ġun deliver ed ElementException ?. let Ġ{ Ġthrow Ġit Ġ} Ġ// Ġthrow ĠUn deliver ed ElementException Ġat Ġthe Ġend Ġif Ġthere Ġwas Ġone ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Value Locked ( element : ĠAny ?): ĠUn deliver ed ElementException ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġold Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġval Ġun deliver ed ElementException Ġ= Ġif Ġ( old Ġ=== ĠEMPTY ) Ġnull Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Un deliver ed Element ?. call Un deliver ed Element Catch ing Exception ( old Ġas ĠE ) ĊĠĠĠĠĠĠĠ Ġvalue Ġ= Ġelement ĊĠĠĠĠĠĠĠ Ġreturn Ġun deliver ed ElementException ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġenqueue Receive Internal ( receive : ĠReceive < E >): ĠBoolean Ġ= Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . enqueue Receive Internal ( receive ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġ------ Ġdebug Ġ------ ĊĊĠĠĠ Ġoverride Ġval Ġbuffer Debug String : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ"( value =$ value )" Ċ } Ċ