aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2007-10-07 22:53:59 +0000
committerlloyd <[email protected]>2007-10-07 22:53:59 +0000
commit47fec89661791a34ae2793a24503e18736a52c47 (patch)
treee8f9c0af1738701abf598ebc4942c26a38911c60
parent273c36c5b28777ac58fdffbc27e9e0dcbd59ce14 (diff)
If we attempt to access the global state, and it is null, call
LibraryInitializer::initialize(), which will set it for us (or fail by throwing an exception, which will be propogated to the caller). So any instances of creating a LibraryInitializer where no option arguments are passed can be removed; instead that initialization will run when or if you execute an operation where Botan requires the services provided in the state. Because no options are passed, the library will be using the default (debug and not thread safe) mutex type: so hopefully you'll quickly get an exception when the debug mutex realizes it is being used in a threaded application, but there is risk of operations silently failing before that happens. You can call LibraryInitializer::deinitialize() at the end of your main function (or whenever you think you won't need Botan anymore), to free the global state; if not a number of cleanup destructors will not run (including the final scrub of memory). You can even shut down Botan speculatively; if it turns out you need it again, it just means you'll have to take the cost of another initialization. However in applications that use Botan only in small bursts, or in rarely taken codepaths, you can remove the state entirely and suffer zero memory overhead. This probably only makes sense in memory constrained systems, but it's reasonable to do now. Speculatively deallocating the state is probably not thread safe without extra work. One thread calling deinitialize() would invalidate pointers that would have been visible to other threads. One (untested) idea: have an atomic integer with the number of current threads using Botan. If any thread decrements and hits zero, it could deinitialize Botan safely. This might cause too many repeated startup/shutdowns, which would depend on the app use pattern. In addition, since you can't pass arguments to the new Library_State, you can't specify the use of real mutexes (or anything else): so for right now, this only works in applications that are fine with the standard options. I want to find a way to get that working, though, since it's very inelegant. Currently a Default_Mutex (not at all thread safe but somewhat error checking) will be used. And self test will always be run (more on that below). I wrote a program that just initializes and shuts down in a tight loop. Running on my Gentoo box (Core2 E6400, gcc 4.1.2): thread_safe? selftest? time (ms) ------------ --------- --------- no yes 6.1 no no 3.8 yes yes 6.7 yes no 3.8 If you're actually worried that the library might start up OK but then start failing basic self tests, what you actually want to do is have a thread that runs diagnostics on your entire process state (including calling Botan's self test code) every N seconds. The question is how to get arguments from the outside world to the constructor of the Library_State that is created inside of global_state(): avoiding many self tests to save a bit of time (many applications won't care about the extra cost but sometimes 2 or 3 ms is important), and thread safety (beacuse you can't specify to use a real mutex).
-rw-r--r--src/libstate.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/libstate.cpp b/src/libstate.cpp
index e2a81d598..62ecd5cdf 100644
--- a/src/libstate.cpp
+++ b/src/libstate.cpp
@@ -31,7 +31,7 @@ Library_State* global_lib_state = 0;
Library_State& global_state()
{
if(!global_lib_state)
- throw Invalid_State("Library was not initialized correctly");
+ LibraryInitializer::initialize();
return (*global_lib_state);
}