c++asynchronousraii

Asynchronous Destruction and RAII in C++


According to RAII when I destroy the object, its resources are deallocated. But what if the destruction of the object requires asynchronous operations? Without using RAII I can call close method of my class that will call necessary async operations and will keep shared_ptr to my object (using shared_from_this) in order to gracefully process callbacks from the async operations. After calling close I can remove my pointer to the object since I do not need it anymore - but I know that the object will not be removed until the async operations are executed.

But how can I achieve this using RAII? One of the possible solutions can be using a wrapper that when destructed will call close method of by object. But.. will it mean that my classes are RAII classes?

class Resource: public std::enable_shared_from_this<Resource> {
    int id;
public:
close() {
    some_async_functin([t = shared_from_this()] {
        std::cout << "Now I am closed " << t->id << std::endl;
    }
}



}

My solution:

class ResourceWrapper {
   std::shared_ptr<Resource> res;

   ~ResourceWrapper() {
       res.close();
   }
}

Solution

  • An object o to be asynchronously destroyed with respect to the thread, T, in which it was created cannot itself be managed via RAII, because destruction of stack-allocated objects is inherently synchronous. If o is managed via the RAII model then thread T will execute its destructor when the innermost block containing its declaration terminates, until the destructor terminates.

    If you do not want to occupy T with releasing o's resources (yet ensure that they are in fact released), then you must delegate the resource release to another thread. You can do that either

    The latter is indirect because it requires a separate object or objects to represent the resource(s) being cleaned up until the cleanup is complete -- especially so if there are callbacks involved or similar. You face the same issue with these objects that you do with o itself. There is nothing inherently wrong with this indirection, by the way. RAII still provides the benefits it usually does.