foreign-call lock: repair for use during place termination

Now that `ffi/unsafe/alloc` deallocations are triggered by a place
exit, it's more likely that an ffi-call lock can be contended during a
place's termination. When that happens, the place cannot cooperate as
usual. Accomodate this rare situation by spinning.
This commit is contained in:
Matthew Flatt 2018-07-20 08:34:12 -06:00
parent b40fdb7dd7
commit a1e928350b
4 changed files with 17 additions and 1 deletions

View File

@ -3256,6 +3256,11 @@ static void wait_ffi_lock(Scheme_Object *lock)
(uintptr_t)scheme_make_integer(scheme_current_place_id))) {
/* obtained lock the fast way */
break;
} else if (!scheme_place_can_receive()) {
/* We can get here while trying to terminate a place and run
custodian callbacks or other shutdown actions, and since
the place is shutting down, we can't commuincate with other
places; since we can't pause nicely, just spin */
} else {
Scheme_Object *owner, *new_val;
owner = SCHEME_VEC_ELS(lock)[1];
@ -3786,7 +3791,7 @@ static Scheme_Object *ffi_call_or_curry(const char *who, int curry, int argc, Sc
scheme_register_finalizer(data, free_fficall_data, cif, NULL, NULL);
a[0] = data;
scheme_performance_record_end("comp-ffi", &perf_state);
scheme_performance_record_end("comp-ffi-call", &perf_state);
if (curry) {
return scheme_make_prim_closure_w_arity(make_ffi_call_from_curried,

View File

@ -2427,6 +2427,11 @@ static void wait_ffi_lock(Scheme_Object *lock)
(uintptr_t)scheme_make_integer(scheme_current_place_id))) {
/* obtained lock the fast way */
break;
} else if (!scheme_place_can_receive()) {
/* We can get here while trying to terminate a place and run
custodian callbacks or other shutdown actions, and since
the place is shutting down, we can't commuincate with other
places; since we can't pause nicely, just spin */
} else {
Scheme_Object *owner, *new_val;
owner = SCHEME_VEC_ELS(lock)[1];

View File

@ -3394,6 +3394,11 @@ Scheme_Object *scheme_place_async_channel_receive(Scheme_Object *ch) {
return place_async_receive((Scheme_Place_Async_Channel *)ch);
}
int scheme_place_can_receive()
{
return !!place_object;
}
/*========================================================================*/
/* precise GC traversers */
/*========================================================================*/

View File

@ -3989,6 +3989,7 @@ void scheme_sort_resolve_ir_local_array(Scheme_IR_Local **a, intptr_t count);
Scheme_Object *scheme_place_make_async_channel();
void scheme_place_async_channel_send(Scheme_Object *ch, Scheme_Object *uo);
Scheme_Object *scheme_place_async_channel_receive(Scheme_Object *ch);
int scheme_place_can_receive();
#endif
int scheme_is_predefined_module_path(Scheme_Object *v);