Subject: [Boost-bugs] [Boost C++ Libraries] #7152: Interprocess 1.50 windows_bootstamp fails when COM already initialized in multithreaded
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-07-19 16:54:17
#7152: Interprocess 1.50 windows_bootstamp fails when COM already initialized in
multithreaded
------------------------------------------------------------------+---------
Reporter: Charles Savoie <boost@â¦> | Owner: igaztanaga
Type: Bugs | Status: new
Milestone: To Be Determined | Component: interprocess
Version: Boost 1.50.0 | Severity: Problem
Keywords: windows bootstamp tmpfile tempfile shared memory shm |
------------------------------------------------------------------+---------
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 <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <cstring>
#include <cstdlib>
#include <string>
#include <atlbase.h>
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<char*>(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_uninitializer> co_initialize_end(( co_init_ret !=
RPC_E_CHANGED_MODE_BIPC ) ? new co_uninitializer : (co_uninitializer*)0 );
bool bRet = false;
// ...
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7152> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:10 UTC