Modify Boost (2)

zhaozj2021-02-08  229

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 :: cleanup) {}

T * get () const {return static_cast (m_tss.get ());}

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 (p);}

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 cleanup_handlers;

Boost :: thread_specific_ptr PTR_GLOBAL; Class Tsskey

{

TSSKEY ();

PUBLIC:

Static TSSKey & Instance ();

Unsigned int alloc ();

Void Free (int key);

Boost :: mutex m_lock;

Std: Set allkey;

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 / boost / thread / directory, and the vtss.cpp file is placed in / libs / thread / src. The only difference between their usage and the original pthread_specific_ptr is more than "V", which is vpthread_specific_ptr. In addition, you can also remove the private noncopyable of vpthread_specific_ptr, then if your vPthread_Specific_PTR is in the class object, the object can also be copied each other.

Secondly, the implementation is reading and writing locks, let go.

转载请注明原文地址:https://www.9cbs.com/read-3056.html

New Post(0)