Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71904 - in trunk/boost/interprocess: containers/container containers/container/detail detail
From: igaztanaga_at_[hidden]
Date: 2011-05-12 16:26:49


Author: igaztanaga
Date: 2011-05-12 16:26:48 EDT (Thu, 12 May 2011)
New Revision: 71904
URL: http://svn.boost.org/trac/boost/changeset/71904

Log:
Added static assert to assure allocator value type is the same as std::pair<Const key, value>
Cached DLL function addresses to speed up some operations
Text files modified:
   trunk/boost/interprocess/containers/container/detail/tree.hpp | 1
   trunk/boost/interprocess/containers/container/map.hpp | 9 +
   trunk/boost/interprocess/detail/win32_api.hpp | 184 ++++++++++++++++++++++++---------------
   3 files changed, 124 insertions(+), 70 deletions(-)

Modified: trunk/boost/interprocess/containers/container/detail/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/tree.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/tree.hpp 2011-05-12 16:26:48 EDT (Thu, 12 May 2011)
@@ -26,6 +26,7 @@
 #include INCLUDE_BOOST_CONTAINER_DETAIL_NODE_ALLOC_HOLDER_HPP
 #include INCLUDE_BOOST_CONTAINER_DETAIL_DESTROYERS_HPP
 #include INCLUDE_BOOST_CONTAINER_DETAIL_PAIR_HPP
+#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
 #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
 #include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
 #endif

Modified: trunk/boost/interprocess/containers/container/map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/map.hpp (original)
+++ trunk/boost/interprocess/containers/container/map.hpp 2011-05-12 16:26:48 EDT (Thu, 12 May 2011)
@@ -61,7 +61,9 @@
 #include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
 #include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
 #include INCLUDE_BOOST_CONTAINER_DETAIL_PAIR_HPP
+#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
 #include <boost/move/move.hpp>
+#include <boost/static_assert.hpp>
 
 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
@@ -106,6 +108,10 @@
                            Pred,
                            Alloc> tree_t;
    tree_t m_tree; // red-black tree representing map
+
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename Alloc::value_type>::value));
+
    /// @endcond
 
    public:
@@ -761,6 +767,9 @@
    tree_t m_tree; // red-black tree representing map
    /// @endcond
 
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename Alloc::value_type>::value));
+
    public:
 
    // typedefs:

Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp (original)
+++ trunk/boost/interprocess/detail/win32_api.hpp 2011-05-12 16:26:48 EDT (Thu, 12 May 2011)
@@ -15,6 +15,7 @@
 #include <boost/interprocess/detail/workaround.hpp>
 #include <cstddef>
 #include <cstring>
+#include <cassert>
 #include <string>
 #include <vector>
 #include <memory>
@@ -1145,29 +1146,62 @@
    ucStr->MaximumLength = bufSize;
 }
 
+//A class that locates and caches loaded DLL function addresses.
 template<int Dummy>
 struct function_address_holder
 {
- enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, FunctionAddressNum };
+ enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NumFunction };
+ enum { NtDll_dll, NumModule };
 
    private:
