ports/unix/modffi.c: FFI fixes.
Fixes and improvements to ffi callabck Add an optional 'lock' kwarg to callback that locks gc and scheduler. This allows the callback to be invoked asynchronously in 'interrupt context', for example as a signal handler Added buffer protocol to callback that allows retrieving the C callback function. This is needed when the callback should be set to a struct field. Signed-off-by: Amir Gonnen <amirgonnen@gmail.com>
This commit is contained in:
parent
377068c5f2
commit
88ddf6fd7a
@ -275,7 +275,9 @@ STATIC void call_py_func(ffi_cif *cif, void *ret, void **args, void *user_data)
|
|||||||
mp_obj_t pyfunc = o->pyfunc;
|
mp_obj_t pyfunc = o->pyfunc;
|
||||||
|
|
||||||
if (o->lock) {
|
if (o->lock) {
|
||||||
|
#if MICROPY_ENABLE_SCHEDULER
|
||||||
mp_sched_lock();
|
mp_sched_lock();
|
||||||
|
#endif
|
||||||
gc_lock();
|
gc_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,17 +292,19 @@ STATIC void call_py_func(ffi_cif *cif, void *ret, void **args, void *user_data)
|
|||||||
|
|
||||||
if (o->lock) {
|
if (o->lock) {
|
||||||
gc_unlock();
|
gc_unlock();
|
||||||
|
#if MICROPY_ENABLE_SCHEDULER
|
||||||
mp_sched_unlock();
|
mp_sched_unlock();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t mod_ffi_callback(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
STATIC mp_obj_t mod_ffi_callback(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
enum { ARG_rettype, ARG_func, ARG_parmtypes, ARG_lock };
|
enum { ARG_rettype, ARG_func, ARG_parmtypes, ARG_lock };
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_rettype, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
{ MP_QSTR_rettype, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_func, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
{ MP_QSTR_func, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_paramtypes, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
{ MP_QSTR_paramtypes, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_lock, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
{ MP_QSTR_lock, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||||
};
|
};
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
@ -485,6 +489,9 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
|||||||
} else if (mp_obj_is_str(a)) {
|
} else if (mp_obj_is_str(a)) {
|
||||||
const char *s = mp_obj_str_get_str(a);
|
const char *s = mp_obj_str_get_str(a);
|
||||||
values[i].ffi = (ffi_arg)(intptr_t)s;
|
values[i].ffi = (ffi_arg)(intptr_t)s;
|
||||||
|
} else if (mp_obj_is_type(a, &fficallback_type)) {
|
||||||
|
mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a);
|
||||||
|
values[i].ffi = (ffi_arg)(intptr_t)p->func;
|
||||||
} else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) {
|
} else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) {
|
||||||
mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a);
|
mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
@ -493,9 +500,6 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
values[i].ffi = (ffi_arg)(intptr_t)bufinfo.buf;
|
values[i].ffi = (ffi_arg)(intptr_t)bufinfo.buf;
|
||||||
} else if (mp_obj_is_type(a, &fficallback_type)) {
|
|
||||||
mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a);
|
|
||||||
values[i].ffi = (ffi_arg)(intptr_t)p->func;
|
|
||||||
} else {
|
} else {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user