On 23/05/2023 10:39, Suraaj K S wrote:
Using this, I wanted to build a 'memory checker'. It has two functions -> `request_space` and `free_space`. A coroutine calls `request_space`, which may block if there is no space left. Meanwhile, another thread / coroutine can call `free_space`, which will run blocked coroutines if possible.
Coroutines and mutexes are mortal enemies; they should not be mixed. Very especially holding locks across async boundaries is a big no-no. Usually the best way to manage coroutines is to not schedule them until they have useful work to do. If you want something more like traditional threading primitives for coroutines instead, consider Boost.Fiber.
Finally, somewhat more surprisingly, If I replace /post(stand_,std::move(posted_lambda));/ by /post(pending_queue_,std::move(posted_lambda));/, things seem to work. However, the asio documentation says that only strands guarantee a FIFO execution order. I am not sure if using a simple `io_context` will work as a FIFO queue (even though it seems to in these examples).
An io_context with only a single thread will behave equivalently to posting all work via a strand (as will posting new work only in response to existing work completing, or when there is no existing work -- read up about "implicit strand"). However, if you block that thread, nothing will be able to progress, possibly including the work needed to unblock the thread, leading to deadlock.