- static void *FunctionAddresses[FunctionAddressNum];
- static volatile long FunctionStates[FunctionAddressNum];
+ static void *FunctionAddresses[NumFunction];
+ static volatile long FunctionStates[NumFunction];
+ static void *ModuleAddresses[NumModule];
+ static volatile long ModuleStates[NumModule];
+
+ static void *get_module_from_id(unsigned int id)
+ {
+ assert(id < (unsigned int)NumModule);
+ const char *module[] = { "ntdll.dll" };
+ bool compile_check[sizeof(module)/sizeof(module[0]) == NumModule];
+ (void)compile_check;
+ return get_module_handle(module[id]);
+ }
+
+ static void *get_module(const unsigned int id)
+ {
+ assert(id < (unsigned int)NumModule);
+ while(ModuleStates[id] < 2u){
+ if(interlocked_compare_exchange(&ModuleStates[id], 1, 0) == 0){
+ ModuleAddresses[id] = get_module_from_id(id);
+ interlocked_increment(&ModuleStates[id]);
+ break;
+ }
+ else{
+ sched_yield();
+ }
+ }
+ return ModuleAddresses[id];
+ }
 
    static void *get_address_from_dll(const unsigned int id)
    {
- const char *module[] = { "ntdll.dll", "ntdll.dll", "ntdll.dll" };
+ assert(id < (unsigned int)NumFunction);
       const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject" };
- return get_proc_address(get_module_handle(module[id]), function[id]);
+ bool compile_check[sizeof(function)/sizeof(function[0]) == NumFunction];
+ (void)compile_check;
+ return get_proc_address(get_module(NtDll_dll), function[id]);
    }
 
    public:
    static void *get(const unsigned int id)
    {
+ assert(id < (unsigned int)NumFunction);
       while(FunctionStates[id] < 2u){
          if(interlocked_compare_exchange(&FunctionStates[id], 1, 0) == 0){
             FunctionAddresses[id] = get_address_from_dll(id);
             interlocked_increment(&FunctionStates[id]);
+ break;
          }
          else{
             sched_yield();
@@ -1178,10 +1212,17 @@
 };
 
 template<int Dummy>
-void *function_address_holder<Dummy>::FunctionAddresses[FunctionAddressNum];
+void *function_address_holder<Dummy>::FunctionAddresses[function_address_holder<Dummy>::NumFunction];
+
+template<int Dummy>
+volatile long function_address_holder<Dummy>::FunctionStates[function_address_holder<Dummy>::NumFunction];
+
+template<int Dummy>
+void *function_address_holder<Dummy>::ModuleAddresses[function_address_holder<Dummy>::NumModule];
 
 template<int Dummy>
-volatile long function_address_holder<Dummy>::FunctionStates[FunctionAddressNum];
+volatile long function_address_holder<Dummy>::ModuleStates[function_address_holder<Dummy>::NumModule];
+
 
 struct dll_func
    : public function_address_holder<0>
@@ -1334,80 +1375,83 @@
 
 inline bool unlink_file(const char *filename)
 {
- try{
- NtSetInformationFile_t pNtSetInformationFile =
- //(NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
- (NtSetInformationFile_t)dll_func::get(dll_func::NtSetInformationFile);
- if(!pNtSetInformationFile){
- return false;
- }
+ if(!delete_file(filename)){
+ try{
+ NtSetInformationFile_t pNtSetInformationFile =
+ //(NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
+ (NtSetInformationFile_t)dll_func::get(dll_func::NtSetInformationFile);
+ if(!pNtSetInformationFile){
+ return false;
+ }
 
- NtQueryObject_t pNtQueryObject =
- //(NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
- (NtQueryObject_t)dll_func::get(dll_func::NtQueryObject);
-
- //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
- void *fh = create_file(filename, generic_read | delete_access, open_existing,
- file_flag_backup_semantics | file_flag_delete_on_close, 0);
- if(fh == invalid_handle_value){
- return false;
- }
+ NtQueryObject_t pNtQueryObject =
+ //(NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
+ (NtQueryObject_t)dll_func::get(dll_func::NtQueryObject);
+
+ //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
+ void *fh = create_file(filename, generic_read | delete_access, open_existing,
+ file_flag_backup_semantics | file_flag_delete_on_close, 0);
+ if(fh == invalid_handle_value){
+ return false;
+ }
 
- handle_closer h_closer(fh);
+ handle_closer h_closer(fh);
 
- std::auto_ptr<ntquery_mem_t> pmem(new ntquery_mem_t);
- file_rename_information_t *pfri = (file_rename_information_t*)&pmem->ren.info;
- const std::size_t RenMaxNumChars =
- ((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
-
- //Obtain file name
- unsigned long size;
- if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(ntquery_mem_t), &size)){
- return false;
- }
+ std::auto_ptr<ntquery_mem_t> pmem(new ntquery_mem_t);
+ file_rename_information_t *pfri = &pmem->ren.info;
+ const std::size_t RenMaxNumChars =
+ ((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
+
+ //Obtain file name
+ unsigned long size;
+ if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(ntquery_mem_t), &size)){
+ return false;
+ }
 
- //Copy filename to the rename member
- std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
- std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
-
- //Second step: obtain the complete native-nt filename
- //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){
- //return 0;
- //}
+ //Copy filename to the rename member
+ std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
+ std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
+
+ //Second step: obtain the complete native-nt filename
+ //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){
+ //return 0;
+ //}
 
- //Add trailing mark
- if((RenMaxNumChars-filename_string_length) < (SystemTimeOfDayInfoLength*2)){
- return false;
- }
+ //Add trailing mark
+ if((RenMaxNumChars-filename_string_length) < (SystemTimeOfDayInfoLength*2)){
+ return false;
+ }
 
- //Search '\\' character to replace it
- for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
- if(pmem->ren.info.FileName[--i] == L'\\')
- break;
- }
+ //Search '\\' character to replace it
+ for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
+ if(pmem->ren.info.FileName[--i] == L'\\')
+ break;
+ }
 
- //Add random number
- std::size_t s = RenMaxNumChars - filename_string_length;
- if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
- return false;
- }
- filename_string_length += s;
+ //Add random number
+ std::size_t s = RenMaxNumChars - filename_string_length;
+ if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
+ return false;
+ }
+ filename_string_length += s;
 
- //Fill rename information (FileNameLength is in bytes)
- pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
- pfri->Replace = 1;
- pfri->RootDir = 0;
-
- //Final step: change the name of the in-use file:
- io_status_block_t io;
- if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(ntquery_mem_t::ren_t), file_rename_information)){
+ //Fill rename information (FileNameLength is in bytes)
+ pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
+ pfri->Replace = 1;
+ pfri->RootDir = 0;
+
+ //Final step: change the name of the in-use file:
+ io_status_block_t io;
+ if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(ntquery_mem_t::ren_t), file_rename_information)){
+ return false;
+ }
+ return true;
+ }
+ catch(...){
          return false;
       }
- return true;
- }
- catch(...){
- return false;
    }
+ return true;
 }
 
 struct reg_closer


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk