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?