| Anonymous | Login | Signup for a new account | 2013-05-22 02:48 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | ||||||
| 0004891 | OCaml | OCaml general | public | 2009-10-13 16:13 | 2012-07-08 11:22 | ||||||
| Reporter | ygrek | ||||||||||
| Assigned To | doligez | ||||||||||
| Priority | normal | Severity | feature | Reproducibility | always | ||||||
| Status | assigned | Resolution | open | ||||||||
| Platform | OS | OS Version | |||||||||
| Product Version | 3.11.1 | ||||||||||
| Target Version | Fixed in Version | ||||||||||
| Summary | 0004891: provide CAMLreturn macros suitable for callbacks | ||||||||||
| Description | Consider callbacks from C to OCaml. Call to caml_callback in the C wrapper code is surrounded with caml_leave_blocking_section and caml_enter_blocking_section. In case when this C callback manipulates ocaml values, it registers them with CAMLlocal. Consequently one should use CAMLreturn to unregister those values. But both CAMLlocal and CAMLreturn should be called with ocaml runtime lock acquired (to prevent race condition on caml_local_roots). But caml_enter_blocking_section cannot be called after CAMLreturn because the latter actually returns from the function. So one has to wrap the C function into another one which solely manages the runtime lock and passes arguments, like this : static int progressFunction(void *data, double dlTotal, double dlNow, double ulTotal, double ulNow) { int r; leave_blocking_section(); r = progressFunction_nolock(data,dlTotal,dlNow,ulTotal,ulNow); enter_blocking_section(); return r; } It would be much nicer to have macros like CAML_callback_return and CAML_callback_returnT (and possibly CAML_callback_enter (alias to CAMLparam0?)) to unregister local values, release runtime lock and return. | ||||||||||
| Tags | No tags attached. | ||||||||||
| Attached Files | |||||||||||
Notes |
|
|
(0005678) yziquel (reporter) 2010-10-11 04:17 |
Yes. I have the same issue. I do: caml_local_roots = caml__frame; caml_enter_blocking_section(); return; to return from OCaml code into standalone C(++) code. Moreover, I haven't checked yet, but I'm worried about the caml_local_roots. If caml_local_roots is managed each time there's an OCaml thread context switch, then it's fine. We can just pop up the frames this way. If not, then how can we be sure that there isn't a race condition? I mean: -1- thread1: caml_leave_blocking_section -2- thread1: CAMLparam3(); -3- thread1: caml_callbackN(...); -4- thread2: CAMLparam2() -5- thread1: returns from OCaml callback -6- thread1: caml_local_roots = caml__frame; ... -15- thread2: CAMLreturn(...) The order of -2-, -4-, -6-, -15- seems problematic to me. |
|
(0005919) doligez (manager) 2011-05-20 15:52 |
I think it's better to just add a macro to pop the frame without returning. |
|
(0007658) ygrek (reporter) 2012-07-08 11:22 |
Yes, sounds reasonable. |
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2009-10-13 16:13 | ygrek | New Issue | |
| 2010-10-11 04:17 | yziquel | Note Added: 0005678 | |
| 2011-05-20 15:52 | doligez | Note Added: 0005919 | |
| 2011-05-20 15:52 | doligez | Assigned To | => doligez |
| 2011-05-20 15:52 | doligez | Status | new => assigned |
| 2012-07-08 11:22 | ygrek | Note Added: 0007658 | |
| Copyright © 2000 - 2011 MantisBT Group |