Modify Boost (1)
Boost is a good library. But it is not too mature. For example, Boost's processing TLS is Boost_ThreadMon.dll, using the TLS code must bring a dynamic link library; secondary library can not be installed automatically, nor can you choose from your program (such as MT, MD) Select the library, if you have a lot of things every time you write a small test program, I am afraid that it is too powerful; third, lack some common functions, such as events, read and write locks, etc. Today I want to set it that you can use Boost if you only need to set MT or MD mode under VC (link to multi-thread dynamic links and static connection libraries). The second is to merge boost_threadmon.dll into the libboost_thread.lib library. "I have just learned Boost for 4 days, I am afraid that I am inevitable, please correct it. The version used in this article is 1.28.0 "
Boost multi-thread library includes two, one is boost_threadmon.dll, a dynamic connection library, another is libboost_thread.lib, a static link library. Why use two? It is mainly to clear the data in TLS. When boost_threadmon.dll is loaded, the dynamic link library receives a message DLL_PROCESS_ATTACH, which is assigned a TLS and key code segment criticalsection. When the user program creates a thread, receive DLL_THREAD_ATTACH, and the TLS data of the thread is cleared. When the primary program exits, receive DLL_PROCESS_DETACH, and the dynamic link library clears the main thread TLS data.
Boost Management TLS is as follows: When the user sets TLS data, Boost places the data pointer and a cleanup function into a Cleanup_info structure and set it into the MAP of Cleanup_Handler. Cleanup_info The first member is the cleaning function pointer, the second member is the data pointer itself. Cleanup_Handler is a TLS index as Key, which corresponds to a Cleanup_Handlers pointer to a TLS index inside the DATA item, and the data in the pointer is the TLS assigned by the user and the corresponding data pointer and the release function. Boost uses the on_thread_exit (& Cleanup) function to install Cleanup_Handlers on the TLS index in Boost_Threadmon.dll.
The structure in the TSS.CPP involved is as follows:
Typedef std :: pair
TypedEf std :: map
The structure in threadmon.cpp involved is as follows:
Typedef void (__cdecl * handler) (VOID);
TypedEf std :: list
Typedef std :: set
The above may not be clear at all, but I don't want to play too much word, and directly modify it directly:
1. Thread.hpp file starts modified to:
#ifndef boost_thread_wek070601_hpp
#define boost_thread_wek070601_hpp
/ *
· Monitor Library: Using / MT BOOST_MON_LIBMT.LIB THREAD: BOOST_THREAD_LIBMT.LIB
· MONITOR library: Using / MTD boost_mon_libmtd.lib thread: boost_thread_libmtd.lib · Monitor library: Using / MD boost_mon_libmd.lib thread: boost_thread_libmd.lib
· MONITOR library: Using / MDD boost_mon_libmdd.lib thread: boost_thread_libmdd.lib
· Monitor-Thread combined library: Using / MT BOOST_THREAD_MON_LIBMT.LIB
· Monitor-Thread combined library: Using / MTD boost_thread_mon_libmtd.lib
· Monitor-Thread combined library: use / md boost_thread_mon_libmd.lib
· Monitor-thread combined library: Using / MDD boost_thread_mon_libmdd.lib
* /
#ifdef Win32
#ifndef _mt
#Error error: Must Compiled with Multithread DLL!
#ENDIF
#define boost_haas_threads
#ifndef boost_threadmon_as_dll
#ifdef _Debug
#ifdef _dll
#pragma comment (Lib, "Boost_thread_MON_LIBMDD.LIB")
#ELSE
#pragma comment (Lib, "Boost_thread_MON_LIBMTD.LIB")
#ENDIF
#ELSE
#ifdef _dll
#pragma comment (LIB, "Boost_thread_MON_LIBMD.LIB")
#ELSE
#pragma comment (Lib, "Boost_thread_MON_LIBMT.LIB")
#ENDIF
#ENDIF
#ELSE
#ifdef _Debug
#ifdef _dll
#pragma comment (Lib, "Boost_MON_LIBMDD.LIB")
#pragma comment (Lib, "Boost_thread_Libmdd.lib")
#ELSE
#pragma comment (Lib, "Boost_MON_LIBMTD.LIB")
#pragma comment (Lib, "Boost_thread_Libmtd.lib")
#ENDIF
#ELSE
#ifdef _dll
#pragma comment (Lib, "Boost_MON_LIBMD.LIB")
#pragma comment (Lib, "Boost_thread_Libmd.lib")
#ELSE
#pragma comment (Lib, "Boost_MON_LIBMT.LIB")
#pragma comment (Lib, "Boost_thread_Libmt.lib")
#ENDIF
#ENDIF
#ENDIF
#ENDIF
//
#include
#ifndef boost_haas_threads
# Error Thread Support Is Unavailable!
#ENDIF
2. Threadmon.hpp file is modified to:
///
//2002.5.30 Modifications. #ifdef boost_threadmon_as_dll
#ifdef boost_threadmon_exports
#define boost_threadmon_api __declspec (dllexport)
#ELSE
#define boost_threadmon_api __declspec (dllimport)
#ENDIF
#ELSE
#define boost_threadmon_API
#ENDIF
EXTERN "C" boost_threadmon_api int on_thread_exit (void (__cdecl * func));
Extern "C" boost_threadmon_api void on_thread_detach ();
3. Threadmon.cpp file modified to:
///
// this file has been modified!
// threadmon.cpp: defines the entry point for the dll application.
//
//2002.5.30.Modified.
#ifdef boost_threadmon_as_dll
#define boost_threadmon_exports
#ELSE
#include
# ENDIF / / BOOST_THREADMON_AS_DLL
#include "threadmon.hpp"
#ifdef boost_haas_winthreads
#define Win32_Lean_and_mean // Exclude Rarely-useed Stuff from Windows Headers
#include
#ifdef boost_msvc
# Pragma Warning (DISABLE: 4786)
#ENDIF
#include
#include
#include
Typedef void (__cdecl * handler) (VOID);
TypedEf std :: list
Typedef std :: set
Namespace
{
Critical_section CS;
DWord Key;
Registered_handlers registry;
}
Void on_process_attach ()
{
InitializationCriticalSection (& CS);
Key = tlsalloc ();
}
Void on_process_detach ()
{
ON_THREAD_DETACH ();
// deStroy Any Remaining Exit Handlers. Above We Assumed There'd Only Be The Main
// Thread Left, But to Insure We don't get MEMORY Leaks We Won't make That Assumption
// here.
ENTERCRITICALSECTION (& CS);
For (registered_handlers :: itrator it = registry.begin ();
It! = registry.end (); IT)
{
#ifndef boost_threadmon_as_dllfor (exit_handlers :: itrator p = (* it) -> begin (); p! = (* it) -> end (); p)
(* p) ();
#ENDIF
Delete (* it);
}
LeavecriticalSection (& CS);
DeletecriticalSection (& CS);
Tlsfree (key);
}
#ifdef boost_threadmon_as_dll
#if Defined (__ borlandc__)
#define dllmain dllenTryPoint
#ENDIF
EXTERN "C"
Bool WinApi Dllmain (Handle Module, DWord Reason, LPVOID)
{
Switch (REASON)
{
Case DLL_Process_attach:
ON_PROCESS_ATTACH ();
Break;
Case DLL_THREAD_ATTACH:
Break;
Case DLL_THREAD_DETACH:
ON_THREAD_DETACH ();
Break;
Case DLL_PROCESS_DETACH:
ON_PROCESS_DETACH ();
Break;
}
Return True;
}
# else // boost_threadmon_as_dll
Boost :: OnCE_FLAG ONCE = boost_once_init;
Class Process_ENVELOPE
{
Process_ENVELOPE ()
{
Boost :: Call_once (& On_Process_attach, ONCE);
}
PUBLIC:
~ Process_envelope () {on_process_detach ();
Static process_ENVELOPE * GET ()
{
Static process_ENVELOPE P;
Return & P;
}
}
#ndif //! boost_threadmon_as_dll
Void on_thread_detach ()
{
// Call The Thread's Exit Handlers.
#ifndef boost_threadmon_as_dll
Process_ENVELOPE :: get ();
#ENDIF
EXIT_HANDLERS * HANDLERS = static_cast
IF (Handlers)
{
For (exit_handlers :: itrator it = handlers-> begin (); it! = handlers-> end (); IT)
(* IT) ();
// Remove The Exit Handler List from The Registered Lists and The Destroy IT.
ENTERCRITICALSECTION (& CS);
Registry.ed (Handlers);
LeavecriticalSection (& CS);
DELETE HANDLERS;
}
}
INT ON_THREAD_EXIT (Void) (VOID))
{
#ifndef boost_threadmon_as_dll
Process_ENVELOPE :: get ();
#ENDIF
// get the exit handlers for the capital thread, Creating and registering
// One if it doesn't exist.
EXIT_HANDLERS * HANDLERS = static_cast
IF (! handlers)
{
Try
{
Handlers = new exit_handlers;
// Handle "Broken" IMPLEMENTATION OF OPERATOR New That Don't throw.
IF (! handlers)
Return -1;
}
Catch (...)
{
Return -1;
}
// attempt to set a tls value for the new handlers.
IF (! TLSSetValue (Key, Handlers))
{
DELETE HANDLERS;
Return -1;
}
// Attempt to Register this New Handler So That Memory Can Be Properly
// cleaned Up.
Try
{
ENTERCRITICALSECTION (& CS);
Registry.insert (Handlers);
LeavecriticalSection (& CS);
}
Catch (...)
{
LeavecriticalSection (& CS);
DELETE HANDLERS;
Return -1;
}
}
// attempt to add the handler to the list of exit handlers. If it's been previously
// Added Just Report Success and exit.
Try
{
Handlers-> Push_Front (FUNC);
}
Catch (...)
{
Return -1;
}
Return 0;
}
#ENDIF / / BOOST_HAS_WINTHREADS
4. Thread.cpp file modified to:
After the #include "timeconv.inl":
//2002.5.30; Modify
#ifdef Win32
#ifndef boost_threadmon_as_dll
#include "threadmon.hpp"
#ENDIF
#ENDIF
The tail of the THREAD_PROXY (VOID * PARAM) method is:
//2002.5.30; Modify
#ifdef Win32
#ifndef boost_threadmon_as_dll
ON_THREAD_DETACH ();
#ENDIF
#ENDIF
5. Insert all files in the