Setting a class up as a singleton is not uncommon:
Shared Function SharedInstance() As MyClass
If mSharedInstance Is Nil Then
mSharedInstance = New MyClass
End If
Return mSharedInstance
End Function
mSharedInstance
is a shared property, so you’d just call MyClass.SharedInstance
to get to the singleton. It’s kind of like a module, but since it’s a class, it gets a constructor for initialization and can have additional instances if necessary.
With preemptive threads, since it can be possible to run the same line across multiple threads at the same time, the test and creation needs to be locked if I’m not mistaken:
Shared Function SharedInstance() As MyClass
If mInstanceLock Is Nil Then
mInstanceLock = New CriticalSection
End If
mInstanceLock.Enter
If mSharedInstance Is Nil Then
mSharedInstance = New MyClass
End If
mInstanceLock.Leave
Return mSharedInstance
End Function
But… doesn’t this have the same problem? Detection and creation of the instance can now be synchronized between threads, but the lock used to do so is now vulnerable.
The best idea I’ve come up with is just a Call MyClass.SharedInstance
on the main thread before any preemptive threads are started. Which kind of begs the question: why use a singleton instead of a module, if I have to call what is essentially an init routine anyway? A singleton is self-initializing, but I can’t think of a way to pull that off with preemptive threads.
I feel like I’m missing something simple though.