Only have one parser running at a time (per buffer)

The parser takes time proportional with line length, so if doing a dozen quick edits on a very long line, we could have a dozen parsers running, making the CPU hot.
This commit is contained in:
Allan Odgaard
2016-10-02 22:05:13 +02:00
parent a378b3d241
commit 1f40f69c07
2 changed files with 7 additions and 1 deletions

View File

@@ -214,6 +214,7 @@ namespace ng
std::shared_ptr<bool> _parser_reference;
bool _async_parsing = false;
bool _parser_running = false;
std::weak_ptr<bool> parser_reference ()
{

View File

@@ -30,7 +30,7 @@ namespace ng
void buffer_t::initiate_repair (size_t limit_redraw, size_t batch_start)
{
if(!_async_parsing)
if(!_async_parsing || _parser_running)
return;
if(!_dirty.empty() && !_parser_states.empty())
@@ -51,6 +51,7 @@ namespace ng
size_t bufferRev = revision();
auto bufferRef = parser_reference();
_parser_running = true;
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@@ -58,6 +59,7 @@ namespace ng
CFRunLoopPerformBlock(runLoop, kCFRunLoopCommonModes, ^{
if(bufferRef.lock())
{
_parser_running = false;
if(bufferRev == revision())
{
update_scopes(limit_redraw, batch_start, { from, to }, result.scopes, result.state);
@@ -102,6 +104,7 @@ namespace ng
}
_parser_reference.reset();
_parser_running = false;
bool next_line_needs_update = !_dirty.empty() && _dirty.begin()->first == range.second;
if(!next_line_needs_update || limit_redraw == 0)
@@ -121,6 +124,8 @@ namespace ng
return;
_parser_reference.reset();
_parser_running = false;
std::lock_guard<std::mutex> lock(grammar()->mutex());
while(!_dirty.empty() && !_parser_states.empty())
{