-
Notifications
You must be signed in to change notification settings - Fork 29
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
Event loop + audio callback = segfault #13
Comments
Yes reproducible. I suspect the problem mentioned in this comment is happening. Sorry it seems I forgot to lift it up in the documentation. @yallop You recently added changes to release the runtime lock in bindings. Is there some support for callbacks aswell ? |
@dbuenzli: there's some support for (re-)acquiring the runtime lock in callbacks in yallop/ocaml-ctypes#171 which should be merged soon. |
Tentative for #13. But still crashes.
7de867c tries to do the obvious by simply acquiring the runtime lock however the program still crashes ( Unclear whether this is ctypes fault or mine, but I don't have time to investigate this further at the moment. If anyone's interested at having a closer look the test case is now included in |
Is it possible that this is due to |
@tokenrove thanks for looking into that; that seems like a very plausible cause. OTOH it seems that SDL 2.0.4 which just got into RC1 introduces a way to queue audio buffers rather than use the callback so we may just aswell scrap the binding to the audiocallback API. What do you think ? |
@dbuenzli I think that would be significantly less hassle. (This is also one of the reasons I tend to use SDL2_mixer when I can get away with it if I'm using SDL through an FFI; I see that the old OCamlSDL package had the same approach and doesn't even bother to provide the lower-level audio functionality.) Of course if an elegant solution to yallop/ocaml-ctypes#269 comes up, that would solve it. I wonder if the SDL developers could be convinced to provide an extra hook into the SDL_Thread code that would allow us to call (FWIW, this morning I did try using the same approach as ocaml-libuv and started getting segfaults in |
If this is a low-latency callback, then running OCaml code is a bad idea anyway – one is not allowed to allocate memory in such a callback, much less grab a global lock. Low latency audio will still require code in a systems language. |
It's still interesting to actually test these boundaries and challenge pre-conceptions, even if you end up failing. For one thing it is very easy to guarantee that OCaml code will not allocate in a given function, especially if you are only filling a bigarray buffer with samples. |
There is still the global lock, and the fact that one can't actually do much useful without allocating. OCaml is not designed for this job. Use a lower-level language. |
Yeah you are right JavaScript would actually be a better fit. |
Btw. it's never a good idea to bound your views at the limits of your own creativity and knowledge. |
BTW, on my computer, the test_audio.native test fails with:
|
@yallop Do you have any idea about this assertion failure:
|
BTW, here is the change I was using that results in a segfault in diff --git a/src/tsdl.ml b/src/tsdl.ml
index 7d5a6e8..fe6e7ec 100644
--- a/src/tsdl.ml
+++ b/src/tsdl.ml
@@ -4573,6 +4573,9 @@ let audio_spec_of_c c as_ba_kind =
{ as_freq; as_format; as_channels; as_silence; as_samples; as_size;
as_ba_kind; as_callback; }
+external caml_c_thread_register : unit -> int = "caml_c_thread_register"
+external caml_c_thread_unregister : unit -> int = "caml_c_thread_unregister"
+
let audio_spec_to_c a =
let wrap_cb = match a.as_callback with
| None -> None
@@ -4580,9 +4583,11 @@ let audio_spec_to_c a =
let kind_bytes = ba_kind_byte_size a.as_ba_kind in
let ba_ptr_typ = access_ptr_typ_of_ba_kind a.as_ba_kind in
Some begin fun _ p len ->
+ ignore (caml_c_thread_register ());
let p = coerce (ptr uint8_t) ba_ptr_typ p in
let len = len / kind_bytes in
- cb (bigarray_of_ptr array1 len a.as_ba_kind p)
+ cb (bigarray_of_ptr array1 len a.as_ba_kind p);
+ ignore (caml_c_thread_unregister ())
end
in
let c = make audio_spec in |
So just talking to @yallop he mentions that the problem is certainly the fact that the OCaml runtime system is not aware of the audio thread. So @tokenrove's intuition is the good one but doing this in the callback is unfortunately already too late. Since we don't have a way of registering that thread with the runtime system using SDL's API. I'm simply going to remove that bit from the API until we can get something safe. |
Closing this, support for the audio callback was removed in 96143eb. We'll bind to audio buffers once SDL 2.0.4 is out. |
Even though audio buffers are certainly the way to go it would still be interesting to revert 96143eb and try with yallop/ocaml-ctypes#420 |
Let me know how it goes, if you do try it! |
@yallop it works ! |
This could deadlock the audio thread (#13) and broke the test suite.
Fantastic! Thanks for the update. |
Try to move mouse cursor over window. Always leads to crash (segfault 11, sometimes Bus error 10).
When you stop audio or remove event loop, everything works well.
When you switch to another app or do not emit any event, it works.
Tested on OSX 10.9, opam instalation of Ocaml 4.01.0, Tsdl 8.1, libsdl2.0.3 an libffi from macports.
Tested on MacBook Pro Retina and MacPro 2008 with usb audio device.
Compiled with: ocamlbuild -pkg tsdl audio.native
audio.ml:
The text was updated successfully, but these errors were encountered: