Sublime Forum

Dealing with text buffer race conditions

#1

I’m working on a multithreaded plugin (st3) that does automated edits on the text buffers simultaneously with the user. Occasionally, when a user edit occurs at exactly the right time simultaneously with my plugin’s edits, a race condition occurs between the main UI thread and my plugin, as evidenced by intermittent single character edit placement errors during high speed typing.

Normally, I would solve this problem with locks to ensure that the “calculate edit” + “perform edit” steps were atomic, but Sublime doesn’t seem to support any kind of buffer locking (understandably…) Optimizing my plugin go be as fast as possible could mitigate the problem by minimizing the “danger” time frame, but that wouldn’t solve the root cause here. It really seems like I need to block the UI thread momentarily, or problems will inevitably occur with low frequency.

Maybe I could coerce the “on_modified” callback into acting as a lock, or potentially I could make the “perform edit” function do error checking, and recursively retry until success without race conditions (but icky).

Has anyone else dealt with this problem?

0 Likes

#2

I might be able to help you with a few ideas that can do different things.

  1. Set view.read_only while doing your changes.

  2. Do changes on the main thread via sublime.set_timeout. No idea if this would actually help, but you might be able to block editing while running view commands there.

  3. Eat all character input by specifying a “” key binding that is only active if a setting is set. You set this setting on the view before doing changes and remove it afterward.

This should work fine enough as long as you are not altering the view’s selection. I don’t have a test case to verify this however.

0 Likes

#3

Thanks for the quick response!

I think I might have just solved my problem, EventListener.on_modified blocks the UI thread and buffers keyboard input until the function returns. I might be use a view buffer mutex there and have everything work as expected - occasional short lag, but correct eventual result.

  1. I wonder if that would cause the client to drop all input during until read_only was set to false. Will try to replicate.
  2. That might do the trick as well, with a nice wrapper that might be a good way to go
  3. This is clever, but somewhat hacky. I’d have to do the keyboard edit buffering and merging myself, or the editor would apparently drop keypresses occasionally.

I need to figure out some test case for this, unfortunately it’s pretty challenging to replicate on purpose.

0 Likes

#4
  1. It will. Better try 3. before this.
  2. That’s true. There is also a different issue with other commands being run by a hotkey, for example when inserting a completion or running other plugin commands. I do not know if those are always pipelined or just all run at the same time.
0 Likes