I need to develop an api, that synchronously allows access to a shared asynchrounous resource. For simplicity lets assume a boolean resource resource, that might take some time to switch its state. It is currently set to false and two clients want to set it to true concurrently. I would like the second client to see that a operation is in progres, and asynchronously wait for its completion. Is there a possibility to somehow add a completion handler to a running asynchronous operation?
What I am currently trying to do, is creating one of asio's timers, set its expire time to a very large value and cancel it when the operation finishes. Any clients get notified through the timer cancel.
void set_true() {
mytimer.expires_after(<a long time>);
if ( !resource.busy )
resource.busy = true;
resource.async_set_true( [](){
resource.busy = false
mytimer.cancel();
});
mytimer.async_wait(do_return);
}
void do_return(...) {
...
}
While I think, that this will work, it feels like
- this is a misuse of the timer classes, since I am not even using their "timer" functionality
- with some kind of asynchronously awaitable lock, this task would be solved more naturally (combining the
busyflag and the notifying into one primitive)
I searched for asynchronous locks in asio, but could not manage to find one. Yet this problem seems so fundamental to me, that I cannot believe, that there is no better solution to this, than the one I mentioned. Note that I don't want to use real locks and I don't need advice to make my code thread-safe, because the API is supposed to run single threaded.
Questions
- is there any asynchronous lock mechanism in asio?
- if there isn't, is there a reason why?
- is there an alternative way using strands to elegantly solve this problem?
