Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework lua timers and remove lua.Lock #3023

Merged
merged 3 commits into from
Mar 14, 2024
Merged

Conversation

dmaluka
Copy link
Collaborator

@dmaluka dmaluka commented Nov 13, 2023

Directly using Go timers from lua (e.g. via Go's time.AfterFunc()) is tricky. First, it requires the lua timer callback to explicitly lock lua.Lock to prevent races. Second, it requires the lua timer callback to explicitly redraw the screen if the callback changes the screen contents (see #2923).

So, as per the discussion in #2945, this PR reworks lua timers support: it replaces directly exposed Go's time.AfterFunc() etc with micro's own micro.After() timer API, which ensures both synchronization and redrawing on its own, instead of leaving this burden to lua code.

Since this PR removes directly exposing Go timers to Lua, now we (probably?) have no cases of lua code possibly running asynchronously without micro controlling when it is running. So this PR also removes lua.Lock, since it is not needed anymore. (Before the recent fix #2945, lua.Lock wasn't workable at all, which suggests that it has never been really used by anyone. So it should be safe to remove it.)

Fixes #2923

Directly using Go's time.AfterFunc() from lua is tricky. First, it
requires the lua timer callback to explicitly lock ulua.Lock to prevent
races. Second, it requires the lua timer callback to explicitly redraw
the screen if the callback changes the screen contents (see zyedidia#2923).

So instead provide micro's own timer API which ensures both
synchronization and redrawing on its own, instead of leaving this burden
to lua code. In fact, its implementation runs the lua timer callback in
the main micro's goroutine (i.e. from micro's perspective it is
synchronous, not asynchronous), so both redrawing and synchronization
are ensured automatically.

Fixes zyedidia#2923
Since we now expose our own micro.After() API which is more convenient
and safer to use than directly using Go timers, we can remove exposing
Go timers to lua directly.
Exposing locking primitives to lua plugins is tricky and may lead to
deadlocks. Instead, if possible, it's better to ensure all the needed
synchonization in micro itself, without leaving this burden to lua code.

Since we've added micro.After() timer API and removed exposing Go timers
directly to lua, now we (probably?) have no cases of lua code possibly
running asynchronously without micro controlling when it is running. So
now we can remove lua.Lock.

This means breaking compatibility, but, until recently lua.Lock wasn't
workable at all (see zyedidia#2945), which suggests that it has never been
really used by anyone. So it should be safe to remove it.
@dmaluka dmaluka merged commit 0a69cc6 into zyedidia:master Mar 14, 2024
3 checks passed
@dmaluka dmaluka mentioned this pull request Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timer callback in lua plugins can't refresh the screen
1 participant