Sign in to follow this  
mfawcett

RAII Singleton Wrapper?

Recommended Posts

Some of the code we write relies on third-party software that has pretty tight license restrictions. To be able to use their API, code must call Initialize from their Singleton Object (it's a COM class) once at application startup to checkout the correct license, and then call Shutdown once at application end (this should be the last thing called). Code looks like this usually:
// Sometime after ::CoInitialize, but before we start using their API
IInitializerPtr init(CLSID_Initializer);
init->Initialize(requested_license);

... // application stuff

init->Shutdown();
// ::CoUninitialize called sometime later

Note that you don't have to retain a pointer to the Initializer instance since every time you instantiate one you get the same one back (it's a Singleton behind the scenes). I want to be able to provide a wrapper that guarantees that Shutdown gets called once at the end of the program. As it currently is, if you don't call it, the license never gets checked back in. I suspect this could be made pretty generic and useful since lots of C libraries have init and shutdown calls that must be made once at startup, and once at shutdown. For example, DevIL has iluInit/iluShutdown() and ilutInit/ilutShutdown() calls that must be paired, similar to my situation above. A simple RAII wrapper might work, but what are some of the caveats? Should it be non-copyable so init/shutdown don't get called multiple times? Is this a valid case for a Singleton? What would your fail-safe, "users can't possibly get this wrong", solution be?

Share this post


Link to post
Share on other sites
Most Singleton implementations tend to hand-wave the whole "destruction" thing. That's because Singleton is actually the worst possible creational pattern to use here. With the Singleton pattern, nobody has any idea how many handles to a given resource are outstanding, because handles tend to have no-op destructors. Much more useful would be a non-Singleton, non-copyable object with reference-counted handles, such that the object is destroyed when the last handle goes away.

In this case, however, I would be inclined to discard OO patterns altogether. Make your initializer global and call Shutdown in an atexit handler. That'll help with (some) crash situations, and eliminate the danger of resource leaks. It's also a lot simpler than the corresponding OOP brouhaha.

Fun note: Did you know that Firefox's spelling dictionary contains "brouhaha" but not "destructor"?

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Much more useful would be a non-Singleton, non-copyable object with reference-counted handles, such that the object is destroyed when the last handle goes away.
This could be implemented as a 'Monostate', if you have a fondness for design patterns.

Share this post


Link to post
Share on other sites
I always found Monostate to be nothing more than a slightly obfuscated Singleton, at least in its classic implementation. I'm therefore guessing that it'll be the Next Big Thing once everybody figures out that they've just been using singletons to pretend they aren't using globals.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this