avoid stack-overflow in scheduler-triggered foreign calls
While a foreigh call is normally guarded by a check on the amount of available stack space, a callbacks triggered by the scheduler will first put Racket in no-stack-overflow mode, and then it's too late to check stack space before making further foreign calls. With Cocoa, there's some chance that the process will run out of space. Avoid the mismatch by checking the stack availability at the start of a scheduler iteration.
This commit is contained in:
parent
bb116e476a
commit
43d6684ab9
|
@ -4882,6 +4882,17 @@ static void find_next_thread(Scheme_Thread **return_arg) {
|
|||
next = NULL;
|
||||
}
|
||||
|
||||
static Scheme_Object *do_thread_block()
|
||||
{
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
float sleep_time = p->sleep_end;
|
||||
p->sleep_end = 0.0;
|
||||
|
||||
scheme_thread_block(sleep_time);
|
||||
|
||||
return scheme_false;
|
||||
}
|
||||
|
||||
void scheme_thread_block(float sleep_time)
|
||||
/* If we're blocked, `sleep_time' is a max sleep time,
|
||||
not a min sleep time. Otherwise, it's a min & max sleep time.
|
||||
|
@ -4922,6 +4933,17 @@ void scheme_thread_block(float sleep_time)
|
|||
|
||||
shrink_cust_box_array();
|
||||
|
||||
/* Scheduling queries might involve callbacks through the FFI that put
|
||||
the runtime system into `scheme_no_stack_overflow` mode. Immitate
|
||||
the foriegn-call entry point with an extra check that we have enough
|
||||
stack to survive in foreign functions. */
|
||||
if (!scheme_no_stack_overflow && scheme_is_stack_too_shallow()) {
|
||||
p->sleep_end = sleep_time; /* an abuse of the `sleep_end` field to
|
||||
pass `sleep_end` along */
|
||||
(void)scheme_handle_stack_overflow(do_thread_block);
|
||||
return;
|
||||
}
|
||||
|
||||
if (scheme_active_but_sleeping)
|
||||
scheme_wake_up();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user