id summary reporter owner description type status milestone component version severity resolution keywords cc 7152 Interprocess 1.50 windows_bootstamp fails when COM already initialized in multithreaded Charles Savoie Ion Gaztañaga "The windows_bootstamp class fails to obtain a bootstamp if the current thread has already been COM-initialized in MULTITHREADED mode. This is due to (detail/win32api.hpp) calling CoInitialize(0) and failing to test for RPC_E_CHANGED_MODE. This causes opening of a shared_memory_object to fail due to a file path mismatch if one process' thread was not running in a multithreaded COM thread. If both processing were running multithreaded, the problem is masked -- the bootstamp returns an empty string and thus the shared memory file path is the same in both cases. A slight modification to the example program in the shared memory documentation (http://www.boost.org/doc/libs/1_50_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.sharedmemory) displays the problem: {{{ #!div style=""font-size: 80%"" {{{#!c++ #include #include #include #include #include #include struct co_uninitializer{ ~co_uninitializer() { CoUninitialize(); } }; int main(int argc, char *argv[]) { using namespace boost::interprocess; if(argc == 1){ //Parent process //Remove shared memory on construction and destruction struct shm_remove { shm_remove() { shared_memory_object::remove(""MySharedMemory""); } ~shm_remove(){ shared_memory_object::remove(""MySharedMemory""); } } remover; //Create a shared memory object. shared_memory_object shm (create_only, ""MySharedMemory"", read_write); //Set size shm.truncate(1000); //Map the whole shared memory in this process mapped_region region(shm, read_write); //Write all the memory to 1 std::memset(region.get_address(), 1, region.get_size()); //Launch child process std::string s(argv[0]); s = ""\"""" + s + ""\"""" + "" child ""; if(0 != std::system( s.c_str() ) ) return 1; } else{ CoInitializeEx(NULL, COINIT_MULTITHREADED ); //*********** co_uninitializer co_uninit; //*********** //Open already created shared memory object. shared_memory_object shm (open_only, ""MySharedMemory"", read_only); //Map the whole shared memory in this process mapped_region region(shm, read_only); //Check that memory was initialized to 1 char *mem = static_cast(region.get_address()); for(std::size_t i = 0; i < region.get_size(); ++i) if(*mem++ != 1) return 1; //Error checking memory } return 0; } }}} }}} The problem seems to be fixed by modifying get_wmi_class_attribute() in interprocess/detail/win32_api.hpp in the following way: {{{ #!div style=""font-size: 80%"" {{{#!c++ // ... const signed long RPC_E_CHANGED_MODE_BIPC = 0x80010106L; // ... inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_class, const wchar_t *wmi_class_var) { //See example http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx long co_init_ret = CoInitialize(0); if(co_init_ret != S_OK_BIPC && co_init_ret != S_FALSE_BIPC && co_init_ret != RPC_E_CHANGED_MODE_BIPC ) return false; // Uninitialize COM at function exit if not already initialized with different threading model std::auto_ptr co_initialize_end(( co_init_ret != RPC_E_CHANGED_MODE_BIPC ) ? new co_uninitializer : (co_uninitializer*)0 ); bool bRet = false; // ... }}}" Bugs closed To Be Determined interprocess Boost 1.50.0 Problem fixed windows bootstamp tmpfile tempfile shared memory shm