Fix backwards logic for cancellation flag

This commit is contained in:
Max Brunsfeld 2019-03-20 13:14:02 -07:00
parent 60265e807c
commit 3340168097
5 changed files with 61 additions and 41 deletions

View file

@ -303,33 +303,48 @@ fn test_parsing_on_multiple_threads() {
#[test]
fn test_parsing_cancelled_by_another_thread() {
let cancellation_flag = AtomicU32::new(0);
let cancellation_flag = Box::new(AtomicU32::new(0));
let mut parser = Parser::new();
parser.set_language(get_language("javascript")).unwrap();
unsafe { parser.set_cancellation_flag(Some(&cancellation_flag)) };
let parse_thread = thread::spawn(move || {
// Infinite input
parser.parse_with(
&mut |offset, _| {
if offset == 0 {
b" ["
} else {
b"0,"
}
},
None,
)
});
// Long input - parsing succeeds
let tree = parser.parse_with(
&mut |offset, _| {
if offset == 0 {
b" ["
} else if offset >= 20000 {
b""
} else {
b"0,"
}
},
None,
);
assert!(tree.is_some());
let cancel_thread = thread::spawn(move || {
thread::sleep(time::Duration::from_millis(80));
cancellation_flag.store(1, Ordering::Relaxed);
thread::sleep(time::Duration::from_millis(100));
cancellation_flag.store(1, Ordering::SeqCst);
});
// Infinite input
let tree = parser.parse_with(
&mut |offset, _| {
thread::yield_now();
thread::sleep(time::Duration::from_millis(10));
if offset == 0 {
b" ["
} else {
b"0,"
}
},
None,
);
// Parsing returns None because it was cancelled.
cancel_thread.join().unwrap();
let tree = parse_thread.join().unwrap();
assert!(tree.is_none());
}

View file

@ -10,6 +10,7 @@ extern "C" {
typedef enum {
TSHighlightOk,
TSHighlightUnknownScope,
TSHighlightTimeout,
} TSHighlightError;
// The list of scopes which can be styled for syntax highlighting.

View file

@ -29,6 +29,7 @@ pub struct TSHighlightBuffer {
pub enum ErrorCode {
Ok,
UnknownScope,
Timeout,
}
#[no_mangle]
@ -162,7 +163,7 @@ impl TSHighlighter {
let configuration = configuration.unwrap();
let languages = &self.languages;
let highlighter = unwrap(Highlighter::new(
let highlighter = Highlighter::new(
source_code,
configuration.language,
&configuration.property_sheet,
@ -178,29 +179,32 @@ impl TSHighlighter {
})
},
cancellation_flag,
));
);
output.html.clear();
output.line_offsets.clear();
output.line_offsets.push(0);
let mut scopes = Vec::new();
for event in highlighter {
match event {
HighlightEvent::ScopeStart(s) => {
scopes.push(s);
output.start_scope(s, &self.attribute_strings);
}
HighlightEvent::ScopeEnd => {
scopes.pop();
output.end_scope();
}
HighlightEvent::Source(src) => {
output.add_text(src, &scopes, &self.attribute_strings);
}
};
if let Ok(highlighter) = highlighter {
output.html.clear();
output.line_offsets.clear();
output.line_offsets.push(0);
let mut scopes = Vec::new();
for event in highlighter {
match event {
HighlightEvent::ScopeStart(s) => {
scopes.push(s);
output.start_scope(s, &self.attribute_strings);
}
HighlightEvent::ScopeEnd => {
scopes.pop();
output.end_scope();
}
HighlightEvent::Source(src) => {
output.add_text(src, &scopes, &self.attribute_strings);
}
};
}
ErrorCode::Ok
} else {
ErrorCode::Timeout
}
ErrorCode::Ok
}
}

View file

@ -22,7 +22,7 @@ static inline uint32_t atomic_dec(volatile uint32_t *p) {
#else
static inline uint32_t atomic_load(const volatile uint32_t *p) {
return __atomic_load_n(p, __ATOMIC_RELAXED);
return __atomic_load_n(p, __ATOMIC_SEQ_CST);
}
static inline uint32_t atomic_inc(volatile uint32_t *p) {

View file

@ -1287,7 +1287,7 @@ static bool ts_parser__advance(
if (++self->operation_count == OP_COUNT_PER_TIMEOUT_CHECK) {
self->operation_count = 0;
if (
(self->cancellation_flag && !atomic_load(self->cancellation_flag)) ||
(self->cancellation_flag && atomic_load(self->cancellation_flag)) ||
(self->clock_limit && get_clock() - self->start_clock > self->clock_limit)
) {
ts_subtree_release(&self->tree_pool, lookahead);