• Some users have recently had their accounts hijacked. It seems that the now defunct EVGA forums might have compromised your password there and seems many are using the same PW here. We would suggest you UPDATE YOUR PASSWORD and TURN ON 2FA for your account here to further secure it. None of the compromised accounts had 2FA turned on.
    Once you have enabled 2FA, your account will be updated soon to show a badge, letting other members know that you use 2FA to protect your account. This should be beneficial for everyone that uses FSFT.

First time implementing a singleton...

Khanmots

Gawd
Joined
May 12, 2007
Messages
905
... and while I think I have determined that I don't need it, I'd like to know if the singleton implementation that I had put together would have had any nasty side-effects that I hadn't considered... as I'm sure that if I keep working directly with device drivers, I'll eventually have a real need for one and I'd like to not have it blow up on me then :)

The basics were a singleton TheDevice class with:
A) a private constructor that would open and initialize the device
B) a private destructor that would shutdown and close the device (and unlock the mutex not unlocked when it's called in D below)
C) a protected getInstance function looking something like:
Code:
mutex.lock();

  if(NULL == theInstance)
  {
    theInstance = new TheDevice();
  }

  numReferences++;

mutex.unlock();

return theInstance;
D) a protected releaseInstance function looking something like:
Code:
mutex.lock();

numReferences--; 

if(0 == numReferences)
{
  delete this;
  // following the delete we can no longer reference any (non-static) variables or functions of this class
}
else // need an else, as this code must not be executed after the destructor is called
{
  mutex.unlock();
}

Finally, there would be a Controller class which would be a friend of TheDevice and thus could call getInstance and releaseInstance. Resulting in a Controller class that could be created/destroyed as a normal class, but with only a single instance of the Device class shared by all instances of the Controller class.
 
It'll be fine, though I'm not sure why you're doing "delete this" and not "delete theInstance".
 
Typically a singleton isnt reference counted and deleted, it lives for the life of the program. At least from my java experience.

I don't know if you were simplifying for the posting here, but i think you're missing some error checking code. Such as ensuring you actually got the mutex lock, making sure your numReferences doesnt overflow and wrap around.

Something seems suspicious about the destructor unlocking the mutex, but i can't pin it down. Id move it to just after the delete. If you removed the else and just had it always unlock, that would do it.
I don't know what all your destructor does though.
 
Typically a singleton isnt reference counted and deleted, it lives for the life of the program. At least from my java experience.

I don't know if you were simplifying for the posting here, but i think you're missing some error checking code. Such as ensuring you actually got the mutex lock, making sure your numReferences doesnt overflow and wrap around.

Due to the program architecture, we shouldn't ever see more than maybe 10-15 calls of getInstance(). I'll likely wind up putting in wrap-around tests to avoid peer-review comments, but this early in trying to hash it out I'm not too worried :) As for the mutex, it's a platform independent wrapper class that returns void on the operations so there's nothing to check for (not my design...)

Anyways, The reason I'm looking to delete it is that it will have opened file descriptors to DMA devices, and at the point I posted this I was unsure of behavior upon program exit. Since then I've discovered that on a POSIX compliant platform they're closed. I'm thinking it may be a good idea to leave the cleanup in though so my code is easier to port (which considering the number and scope of change requests we get on this program.... may be more likely than you think :( )

Something seems suspicious about the destructor unlocking the mutex, but i can't pin it down. Id move it to just after the delete. If you removed the else and just had it always unlock, that would do it.
I don't know what all your destructor does though.

I started to say that if I removed the else and had it always unlock then in the case where the delete was called, the following call to unlock the mutex would result in undefined behavior as the mutex is a member variable of the instance being deleted.

But then I realized that the mutex is static (so it can be accessed by the static member functions), and that isn't going to be the case... doh! You're right :)
 
What parameterless mutex acquisition function can return failure?

If the mutex is static (and therefore a singleton), why isn't the singleton a static?
 
What parameterless mutex acquisition function can return failure?
It could throw an exception or block and wait (ick all kinds of problems with that idea).

If the mutex is static (and therefore a singleton), why isn't the singleton a static?
If the singleton were static it couldn't be deleted until program completion, which may not be desirable, or at least might make the code messier to handle possible re initialization and facilities for cleaning up outside the constructor/destructor. And it doesn't really buy you anything since the singleton scaffolding ensures a single instance anyway.
 
Is there any particular reason you need a singleton? It sounds more like you want your controller to be a Factory.
 
Back
Top