Modify Boost (2)
The three_specific_ptr provided by Boost is easy. However, the number of available indexes of TLS is limited. Especially in the DLL, if the first process loaded DLL module uses N indexes, the second process is loaded with the same module to reduce N, and the index available under Windows is about 1,000. I didn't check the information, just by memory, if there is an error, you can point out in the discussion below, but it is probably what this means). However, only one TLS index is used to save all the thread-related data. The following is the source code.
1. Header file vtss.hpp
//VTSS.HPP. Virtual TSS index
#ifndef _vtss_h
#define _vtss_h
#include
Namespace boost {
Namespace detail {
Class VTSS
{
PUBLIC:
VTSS (Void (* Cleanup) = 0);
~ vtss ();
Void * get () const;
Bool Set (Void * Value);
Private:
Unsigned int key;
}
}
Template
Class vthread_specific_ptr: Private NoncopyAble
{
PUBLIC:
vthread_specific_ptr (): m_tss (& thread_specific_ptr
T * get () const {return static_cast
T * Operator -> () const {return get ();
T & operator * () const {return * get ();
T * Release () {t * temp = get (); m_tss.set (0); return temp;}
Void reset (t * p = 0) {t * cur = get (); if (cur == p) return; delete cur; m_tss.set (p);}
Private:
Static void cleanup (void * p) {delete static_cast
Mutable Detail :: VTSS M_TSS;
}
} // Namespace Boost
#ENDIF
2.vtss.cpp file
#include
#include
#include
#include
#include
Namespace {
Class cleanup_info
{
PUBLIC:
Cleanup_info (void (* _Cleanup) = 0, void * _data = 0)
: cleanup (_CLEANUP), DATA (_DATA) {}
~ Cleanup_info () {if (Cleanup && Data) Cleanup (data);}
Void reset () {data = 0;}
Void (* Cleanup) (void *);
Void * Data;
}
TypedEf std :: map
Boost :: thread_specific_ptr
{
TSSKEY ();
PUBLIC:
Static TSSKey & Instance ();
Unsigned int alloc ();
Void Free (int key);
Boost :: mutex m_lock;
Std: Set
Unsigned int key;
}
TSSKey :: TSSKEY (): Key (0)
{
}
TSSKey & Tsskey :: instance ()
{
Static TSSKey TSS;
Return TSS;
}
Unsigned int Tsskey :: alloc ()
{
Boost :: Mutex :: Scoped_lock Lock (M_Lock);
While (allkey.find ( key)! = allkey.end ());
Return Key;
}
Void Tsskey :: free (int key)
{
Boost :: Mutex :: Scoped_lock Lock (M_Lock);
AllKey.rase (Key);
}
}
Namespace boost {
Namespace detail {
VTSS :: VTSS (Void (* Cleanup) (void *))
: m_cleanup (Cleanup)
{
M_key = tsskey :: instance (). alloc ();
}
VTSS :: ~ VTSS ()
{
TSSKey :: instance (). free (m_key);
}
Void * vtss :: get () const
{
Cleanup_handlers * p = ptr_global.get ();
IF (p)
{
Cleanup_handlers :: itrator it = p-> find (m_key);
IF (it! = p-> end ())
{
Return it-> second.data;
}
}
Return 0;
}
Void VTSS :: Set (Void * Value)
{
Cleanup_handlers * p = ptr_global.get ();
IF (! p)
{
P = new cleanup_handlers;
PTR_GLOBAL.RESET (P);
}
IF (Value)
{
Cleanup_info info (m_cleanup, value);
(* p) [m_key] = info;
Info.reset ();
}
Else
{
P-> ERASE (M_Key);
}
}
} // Namespace Detail
} // Namespace Boost
3. VTSS.HPP files are placed in the
Secondly, the implementation is reading and writing locks, let go.