diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-01-04 13:09:47 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-01-04 13:09:47 -0200 |
| commit | 4ace93ca6502dd1da38d5c06fa099d229e791ba8 (patch) | |
| tree | 34f95ef56aecb56ae1db5e8b843b6e9bd2cbae51 /testes/coroutine.lua | |
| parent | c6f7181e910b6b2ff1346b5486a31be87b1da5af (diff) | |
| download | lua-4ace93ca6502dd1da38d5c06fa099d229e791ba8.tar.gz lua-4ace93ca6502dd1da38d5c06fa099d229e791ba8.tar.bz2 lua-4ace93ca6502dd1da38d5c06fa099d229e791ba8.zip | |
No more to-be-closed functions
To-be-closed variables must contain objects with '__toclose'
metamethods (or nil). Functions were removed for several reasons:
* Functions interact badly with sandboxes. If a sandbox raises
an error to interrupt a script, a to-be-closed function still
can hijack control and continue running arbitrary sandboxed code.
* Functions interact badly with coroutines. If a coroutine yields
and is never resumed again, its to-be-closed functions will never
run. To-be-closed objects, on the other hand, will still be closed,
provided they have appropriate finalizers.
* If you really need a function, it is easy to create a dummy
object to run that function in its '__toclose' metamethod.
This comit also adds closing of variables in case of panic.
Diffstat (limited to 'testes/coroutine.lua')
| -rw-r--r-- | testes/coroutine.lua | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index ca30011f..a4321bed 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
| @@ -142,8 +142,15 @@ do | |||
| 142 | 142 | ||
| 143 | -- to-be-closed variables in coroutines | 143 | -- to-be-closed variables in coroutines |
| 144 | local X | 144 | local X |
| 145 | |||
| 146 | local function func2close (f) | ||
| 147 | return setmetatable({}, {__close = f}) | ||
| 148 | end | ||
| 149 | |||
| 145 | co = coroutine.create(function () | 150 | co = coroutine.create(function () |
| 146 | local *toclose x = function (err) assert(err == nil); X = false end | 151 | local *toclose x = func2close(function (self, err) |
| 152 | assert(err == nil); X = false | ||
| 153 | end) | ||
| 147 | X = true | 154 | X = true |
| 148 | coroutine.yield() | 155 | coroutine.yield() |
| 149 | end) | 156 | end) |
| @@ -154,7 +161,9 @@ do | |||
| 154 | 161 | ||
| 155 | -- error killing a coroutine | 162 | -- error killing a coroutine |
| 156 | co = coroutine.create(function() | 163 | co = coroutine.create(function() |
| 157 | local *toclose x = function (err) assert(err == nil); error(111) end | 164 | local *toclose x = func2close(function (self, err) |
| 165 | assert(err == nil); error(111) | ||
| 166 | end) | ||
| 158 | coroutine.yield() | 167 | coroutine.yield() |
| 159 | end) | 168 | end) |
| 160 | coroutine.resume(co) | 169 | coroutine.resume(co) |
