RAII Singleton Wrapper?

Started by
3 comments, last by Sneftel 15 years, 5 months ago
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?
--Michael Fawcett
Advertisement
First off there is no way to guaranty it(think power loss, etc.) Second have you tried the easy way and used atexit()?
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"?
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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

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.

This topic is closed to new replies.

Advertisement