# Reading SDL events (via TSDL)

**URL:** <https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052>\
**Category:** Learning\
**Tags:** lwt, tsdl\
**Created:** [November 1, 2017, 9:39pm UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052 "2017-11-01T21:39:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cfcs](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cfcs/32/833_2.png) [@cfcs](https://discuss.ocaml.org/u/cfcs)\
**Post date:** [November 1, 2017, 9:39pm UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/1 "2017-11-01T21:39:54Z")

</div>

Hello!

I’m trying to read input events from @dbuenzli’s [TSDL](https://github.com/dbuenzli/tsdl/) library in my Lwt application.

API: [http://erratique.ch/software/tsdl/doc/Tsdl.Sdl.html#events](http://erratique.ch/software/tsdl/doc/Tsdl.Sdl.html#events)

```ocaml
val wait_event : event option -> unit result

```

If I use `wait_event` I block the OS thread, meaning everything grinds to a halt.

```ocaml
val wait_event_timeout : event option -> int -> bool

```

This is slightly better, since it allows me to schedule some Lwt threads every now and then, but still halts the main thread.

* * *

I feel like I need another OS thread here, and somehow have that write into a `Lwt_mvar.t` or similar that I can use from inside Lwt.

Can anyone point me to an example of similar code, or to a possible solution for this problem?

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [November 1, 2017, 9:52pm UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/2 "2017-11-01T21:52:55Z")

</div>

You may want to check [`useri`](http://erratique.ch/software/useri). I’m no longer sure if it fully solved the problem in the way you want but it was designed to work both with cooperative concurency and event callbacks (e.g. the browser via `jsoo`), see [here](https://github.com/dbuenzli/useri/blob/master/test/test_tsdl_lwt.ml) for an example.

---

<div class="post-metadata">

**Author:** ![cfcs](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cfcs/32/833_2.png) [@cfcs](https://discuss.ocaml.org/u/cfcs)\
**Post date:** [November 1, 2017, 10:36pm UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/3 "2017-11-01T22:36:52Z")

</div>

Thank you!

I had not considered doing tick-based reading, but that will definitely work for my case.  
The alternative quickly becomes unnecessarily complex, so I will adopt your approach. 🙂

By the way: I found this to be a good source of examples of reading various types of input: [https://github.com/dbuenzli/useri/blob/master/src-tsdl/useri\_backend\_tsdl.ml](https://github.com/dbuenzli/useri/blob/master/src-tsdl/useri_backend_tsdl.ml)

---

<div class="post-metadata">

**Author:** ![Freyr666](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/freyr666/32/591_2.png) [@Freyr666](https://discuss.ocaml.org/u/Freyr666)\
**Post date:** [November 2, 2017, 8:00am UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/4 "2017-11-02T08:00:52Z")

</div>

Is it possible to wait for an event in a separate preemptive lwt thread?

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [November 2, 2017, 9:21am UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/5 "2017-11-02T09:21:22Z")

</div>

> [@Freyr666](#):
>
> Is it possible to wait for an event in a separate preemptive lwt thread?

You have to be careful with these things, as the underlying OS libraries may have strong requirements about which thread is allowed to get user events (IIRC on `macos` this had to be done on the main thread). As far as SDL is concerned you [have to](https://wiki.libsdl.org/SDL_WaitEvent) do this in the same thread that initialized the video subsystem.

---

<div class="post-metadata">

**Author:** ![cfcs](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cfcs/32/833_2.png) [@cfcs](https://discuss.ocaml.org/u/cfcs)\
**Post date:** [November 2, 2017, 1:45pm UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/6 "2017-11-02T13:45:10Z")

</div>

Here’s the code I ended up with for this tick-based thing instead of getting into the misty swamps of portable thread synchronization:

> <https://github.com/cfcs/mirage-framebuffer/blob/master/tsdl/framebuffer_tsdl.ml#L47-L92>

---

<div class="post-metadata">

**Author:** ![mbacarella](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mbacarella/32/2420_2.png) [@mbacarella](https://discuss.ocaml.org/u/mbacarella)\
**Post date:** [July 22, 2020, 2:49pm UTC](https://discuss.ocaml.org/t/reading-sdl-events-via-tsdl/1052/7 "2020-07-22T14:49:17Z")

</div>

To add my 0.02 cents to this old thread.

I had a Tsdl + Lwt application that worked fine when I was using software renderers, but then I swapped an Nvidia GPU into the computer and the application stopped updating the window altogether.

Although the SDL docs say you need to make sure you limit stuff like SDL\_WaitEvent to the thread that initialized SDL video, the underlying Nvidia library appears to further require (without logging anything?) that this thread is the first application thread. I had tried to coordinate all SDL stuff through a detached thread, which didn’t work.

The solution was to do all of the SDL stuff in my main thread and adopt the polling approach mentioned here to get multi-threading to work. Thanks for posting this!
