Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/bindings/text-buffer-wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,11 @@ void TextBufferWrapper::find_words_with_subsequence_in_range(const CallbackInfo
}

void OnWorkComplete(Napi::Env env, napi_status status) override {
{
std::lock_guard<std::mutex> guard(text_buffer_wrapper->outstanding_workers_mutex);
text_buffer_wrapper->outstanding_workers.erase(this);
}

if (status == napi_cancelled) {
Callback().Call({env.Null()});
}
Expand All @@ -631,11 +636,6 @@ void TextBufferWrapper::find_words_with_subsequence_in_range(const CallbackInfo
}

void Execute() override {
{
std::lock_guard<std::mutex> guard(text_buffer_wrapper->outstanding_workers_mutex);
text_buffer_wrapper->outstanding_workers.erase(this);
}

if (!snapshot) {
return;
}
Expand Down
23 changes: 23 additions & 0 deletions test/js/text-buffer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const MAX_INT32 = 4294967296

const isWindows = process.platform === 'win32'

async function wait (ms) {
return new Promise(r => setTimeout(r, ms));
}

const encodings = [
'big5hkscs',
'cp850',
Expand Down Expand Up @@ -1261,6 +1265,25 @@ describe('TextBuffer', () => {
return Promise.all(promises)
})

it('doesn\'t crash when a job is cancelled', async () => {
function randomChar () {
const chars = "abcdefghijklmnopqrstuvwxyz ";
return chars[Math.floor(Math.random() * chars.length)];
}
let buffer = new TextBuffer(`lorem ipsum dolor sit amet, consecuetur adipiscing elit`)
// This test triggers a known segfault scenario in which a
// `FindWordsWithSubsequenceInRangeWorker` is created and then needs to
// be cancelled because of a subsequent call to `set_text_in_range`. Just
// like the test above, this one will either pass without making any
// assertions… or crash.
for (let k = 0; k < 100; k++) {
let ch = randomChar()
buffer.findWordsWithSubsequence('lor', '(){} :;,$@%', 20)
buffer.setTextInRange({ start: { row: 0, column: 8 }, end: { row: 0, column: 9 } }, ch)
await wait(Math.round(Math.random() * 20))
}
})

it('resolves with all words matching the given query', () => {
const buffer = new TextBuffer('banana bandana ban_ana bandaid band bNa\nbanana')
return buffer.findWordsWithSubsequence('bna', '_', 4).then((result) => {
Expand Down