@ -1034,7 +1034,7 @@ class TlsStorage
public :
TlsStorage ( )
{
tlsSlots = 0 ;
tlsSlots . reserve ( 32 ) ;
threads . reserve ( 32 ) ;
}
~ TlsStorage ( )
@ -1077,15 +1077,27 @@ public:
size_t reserveSlot ( )
{
AutoLock guard ( mtxGlobalAccess ) ;
tlsSlots + + ;
return ( tlsSlots - 1 ) ;
// Find unused slots
for ( size_t slot = 0 ; slot < tlsSlots . size ( ) ; slot + + )
{
if ( ! tlsSlots [ slot ] )
{
tlsSlots [ slot ] = 1 ;
return slot ;
}
}
// Create new slot
tlsSlots . push_back ( 1 ) ;
return ( tlsSlots . size ( ) - 1 ) ;
}
// Release TLS storage index and pass assosiated data to caller
void releaseSlot ( size_t slotIdx , std : : vector < void * > & dataVec )
{
AutoLock guard ( mtxGlobalAccess ) ;
CV_Assert ( tlsSlots > slotIdx ) ;
CV_Assert ( tlsSlots . size ( ) > slotIdx ) ;
for ( size_t i = 0 ; i < threads . size ( ) ; i + + )
{
@ -1096,15 +1108,14 @@ public:
threads [ i ] - > slots [ slotIdx ] = 0 ;
}
}
// If we removing last element, decriment slots size to save space
if ( tlsSlots - 1 = = slotIdx )
tlsSlots - - ;
tlsSlots [ slotIdx ] = 0 ;
}
// Get data by TLS storage index
void * getData ( size_t slotIdx ) const
{
CV_Assert ( tlsSlots > slotIdx ) ;
CV_Assert ( tlsSlots . size ( ) > slotIdx ) ;
ThreadData * threadData = ( ThreadData * ) tls . GetData ( ) ;
if ( threadData & & threadData - > slots . size ( ) > slotIdx )
@ -1113,10 +1124,24 @@ public:
return NULL ;
}
// Gather data from threads by TLS storage index
void gather ( size_t slotIdx , std : : vector < void * > & dataVec )
{
AutoLock guard ( mtxGlobalAccess ) ;
CV_Assert ( tlsSlots . size ( ) > slotIdx ) ;
for ( size_t i = 0 ; i < threads . size ( ) ; i + + )
{
std : : vector < void * > & thread_slots = threads [ i ] - > slots ;
if ( thread_slots . size ( ) > slotIdx & & thread_slots [ slotIdx ] )
dataVec . push_back ( thread_slots [ slotIdx ] ) ;
}
}
// Set data to storage index
void setData ( size_t slotIdx , void * pData )
{
CV_Assert ( pData ! = NULL ) ;
CV_Assert ( tlsSlots . size ( ) > slotIdx & & pData ! = NULL ) ;
ThreadData * threadData = ( ThreadData * ) tls . GetData ( ) ;
if ( ! threadData )
@ -1131,7 +1156,11 @@ public:
}
if ( slotIdx > = threadData - > slots . size ( ) )
threadData - > slots . resize ( slotIdx + 1 ) ;
{
AutoLock guard ( mtxGlobalAccess ) ;
while ( slotIdx > = threadData - > slots . size ( ) )
threadData - > slots . push_back ( NULL ) ;
}
threadData - > slots [ slotIdx ] = pData ;
}
@ -1139,7 +1168,7 @@ private:
TlsAbstraction tls ; // TLS abstraction layer instance
Mutex mtxGlobalAccess ; // Shared objects operation guard
size_t tlsSlots ; // TLS stor age coun ter
std : : vector < int > tlsSlots ; // TLS keys state
std : : vector < ThreadData * > threads ; // Array for all allocated data. Thread data pointers are placed here to allow data cleanup
} ;
@ -1159,6 +1188,11 @@ TLSDataContainer::~TLSDataContainer()
CV_Assert ( key_ = = - 1 ) ; // Key must be released in child object
}
void TLSDataContainer : : gatherData ( std : : vector < void * > & data ) const
{
getTlsStorage ( ) . gather ( key_ , data ) ;
}
void TLSDataContainer : : release ( )
{
std : : vector < void * > data ;