std::function<void(ExternalObject*)> ObjectDeleter(std::shared_ptr<Simulation> simulation) { return [=](ExternalObject* obj) { //We have to make sure to call the callback outside the lock. //To that end, we gather information as follows, and then queue it. bool isExternal; int handle; LOCK(*simulation); isExternal = obj->is_external_object; handle = obj->external_object_handle; //WARNING: this line can call this deleter recursively, if obj contains the final shared pointer to another ExternalObject. delete obj; //Because of the recursion, shell out to the simulation's task thread. if(isExternal && handle_destroyed_callback) simulation->enqueueTask([handle] () {handle_destroyed_callback(handle);}); }; }
std::function<void(ExternalObject*)> ObjectDeleter(std::shared_ptr<Server> server) { return [=](ExternalObject* obj) mutable { //We have to make sure to call the callback outside the lock. //To that end, we gather information as follows, and then queue it. bool isExternal; int handle; LOCK(*server); isExternal = obj->is_external_object; handle = obj->external_object_handle; //WARNING: this line can call this deleter recursively, if obj contains the final shared pointer to another ExternalObject. delete obj; //Because of the recursion, shell out to the server's task thread. if(isExternal && handle_destroyed_callback) server->enqueueTask([handle] () {handle_destroyed_callback(handle);}); //The server holds weak_ptrs to nodes. //weak_ptrs hold references to this deleter. //Therefore there is a cycle. server = nullptr; }; }