-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
ports/unix/modffi.c: FFI fixes. #7401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ports/unix/modffi.c
Outdated
(void)flags; | ||
mp_obj_fficallback_t *self = MP_OBJ_TO_PTR(self_in); | ||
|
||
bufinfo->buf = &self->func; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't feel like the right approach, using the buffer protocol to get out the C closure wrapper function (I would expect it to get access to the underlying data of the function itself).
Instead I'd suggest to add a method to the callback type, eg cfun()
. Then one can write:
sa.sa_handler = cb.cfun()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
However, sa.sa_handler = cb.cfun()
doesn't work in this case because we want to set the pointer value, not the value the pointer points at.
So we need something like this instead:
memoryview(sa.sa_handler)[:] = cb.cfun()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However,
sa.sa_handler = cb.cfun()
doesn't work in this case because we want to set the pointer value, not the value the pointer points at.
If sa_handler
were defined as a UINT64 would it work without the memoryview?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right.
I changed cfun
to return ULL integer and defined sa.sa_handler
as uctypes.UINT64
, it works fine.
faca276
to
5144356
Compare
I'm not sure why "coverage/coveralls" test fails. |
for (uint i = 0; i < cif->nargs; i++) { | ||
pyargs[i] = mp_obj_new_int(*(mp_int_t *)args[i]); | ||
} | ||
mp_obj_t res = mp_call_function_n_kw(MP_OBJ_FROM_PTR(func), cif->nargs, 0, pyargs); | ||
mp_obj_t res = mp_call_function_n_kw(pyfunc, cif->nargs, 0, pyargs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this call raises an exception, and locking is enabled, then things will not go well, the GC will remain locked and the code will fail completely.
I think it makes sense to have two separate callback functions: call_py_func
and call_py_func_with_lock
. The correct one is registered with ffi_prep_closure_loc
. The wrapper call_py_func_with_lock
will do something similar to lib/utils/mpirq.c:mp_irq_handler
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
4c6b493
to
125064b
Compare
Fixes and improvements to ffi callback Added 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 'cfun' member function to callback, that allows retrieving the C callback function address. This is needed when the callback should be set to a struct field. Signed-off-by: Amir Gonnen <amirgonnen@gmail.com>
125064b
to
6c7ad06
Compare
Thanks for updating. Merged in cb332dd with some minor edits (use mp_printf instead of printf). |
Added M5Stack Atom Echo board
Fixes and improvements to ffi callback
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.
Usage example - Creating a signal handler and setting sa_handler to it:
Related: #7373