Re: [asio-users] Waiting on pending work
Brought to you by:
chris_kohlhoff
From: Vinnie F. <vin...@gm...> - 2022-02-22 03:17:46
|
On Mon, Feb 21, 2022 at 4:54 PM Rory Jaffe <rs...@gm...> wrote: > At each class's shutdown, I want to make sure the work is completed before destroying the class. You have it backwards. Instead of doing funny business in your workers' destructors, just make sure that the lifetime of the worker is extended until it is complete. In other words, in your worker class T, extend the lifetime by storing an instance of shared_ptr<T> in every completion handler associated with that worker. > Currently, I use a std::binary_semaphore, acquire the semaphore > when work first starts, then release the semaphore when the work > cycle exits, whether it exits by a socket error, finish signal, or exception. > Then I acquire the semaphore in the destructor, which forces the > destructor to wait for the semaphore to be released. Yeah this is going to be messy, as you have discovered. You should not need any additional synchronization primitives at all. If you find that you are trying to do "interesting" things in destructors of objects that perform work submitted to executors, it usually means you're using the wrong pattern. The usage of shared_ptr to manage the lifetime of long-running work is covered in my video "Get Rich Quick!", cued to the right time at this link: <https://youtu.be/7FQwAjELMek?t=1347> Once you invert the model of ownership as I described above, cleanly terminating the application becomes easy: 1. Stop queuing new work, and 2. Wait for io_context::run to return from all threads Hope this helps! |