I'll add this to my to-do list. What would be your proposal? Should we
take in care also permission or mode (r/w) issues?
Currently I just need to know if the named objects exist in shared memory.
Well after having looked through the documentation and trying to get to know
the API a little lately. I would like to see some things.
1) Provide the use of std::system to launching processes maybe boost::inter
process::system(...) to allow spawning a process in a non blocking fashion.
as the following code in Windows allows (on Linux I think & would work after
the command using std::system though I have not tried this):
Currently what I am using on windows:
<code>
std::string path = getenv( "PATH" );
path = "PATH=" + path;
std::cout << "The current path is " << path << std::endl;
char *pValue;
size_t len;
errno_t err = _dupenv_s( &pValue, &len, "path" );
path = pValue;
std::cout << "The current path is " << path << std::endl;
mexPrintf( "The current path is %s", path.c_str() );
if(
0 ==
_spawnlp(
_P_DETACH,
"cmd", "cmd", "/K", "dsa4DTool.exe",
NULL)
)
{
printf( "dsa4DTool lanuched sucessfully\n" );
}
else
{
printf( "dsa4DTool failed to launch\n" );
}
</code>
2) As discussed provide ability to search for every named shared memory
variable. Currently I was having problems with the code where I try to
search for a shared memory variable that may have, but not necessarily have,
already been created by the process running the code in the previous run of
the process. This may be working, but I have not had success with it yet.
The first call :
res = segment.find
("show_volume_data_dimensions");
seems to block indefinitely in the code if the named object does not exist
yet. The logic was open the shared memory region using open and check if
the show_volume_data_dimensions_t object exists (the process has run one
time before) if not created it (this is the first time the process is
running).
It appears that using CreateFileMapping will set ERROR_ALREADY_EXISTS which
can be determined from GetLastError after the call (attempt to open the
shared memory region) to CreateFileMapping. Then if the file did not exist
and was created CloseHandle could be called. Of course then comes the
problem of inter-process race conditions. It does not appear that
FindFirstFileEx supports named files. Though this still does not preclude
interprocess from not throwing a exceptoin as boost.filesystem filebuf.open
does not seem to throw on failed open and fb.is_open() can be called along
with fb::exists(p) syntax from:
http://live.boost.org/doc/libs/1_41_0/libs/filesystem/test/fstream_test.cpp
So I guess my proposal would be to mirror the likes of boost.filesystem
<code>
try{
//shared_memory_object::remove("show_volume_data");
managed_shared_memory segment
//create segment name segment size
(open_or_create, "show_volume_data",
sizeof(show_volume_data_dimensions_t) );
show_volume_data_dimensions_t * vol_dimensions = NULL;
std::pair res;
std::cout << "attempting to open named shared memory region:
show_volume_data_dimensions" << std::endl;
res = segment.find
("show_volume_data_dimensions");
if( res.second < 1 )
{
try
{
std::cout << "shared memory region was not found" <<
std::endl;
std::cout << "attempting to create shared memory region"
<< std::endl;
vol_dimensions =
segment.construct
("show_volume_data_dimensions") //name of the
object
()/*(x_dim, y_dim, z_dim)*/; //ctor first
argument
}
catch( ... )
{
}
}
else
{
vol_dimensions = res.first;
}
std::cout << "setting volume data\n";
vol_dimensions->x_dim = x_dim;
vol_dimensions->y_dim = y_dim;
vol_dimensions->z_dim = z_dim;
std::cout << str( boost::format(
"dimensions of data are:\n"
"x_dim = %d, y_dim = %d, z_dim = %d\n" ) %
vol_dimensions->x_dim %
vol_dimensions->y_dim %
vol_dimensions->z_dim );
}
catch( boost::interprocess::interprocess_exception e )
{
std::cout << "exception: " << e.what();
shared_memory_object::remove("show_volume_data");
throw;
}
catch( ... )
{
std::cout << "unknown exception occured\n";
shared_memory_object::remove("show_volume_data");
throw;
}
// shared_memory_object::remove("show_volume_data");
</code>