Deinit and MainActor

This topic was brought up again in another thread.

I looked up how executors are normally switched for async methods - it is done using swift_task_switch which takes async context as one of its parameters, what we obviously don't have in the release/dealloc context.

But maybe it is doable using more low-level tools. @Douglas_Gregor, can Job be constructed without any task? If so, then compiler could synthesise code in __deallocating_deinit that switches to the desired executor.

void MyClass__deallocating_deinit(void *self) {
    ExecutorRef myExecutor = ... // Read executor from self in case of actor or use one from global actor
    if (swift_task_isCurrentExecutor(myExecutor)) {
        return MyClass__deallocating_deinit_impl(self);
    }
    // New runtime function
    // Creates job in regular heap, does not use task allocator
    // Should priority be copied from the current task?
    Job *deallocJob = swift_task_createDeallocJob(self, MyClass__deallocating_deinit_impl);
    swift_task_enqueue(deallocJob, myExecutor);
}

void MyClass__deallocating_deinit_impl(void *self) {
   ...
   swift_deallocClassInstance(self, ...);
}

Would this work?

1 Like