/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 2 0 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ċ Ġ* Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ġ*/ Ċ Ċ package Ġkotlin . native . internal Ċ Ċ import Ġkotlin . native . concurrent .* Ċ import Ġkotlinx . c interop . Native Ptr Ċ Ċ public Ġinterface ĠClean er Ċ Ċ /** Ċ Ġ* ĠCreates Ġan Ġobject Ġwith Ġa Ġcleanup Ġassociated . Ċ Ġ* Ċ Ġ* ĠAfter Ġthe Ġresulting Ġobject Ġ(" clean er ") Ġgets Ġde allocated Ġby Ġmemory Ġmanager , Ċ Ġ* Ġ[ block ] Ġis Ġeventually Ġcalled Ġonce Ġwith Ġ[ argument ]. Ċ Ġ* Ċ Ġ* ĠExample Ġof Ġusage : Ċ Ġ* Ġ``` Ċ Ġ* Ġclass ĠResource Wrapper Ġ{ Ċ Ġ* ĠĠĠĠ Ġprivate Ġval Ġresource Ġ= ĠResource () Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġprivate Ġval Ġcleaner Ġ= Ġcreate Clean er ( resource ) Ġ{ Ġit . dispose () Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠWhen Ġ` Resource Wrapper ` Ġbecomes Ġunused Ġand Ġgets Ġde allocated , Ġits Ġ` clean er ` Ċ Ġ* Ġis Ġalso Ġde allocated , Ġand Ġthe Ġresource Ġis Ġdisposed Ġlater . Ċ Ġ* Ċ Ġ* ĠIt Ġis Ġnot Ġspecified Ġwhich Ġthread Ġruns Ġ[ block ], Ġas Ġwell Ġas Ġwhether Ġtwo Ġor Ġmore Ċ Ġ* Ġblocks Ġfrom Ġdifferent Ġclean ers Ġcan Ġbe Ġrun Ġin Ġparallel . Ċ Ġ* Ċ Ġ* ĠNote : Ġif Ġ[ argument ] Ġrefers Ġ( direct ly Ġor Ġindirect ly ) Ġthe Ġcleaner , Ġthen Ġboth Ċ Ġ* Ġmight Ġleak , Ġand Ġthe Ġ[ block ] Ġwill Ġnot Ġbe Ġcalled Ġin Ġthis Ġcase . Ċ Ġ* ĠFor Ġexample , Ġthe Ġcode Ġbelow Ġhas Ġa Ġleak : Ċ Ġ* Ġ``` Ċ Ġ* Ġclass ĠLe aking Resource Wrapper Ġ{ Ċ Ġ* ĠĠĠĠ Ġprivate Ġval Ġresource Ġ= ĠResource () Ċ Ġ* ĠĠĠĠ Ġprivate Ġval Ġcleaner Ġ= Ġcreate Clean er ( this ) Ġ{ Ġit . resource . dispose () Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* ĠIn Ġthis Ġcase Ġcleaner 's Ġargument Ġ(` Le aking Resource Wrapper `) Ġcan 't Ġbe Ġde allocated Ċ Ġ* Ġuntil Ġcleaner 's Ġblock Ġis Ġexecuted , Ġwhich Ġcan Ġhappen Ġonly Ġstrictly Ġafter Ċ Ġ* Ġthe Ġcleaner Ġis Ġde allocated , Ġwhich Ġcan 't Ġhappen Ġuntil Ġ` Le aking Resource Wrapper ` Ċ Ġ* Ġis Ġde allocated . ĠSo Ġthe Ġrequirements Ġon Ġobject Ġde alloc ations Ġare Ġcontr ad ictory Ċ Ġ* Ġin Ġthis Ġcase , Ġwhich Ġcan 't Ġbe Ġhandled Ġgrace fully . ĠThe Ġcleaner 's Ġblock Ċ Ġ* Ġis Ġnot Ġexecuted Ġthen , Ġand Ġcleaner Ġand Ġits Ġargument Ġmight Ġleak Ċ Ġ* Ġ( depend ing Ġon Ġthe Ġimplementation ). Ċ Ġ* Ċ Ġ* Ġ[ block ] Ġshould Ġnot Ġuse Ġ`@ Thread Local ` Ġglobals , Ġbecause Ġit Ġmay Ċ Ġ* Ġbe Ġexecuted Ġon Ġa Ġdifferent Ġthread . Ċ Ġ* Ċ Ġ* ĠIf Ġ[ block ] Ġthrows Ġan Ġexception , Ġthe Ġbehavior Ġis Ġunspecified . Ċ Ġ* Ċ Ġ* ĠClean ers Ġshould Ġnot Ġbe Ġkept Ġin Ġglobals , Ġbecause Ġif Ġcleaner Ġis Ġnot Ġde allocated Ċ Ġ* Ġbefore Ġexiting Ġmain (), Ġit 'll Ġnever Ġget Ġexecuted . Ċ Ġ* ĠUse Ġ` Platform . is Clean ers Leak Checker Active ` Ġto Ġwarn Ġabout Ġun executed Ġclean ers . Ċ Ġ* Ċ Ġ* ĠIf Ġclean ers Ġare Ġnot ĠGC 'd Ġbefore Ġmain () Ġexits , Ġthen Ġit 's Ġnot Ġguaranteed Ġthat Ċ Ġ* Ġthey Ġwill Ġbe Ġrun . ĠMore over , Ġit Ġdepends Ġon Ġ` Platform . is Clean ers Leak Checker Active `. Ċ Ġ* ĠWith Ġthe Ġchecker Ġenabled , Ġclean ers Ġwill Ġbe Ġrun Ġ( and Ġtherefore Ġnot Ġreported Ġas Ċ Ġ* Ġun executed Ġclean ers ); Ġwith Ġthe Ġchecker Ġdisabled Ġ- Ġthey Ġmight Ġnot Ġget Ġrun . Ċ Ġ* Ċ Ġ* Ġ@ param Ġargument Ġmust Ġbe Ġshare able Ċ Ġ* Ġ@ param Ġblock Ġmust Ġnot Ġcapture Ġanything Ċ Ġ*/ Ċ // ĠTODO : ĠConsider Ġjust Ġannot ating Ġthe Ġlambda Ġargument Ġrather Ġthan Ġhard coding Ġchecking Ċ // Ġby Ġfunction Ġname Ġin Ġthe Ġcompiler . Ċ @ Experimental Std lib Api Ċ @ Export For Compiler Ċ fun Ġ< T > Ġcreate Clean er ( argument : ĠT , Ġblock : Ġ( T ) Ġ-> ĠUnit ): ĠClean er Ġ{ ĊĠĠĠ Ġif Ġ(! argument . is Share able ()) ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ("$ argument Ġmust Ġbe Ġshare able ") ĊĊĠĠĠ Ġval Ġclean Ġ= Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠMaybe Ġif Ġthis Ġfails Ġwith Ġexception , Ġit Ġshould Ġbe Ġ( option ally ) Ġreported . ĊĠĠĠĠĠĠĠ Ġblock ( argument ) ĊĠĠĠ Ġ}. freeze () ĊĊĠĠĠ Ġ// ĠMake Ġsure Ġthere 's Ġan Ġextra Ġreference Ġto Ġclean , Ġso Ġit 's Ġdefinitely Ġalive Ġwhen ĠClean er Impl Ġis Ġdestroyed . ĊĠĠĠ Ġval Ġclean Ptr Ġ= Ġcreate Stable Pointer ( clean ) ĊĊĠĠĠ Ġ// ĠMake Ġsure Ġcleaner Ġworker Ġis Ġinitialized . ĊĠĠĠ Ġget Clean er Worker () ĊĊĠĠĠ Ġreturn ĠClean er Impl ( clean Ptr ). freeze () Ċ } Ċ Ċ /** Ċ Ġ* ĠPerform ĠGC Ġon Ġa Ġworker Ġthat Ġexecutes ĠClean er Ġblocks . Ċ Ġ*/ Ċ @ Internal For Kotlin Native Ċ fun Ġperform G CO n Clean er Worker () Ġ= ĊĠĠĠ Ġget Clean er Worker (). execute ( Transfer Mode . SAFE , Ġ{}) Ġ{ ĊĠĠĠĠĠĠĠ ĠGC . collect () ĊĠĠĠ Ġ}. result Ċ Ċ /** Ċ Ġ* ĠWait Ġfor Ġa Ġworker Ġthat Ġexecutes ĠClean er Ġblocks Ġto Ġcomplete Ġits Ġscheduled Ġtasks . Ċ Ġ*/ Ċ @ Internal For Kotlin Native Ċ fun Ġwait Clean er Worker () Ġ= ĊĠĠĠ Ġget Clean er Worker (). execute ( Transfer Mode . SAFE , Ġ{}) Ġ{ ĊĠĠĠĠĠĠĠ ĠUnit ĊĠĠĠ Ġ}. result Ċ Ċ @ Symbol Name (" Kotlin _ Clean er Impl _ get Clean er Worker ") Ċ external Ġprivate Ġfun Ġget Clean er Worker (): ĠWorker Ċ Ċ @ Export For Cpp Runtime (" Kotlin _ Clean er Impl _ shutdown Clean er Worker ") Ċ private Ġfun Ġshutdown Clean er Worker ( worker : ĠWorker , Ġexecute Scheduled Clean ers : ĠBoolean ) Ġ{ ĊĠĠĠ Ġworker . request Termination ( execute Scheduled Clean ers ). result Ċ } Ċ Ċ @ Export For Cpp Runtime (" Kotlin _ Clean er Impl _ create Clean er Worker ") Ċ private Ġfun Ġcreate Clean er Worker (): ĠWorker Ġ{ ĊĠĠĠ Ġreturn ĠWorker . start ( error Reporting Ġ= Ġfalse , Ġname Ġ= Ġ" Clean er Ġworker ") Ċ } Ċ Ċ @ No Re order Fields Ċ @ Export TypeInfo (" the Clean er Impl TypeInfo ") Ċ @ Has Final izer Ċ private Ġclass ĠClean er Impl ( ĊĠĠĠ Ġprivate Ġval Ġclean Ptr : ĠNative Ptr , Ċ ): ĠClean er Ġ{} Ċ Ċ @ Symbol Name (" Kotlin _ Any _ is Share able ") Ċ external Ġprivate Ġfun ĠAny ?. is Share able (): ĠBoolean Ċ Ċ @ Symbol Name (" Create Stable Pointer ") Ċ external Ġprivate Ġfun Ġcreate Stable Pointer ( obj : ĠAny ): ĠNative Ptr Ċ