@@ -298,7 +298,8 @@ static void range_str(const SEXP *x, int n, uint64_t *out_min, uint64_t *out_max
298298 bool anynotascii = false, anynotutf8 = false;
299299 if (ustr_n != 0 ) internal_error_with_cleanup (__func__ , "ustr isn't empty when starting range_str: ustr_n=%d, ustr_alloc=%d" , ustr_n , ustr_alloc ); // # nocov
300300 if (ustr_maxlen != 0 ) internal_error_with_cleanup (__func__ , "ustr_maxlen isn't 0 when starting range_str" ); // # nocov
301- #pragma omp parallel for num_threads(getDTthreads(n, true)) shared(marks)
301+ bool fail = false;
302+ #pragma omp parallel for num_threads(getDTthreads(n, true)) shared(marks, fail)
302303 for (int i = 0 ; i < n ; i ++ ) {
303304 SEXP s = x [i ];
304305 if (s == NA_STRING ) {
@@ -317,9 +318,16 @@ static void range_str(const SEXP *x, int n, uint64_t *out_min, uint64_t *out_max
317318 if (ustr == NULL ) STOP (_ ("Unable to realloc %d * %d bytes in range_str" ), ustr_alloc , (int )sizeof (SEXP )); // # nocov
318319 }
319320 ustr [ustr_n ++ ] = s ;
320- // Under the OpenMP memory model, if the hash table is expanded, we have to explicitly update the pointer.
321- #pragma omp atomic write
322- marks = hash_set_shared (marks , s , - ustr_n ); // unique in any order is fine. first-appearance order is achieved later in count_group
321+ hashtab * new_marks = hash_set_shared (marks , s , - ustr_n ); // unique in any order is fine. first-appearance order is achieved later in count_group
322+ if (new_marks != marks ) {
323+ if (new_marks ) {
324+ // Under the OpenMP memory model, if the hash table is expanded, we have to explicitly update the pointer.
325+ #pragma omp atomic write
326+ marks = new_marks ;
327+ } else { // longjmp() from a non-main thread not allowed
328+ fail = true;
329+ }
330+ }
323331 if (LENGTH (s )> ustr_maxlen ) ustr_maxlen = LENGTH (s );
324332 if (!anynotutf8 && // even if anynotascii we still want to know if anynotutf8, and anynotutf8 implies anynotascii already
325333 !IS_ASCII (s )) { // anynotutf8 implies anynotascii and IS_ASCII will be cheaper than IS_UTF8, so start with this one
@@ -330,6 +338,7 @@ static void range_str(const SEXP *x, int n, uint64_t *out_min, uint64_t *out_max
330338 }
331339 }
332340 }
341+ if (fail ) internal_error_with_cleanup (__func__ , "failed to grow the 'marks' hash table" );
333342 * out_na_count = na_count ;
334343 * out_anynotascii = anynotascii ;
335344 * out_anynotutf8 = anynotutf8 ;
0 commit comments