lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Thu, 30 Jul 2020 at 18:01, Egor Skriptunoff wrote:
> Dead coroutines (after an error is raised) can have non-closed to-be-closed variables too.
> So, the suggestion is: All coroutines in the VM should be implicitly closed on VM exit.
> Of course it would be better to implicitly close dead coroutines at the moment they become dead.

coroutine.wrap closes them automatically [4]

On Thu, Jul 30, 2020 at 8:08 PM Dibyendu Majumdar wrote:
> Repeating myself - the 'defer' statement leads to no such issue or
> expectation - as it is explicitly related to a scope exit and does not
> promise to close anything!

I tried to run some tests with and without the defer patch [1][2]. I
created a coroutine with coroutine.create and I run it with
coroutine.resume. In the coroutine a defer/<close> is "Registered" and
an error is raised.

It seems to me that both the codes just do not call the finalization
code [3]. Calling coroutine.close (or using coroutine.wrap) just makes
the finalizer be called in both the cases (with or without the patch).

What am I missing ?

Just to be clear, I am not fully sure what the "Right" behaviour
should be. I was just puzzled by Dibyendu's statement that the defer
patch behaves differently in this case. I also wrote a different defer
patch [5] and it behaves the same.

--

[1] The code for the defer is:
```
local thread = coroutine.create(function()
  defer
    print"coroutine defer"
  end
  error"an error in the goroutine"
  print"coroutine ends"
end)
local ok= coroutine.resume(thread)
if not ok then
  -- This should be the right thing to do (and indeed coroutine.wrap does it),
  -- but it is skipped for the sake of the test
  -- -- coroutine.close(thread)
end
print"program exit"
```

[2] the code for the <close> variable is:
```
local thread = coroutine.create(function()
  local please <close> = setmetatable({}, {__close = function()
    print"coroutine toclose"
  end})
  error"an error in the goroutine"
  print"coroutine ends"
end)
local ok= coroutine.resume(thread)
if not ok then
  -- This should be the right thing to do (and indeed coroutine.wrap does it),
  -- but it is skipped for the sake of the test
  -- -- coroutine.close(thread)
end
print"program exit"
```

[3] In both the cases I got
```
program exit
```
i.e.  print"coroutine defer/toclose" is not called

[4] The code
```
local thread = coroutine.wrap(function()
  local please <close> = setmetatable({}, {__close = function()
    print"coroutine toclose"
  end})
  error"an error in the goroutine"
  print"coroutine ends"
end)
thread()
print"program exit"
```
prints "coroutine toclose" before quitting with an error.

[5] A defer statement is part of the do-attibute patch. It does not
introduce any new keyword, since it uses a syntax like do <defer> end.
It works by creating an "Hidden" to-be-closed variable.
https://github.com/pocomane/lua-do-attribute