aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-03-16 08:20:01 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-03-16 08:20:01 +0200
commit58a02e9c923fbc9b8f59c5b52ec7c8c55adffa31 (patch)
tree64c1db988fc841a1a1d44418b4757ef187af3e80
parentcdb8876ff271ce235c2f02a917a0c79a37d5c4b0 (diff)
Make sure we can free memory even in case of "unsafe" DLL termination1.2.0
-rw-r--r--odb/details/win32/tls.cxx29
1 files changed, 18 insertions, 11 deletions
diff --git a/odb/details/win32/tls.cxx b/odb/details/win32/tls.cxx
index 27778b2..d76d560 100644
--- a/odb/details/win32/tls.cxx
+++ b/odb/details/win32/tls.cxx
@@ -66,21 +66,22 @@ namespace odb
InitializeCriticalSection (&cs_);
- proc_data_ = static_cast<process_data*> (
- operator new (
- sizeof (process_data) + sizeof (dtor_func) * init_capacity));
+ process_data* pd (
+ static_cast<process_data*> (
+ operator new (
+ sizeof (process_data) + sizeof (dtor_func) * init_capacity)));
- proc_data_->size = 0;
- proc_data_->capacity = init_capacity;
- memset (proc_data_->dtors, 0, sizeof (dtor_func) * init_capacity);
+ pd->size = 0;
+ pd->capacity = init_capacity;
+ memset (pd->dtors, 0, sizeof (dtor_func) * init_capacity);
+
+ proc_data_ = pd;
}
void
- tls_process_end (bool safe)
+ tls_process_end (bool)
{
- if (safe)
- operator delete (proc_data_);
-
+ operator delete (proc_data_);
DeleteCriticalSection (&cs_);
if (index_ != TLS_OUT_OF_INDEXES)
@@ -134,6 +135,10 @@ namespace odb
{
c *= 2;
+ // Try to do "atomic" switch-over so that proc_data_ always points
+ // to memory that can be freed even if this thread is killed in the
+ // middle.
+ //
process_data* pd (
static_cast<process_data*> (
operator new (sizeof (process_data) + sizeof (dtor_func) * c)));
@@ -143,8 +148,10 @@ namespace odb
pd->size = n;
pd->capacity = c;
- operator delete (proc_data_);
+
+ process_data* old (proc_data_);
proc_data_ = pd;
+ operator delete (old);
}
proc_data_->dtors[n] = dtor;