Thread overview
Is there a way to call scope guard without throw exception?
Dec 30, 2017
ChangLong
Jan 01, 2018
Jack Stouffer
Jan 01, 2018
David Nadlinger
Jan 02, 2018
ChangLong
Jan 03, 2018
ChangLong
December 30, 2017
I try to find a way to yield custom fiber without throw exception,  is it possible ?

I need make sure the scope guard is executed and the resource will auto release relay on scope(exit).

After fiber yield, the spoke guard is not able to execute,  unless I throw a exception in Fiber.  I am look if there is some hack method to make the fiber Interrupted at any time with  scope(exit) code executed.



January 01, 2018
On Saturday, 30 December 2017 at 13:48:16 UTC, ChangLong wrote:
> I try to find a way to yield custom fiber without throw exception,  is it possible ?
>
> I need make sure the scope guard is executed and the resource will auto release relay on scope(exit).
>
> After fiber yield, the spoke guard is not able to execute,  unless I throw a exception in Fiber.  I am look if there is some hack method to make the fiber Interrupted at any time with
>  scope(exit) code executed.

You might want to repost this question to the Learn board, along with some example code of what you're trying to achieve.
January 01, 2018
On Saturday, 30 December 2017 at 13:48:16 UTC, ChangLong wrote:
> After fiber yield, the spoke guard is not able to execute,  unless I throw a exception in Fiber.  I am look if there is some hack method to make the fiber Interrupted at any time with
>  scope(exit) code executed.

There isn't. In fact, ensuring that the scope isn't left is the whole point of fibre context switches – how else would execution continue after the fibre is returned to? (How would objects be "un-destroyed"?)

However, there is nothing stopping you from creating a registry of resources yourself, and then wrapping the Fiber.yield() call into something like:

void myYield() {
  registry.releaseResources();
  Fiber.yield();
  registry.reacquireResources();
}

You could have the resource handles be structs that register themselves with the registry to integrate with fibre scheduling, and that also have a destructor to execute the cleanup when the scope is left (like `scope(exit)`).

 — David
January 02, 2018
On Monday, 1 January 2018 at 03:06:42 UTC, David Nadlinger wrote:
> On Saturday, 30 December 2017 at 13:48:16 UTC, ChangLong wrote:
>> After fiber yield, the spoke guard is not able to execute,  unless I throw a exception in Fiber.  I am look if there is some hack method to make the fiber Interrupted at any time with
>>  scope(exit) code executed.
>
> There isn't. In fact, ensuring that the scope isn't left is the whole point of fibre context switches – how else would execution continue after the fibre is returned to? (How would objects be "un-destroyed"?)
>
> However, there is nothing stopping you from creating a registry of resources yourself, and then wrapping the Fiber.yield() call into something like:
>
> void myYield() {
>   registry.releaseResources();
>   Fiber.yield();
>   registry.reacquireResources();
> }
>
> You could have the resource handles be structs that register themselves with the registry to integrate with fibre scheduling, and that also have a destructor to execute the cleanup when the scope is left (like `scope(exit)`).
>
>  — David


I was looking for some thing like yieldAndThrow,  and destroy or reset the fiber same time, without throw exception but call the scope(exit).  I guess It maybe can be done with some ASM jump code.  (or I am wrong.)

I already ask from Learn board few days ago,  no answer yet so I paste it here.


January 03, 2018
On Tuesday, 2 January 2018 at 07:10:14 UTC, ChangLong wrote:
> On Monday, 1 January 2018 at 03:06:42 UTC, David Nadlinger wrote:
>> On Saturday, 30 December 2017 at 13:48:16 UTC, ChangLong wrote:
>>> After fiber yield, the spoke guard is not able to execute,  unless I throw a exception in Fiber.  I am look if there is some hack method to make the fiber Interrupted at any time with
>>>  scope(exit) code executed.
>>
>> There isn't. In fact, ensuring that the scope isn't left is the whole point of fibre context switches – how else would execution continue after the fibre is returned to? (How would objects be "un-destroyed"?)
>>
>> However, there is nothing stopping you from creating a registry of resources yourself, and then wrapping the Fiber.yield() call into something like:
>>
>> void myYield() {
>>   registry.releaseResources();
>>   Fiber.yield();
>>   registry.reacquireResources();
>> }
>>
>> You could have the resource handles be structs that register themselves with the registry to integrate with fibre scheduling, and that also have a destructor to execute the cleanup when the scope is left (like `scope(exit)`).
>>
>>  — David
>
>
> I was looking for some thing like yieldAndThrow,  and destroy or reset the fiber same time, without throw exception but call the scope(exit).  I guess It maybe can be done with some ASM jump code.  (or I am wrong.)
>
> I already ask from Learn board few days ago,  no answer yet so I paste it here.

I just implement solution, maybe some one is interested.

step 1: add a FiberQuitChain for each Fiber,  when fiber is terminated each chain delegate will be executed in order.

step 2: when create a new Resource, add the onCancel delegate into FiberQuitChain.  doCancel or ~this will remove it self from FiberQuitChain.

When a fiber is Killed it will call the FiberQuitChain to notify every resource the mission is aborted, the resource will release them self.