# Lwt, system threads, FUSE and ocamlfuse

**URL:** https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387
**Category:** Learning
**Tags:** lwt
**Created:** [March 27, 2020, 9:41am UTC](https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387 "2020-03-27T09:41:32Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)
#### Post date: [March 27, 2020, 9:41am UTC](https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387/1 "2020-03-27T09:41:32Z")

</div>

I want to implement a silly filesystem using ocamlfuse. In the silly filesystem implementation, everything is in the Lwt monad.

ocamlfuse (and FUSE itself) allow working in two different modes: single-threaded and multithreaded.  
ocamlfuse has an “event loop” I believe. If we stick to single-threaded FUSE/ocamlfuse usage, the main thread repeatedly takes a request and services it.

Now, if the implementation is using Lwt, there seem to be two problems: 1) we can’t run the top-level Lwt\_main.run loop in the main thread, because that is being used for the ocamlfuse event loop, and 2) after servicing a request using Lwt code, it is not immediately obvious how to extract a result from the Lwt monad and return it to the ocamlfuse event loop (?).

Regarding 1), can I just create a new Thread.t and run the Lwt\_main.run loop there, whilst ocamlfuse executes in the initial thead?

Regarding 2), in single-threaded mode (for the time being), can I just create eg an ('a ref \* semaphore) spawn the lwt thread (and block the ocamlfuse thread by waiting on the semaphore), and at the end of the lwt thread, make sure I place the result in the ref and signal the semaphore to indicate that the result is available ?

I hope this description makes sense to someone.

---

<div class="post-metadata">

### Author: ![antron](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/antron/32/62_2.png) [@antron](https://discuss.ocaml.org/u/antron)
#### Post date: [March 28, 2020, 10:30am UTC](https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387/2 "2020-03-28T10:30:34Z")

</div>

For 1), Lwt _should_ work that way. As I remember, Lwt does not really know which thread is the “main” thread. There is a pipe that Lwt’s worker threads use to communicate Lwt I/O completions back to the Lwt main loop, and `Lwt_main.run` monitors that pipe. So, you should, in principle, be able to monitor it from a spawned thread.

I’m not sure what the issue in 2) is. What kind of semaphore are you creating? If it is something based on `Mutex` and `Condition` from the standard library, then this question seems to be about ordinary inter-thread communication, and yes, you can do it. What does single-threaded mode refer to here? It seems clear you want two threads to communicate with each other. If the ocamlfuse thread has a main loop to run, can it afford to block on the semaphore?

---

<div class="post-metadata">

### Author: ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)
#### Post date: [March 30, 2020, 11:59am UTC](https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387/3 "2020-03-30T11:59:10Z")

</div>

Hi,

My 2) was not well phrased.

ocamlfuse can service filesystem operations in either a single-threaded mode one-at-a-time, or using multiple threads (which is potentially faster of course). At the moment I am just trying to get the single-threaded mode to work.

As you say, I want to communicate a value back from the lwt thread to the ocamlfuse thread which is presumably doing something like waiting on a Stdlib.Mutex.t. Indeed, the current implementation has the ocamlfuse thread waiting on a mutex, and the lwt code just signals a condition variable in the usual way before unlocking the mutex.

I guess my question then is: when the lwt thread initially acquires the mutex, at the moment it does a plain Mutex.lock; since this is potentially long-running (although in this scenario, not much) does this need to use something like Lwt\_preemptive.detach to avoid blocking the main Lwt loop? The issue is that there may be other lwt promises doing all sorts of things, which I don’t want to block while one lwt thread waits on a Stdlib.Mutex. Does this make sense?

Maybe the question is: what are the best practices for lwt when working with Stdlib.Mutex and Stdlib.Condition (i.e., when trying to co-exist with other threads)?

---

<div class="post-metadata">

### Author: ![antron](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/antron/32/62_2.png) [@antron](https://discuss.ocaml.org/u/antron)
#### Post date: [March 30, 2020, 12:19pm UTC](https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387/4 "2020-03-30T12:19:16Z")

</div>

You could use `Lwt_preemptive.detach` — just make sure to use one call for the whole lock-signal-unlock sequence, not multiple, and interact with the rest of Lwt by calling `Lwt_preemptive.run_in_main` in between. This “should” convert blocking on a mutex into blocking on the internal pipe that is inside `Lwt_main.run`. It does seem a little inconvenient to need a third thread for the two threads to interact. I am not sure if there is some better way to make Lwt and ocamlfuse interact, but I would try to find one.

As for best practices, I think these situations are rare enough to be unique, so it’s not clear what the best practices are.

---

<div class="post-metadata">

### Author: ![thomas\_ridge](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thomas_ridge/32/1478_2.png) [@thomas\_ridge](https://discuss.ocaml.org/u/thomas_ridge)
#### Post date: [March 30, 2020, 1:21pm UTC](https://discuss.ocaml.org/t/lwt-system-threads-fuse-and-ocamlfuse/5387/5 "2020-03-30T13:21:28Z")

</div>

Thanks @antron! I will try some things out and maybe update this post if I find anything better.
