mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Fixes for Boost 1.45
[SVN r65013]
This commit is contained in:
@@ -44,6 +44,7 @@ boostbook standalone
|
||||
interprocess
|
||||
:
|
||||
<xsl:param>boost.root=../../../..
|
||||
<xsl:param>boost.libraries=../../../../libs/libraries.htm
|
||||
<xsl:param>toc.max.depth=1
|
||||
<xsl:param>toc.section.depth=2
|
||||
<xsl:param>chunk.first.sections=1
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
[library Boost.Interprocess
|
||||
[quickbook 1.4]
|
||||
[authors [Gaztanaga, Ion]]
|
||||
[copyright 2005- 2008 Ion Gaztanaga]
|
||||
[copyright 2005- 2010 Ion Gaztanaga]
|
||||
[id interprocess]
|
||||
[dirname interprocess]
|
||||
[purpose Interprocess communication utilities]
|
||||
@@ -311,6 +311,33 @@ allocated by the system for use by the process for the named resource.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:permissions Permissions]
|
||||
|
||||
Named resources offered by [*Boost.Interprocess] must cope with platform-dependant
|
||||
permission issues also present when creating files. If a programmer wants to
|
||||
shared shared memory, memory mapped files or named synchronization mechanisms
|
||||
(mutexes, semaphores, etc...) between users, it's necessary to specify
|
||||
those permissions. Sadly, traditional UNIX and Windows permissions are very
|
||||
different and [*Boost.Interprocess] does not try to standardize permissions,
|
||||
but does not ignore them.
|
||||
|
||||
All named resource creation functions take an optional
|
||||
[classref boost::interprocess::permissions permissions object] that can be
|
||||
configured with platform-dependant permissions.
|
||||
|
||||
Since each mechanism can be emulated through diferent mechanisms
|
||||
(a semaphore might be implement using mapped files or native semaphores)
|
||||
permissions types could vary when the implementation of a named resource
|
||||
changes (eg.: in Windows mutexes require `synchronize permissions`, but
|
||||
that's not the case of files).
|
||||
To avoid this, [*Boost.Interprocess] relies on file-like permissions,
|
||||
requiring file read-write-delete permissions to open named synchronization mechanisms
|
||||
(mutex, semaphores, etc.) and appropiate read or read-write-delete permissions for
|
||||
shared memory. This approach has two advantages: it's similar to the UNIX philosophy
|
||||
and the programmer does not need to know how the named resource is implemented.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:sharedmemorybetweenprocesses Sharing memory between processes]
|
||||
@@ -609,6 +636,16 @@ which is the size of that memory. This limitation is imposed by the Windows API
|
||||
the user must somehow transmit the size of the segment to processes opening the
|
||||
segment.
|
||||
|
||||
Sharing memory between services and user applications is also different. To share memory
|
||||
between services and user applications the name of the shared memory must start with the
|
||||
global namespace prefix `"Global\\"`. This global namespace enables processes on multiple
|
||||
client sessions to communicate with a service application. The server component can create
|
||||
the shared memory in the global namespace. Then a client session can use the "Global\" prefix
|
||||
to open that memory.
|
||||
|
||||
The creation of a shared memory object in the global namespace from a session other than
|
||||
session zero is a privileged operation.
|
||||
|
||||
Let's repeat the same example presented for the portable shared memory object:
|
||||
A server process creates a
|
||||
shared memory object, maps it and initializes all the bytes to a value. After that,
|
||||
@@ -757,7 +794,8 @@ inmedially visible to other processes. However, the file contents on disk are
|
||||
not updated immediately, since that would hurt performance (writing to disk
|
||||
is several times slower than writing to memory). If the user wants to make sure
|
||||
that file's contents have been updated, it can flush a range from the view to disk.
|
||||
When the function returns, the data should have been written to disk:
|
||||
When the function returns, the flushing process has startd but there is not guarantee that
|
||||
all data has been written to disk:
|
||||
|
||||
[c++]
|
||||
|
||||
@@ -3128,6 +3166,10 @@ lifetime issues as the windows shared memory: when the last process attached to
|
||||
windows shared memory is detached from the memory (or ends/crashes) the memory is
|
||||
destroyed. So there is no persistence support for windows shared memory.
|
||||
|
||||
To communicate between system services and user applications using `managed_windows_shared_memory`,
|
||||
please read the explanations given in chapter
|
||||
[interprocess.sharedmemorybetweenprocesses.sharedmemory.windows_shared_memory Native windows shared memory]
|
||||
|
||||
[endsect]
|
||||
|
||||
For more information about managed shared memory capabilities, see
|
||||
@@ -5078,6 +5120,13 @@ Here is an example that shows how to put a multi index container in shared memor
|
||||
|
||||
[endsect]
|
||||
|
||||
Programmers can place [*Boost.CircularBuffer] containers in sharecd memory provided
|
||||
they disable debugging facilities with defines `BOOST_CB_DISABLE_DEBUG` or the more
|
||||
general `NDEBUG`. The reason is that those debugging facilities are only compatible
|
||||
with raw pointers.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:memory_algorithms Memory allocation algorithms]
|
||||
@@ -5192,9 +5241,6 @@ For allocations bigger than 8 bytes the memory overhead is exactly the same.
|
||||
This is the default allocation algorithm in [*Boost.Interprocess] managed memory
|
||||
segments.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
@@ -6504,32 +6550,46 @@ thank them:
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:thanks_to_license_notes License notes]
|
||||
|
||||
[*Boost.Interprocess] STL containers are based on the SGI STL library implementation:
|
||||
|
||||
Copyright (c) 1996,1997 Silicon Graphics Computer Systems, Inc. Permission to use,
|
||||
copy, modify, distribute and sell this software and its documentation for any
|
||||
purpose is hereby granted without fee, provided that the above copyright notice
|
||||
appear in all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation. Silicon Graphics makes no representations
|
||||
about the suitability of this software for any purpose. It is provided "as is"
|
||||
without express or implied warranty.
|
||||
|
||||
Copyright (c) 1994 Hewlett-Packard Company Permission to use, copy, modify,
|
||||
distribute and sell this software and its documentation for any purpose is hereby
|
||||
granted without fee, provided that the above copyright notice appear in all copies
|
||||
and that both that copyright notice and this permission notice appear in supporting
|
||||
documentation. Hewlett-Packard Company makes no representations about the suitability
|
||||
of this software for any purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_45_00 Boost 1.45 Release]
|
||||
|
||||
* Fixed bugs
|
||||
[@https://svn.boost.org/trac/boost/ticket/3439 #3439],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3448 #3448],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3582 #3582],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3682 #3682],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3829 #3829],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3846 #3846],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3947 #3947],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3950 #3950],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3951 #3951],
|
||||
[@https://svn.boost.org/trac/boost/ticket/3985 #3985],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4010 #4010],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4019 #4019],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4039 #4039],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4218 #4218],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4230 #4230],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4230 #4352],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4230 #4352],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4516 #4516],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4524 #4524],
|
||||
[@https://svn.boost.org/trac/boost/ticket/4557 #4557].
|
||||
|
||||
* Added support for standard rvalue reference move semantics
|
||||
(tested on GCC 4.5 and VC10).
|
||||
|
||||
* Permissions can be detailed for interprocess named resources.
|
||||
|
||||
* `mapped_region::flush` initiates disk flushing but does not guarantee it's completed
|
||||
when returns, since it is not portable.
|
||||
|
||||
* FreeBSD and MacOS now use posix semaphores to implement named semaphores and mutex.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_41_00 Boost 1.41 Release]
|
||||
|
||||
* Support for POSIX shared memory in Mac OS.
|
||||
|
||||
@@ -36,6 +36,7 @@ rule test_all
|
||||
: # requirements
|
||||
<toolset>acc:<linkflags>-lrt
|
||||
<toolset>acc-pa_risc:<linkflags>-lrt
|
||||
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32"
|
||||
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
|
||||
] ;
|
||||
}
|
||||
|
||||
@@ -77,4 +77,3 @@ int main ()
|
||||
return 0;
|
||||
}
|
||||
//]
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
181
proj/to-do.txt
181
proj/to-do.txt
@@ -1,4 +1,46 @@
|
||||
-> add private_read_only to mapped_region to support MAP_PRIVATE plus PROT_READ
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
Platform conformance
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////
|
||||
FreeBSD
|
||||
//////////
|
||||
|
||||
Tested until FreeBSD 9
|
||||
|
||||
Shared memory: FreeBSD < 7 filesystem semantics
|
||||
|
||||
HISTORY
|
||||
The shm_open() and shm_unlink() functions first appeared in FreeBSD 4.3.
|
||||
The functions were reimplemented as system calls using shared memory
|
||||
objects directly rather than files in FreeBSD 7.0.
|
||||
|
||||
BUG: MAP_PRIVATE requires read-write access to shared memory object (mapped files work fine)
|
||||
|
||||
Named semaphore: _POSIX_SEMAPHORES not defined. Limited named semaphore support (short names)
|
||||
Process shared: _POSIX_THREAD_PROCESS_SHARED not defined
|
||||
|
||||
//////////
|
||||
Linux 2.6
|
||||
//////////
|
||||
|
||||
All Fine
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-> add contiguous_elements option to burst allocation
|
||||
|
||||
@@ -61,4 +103,139 @@
|
||||
|
||||
-> MacOS shm_open is non-conformant. Is there a way to know the size of a shared memory object?
|
||||
|
||||
-> swap() of multiallocaiton iterator is wrong. Try to reimplement it with slist
|
||||
-> swap() of multiallocaiton iterator is wrong. Try to reimplement it with slist
|
||||
|
||||
-> Could the mapped_file constructor allow a wchar_t filename on Windows?
|
||||
Or some cross-platform way to get Unicode support?
|
||||
|
||||
-> map::node_ptr p = m.create_node(my_special_cheap_key_value, mv1, mv2);
|
||||
//We would need to unconst-cast...
|
||||
const_cast<Key&>(p->first) = modify( p->second );
|
||||
m.insert( boost::move(p) );
|
||||
|
||||
-> I found some bug in the interprocess library. I use
|
||||
boost::interprocess::managed_mapped_file class and
|
||||
managed_mapped_file::shrink_to_fit() method to decrease the size of file
|
||||
on the disk. It works good but the thread hang up on shrink_to_fit() call
|
||||
if the file exists already and it's size is zero. It makes me check the
|
||||
file existance and it's size before shrink_to_fit() call.
|
||||
Thank you!
|
||||
|
||||
-> Ticket URL: <https://svn.boost.org/trac/boost/ticket/3375>
|
||||
|
||||
->Robust mutex emulation:
|
||||
|
||||
Two new fields:
|
||||
- owner
|
||||
- state
|
||||
|
||||
Use intermodule singleton to store the lock file name
|
||||
|
||||
LOCK
|
||||
if (broken_id){
|
||||
throw exception;
|
||||
}
|
||||
|
||||
lock_own_unique_file();
|
||||
|
||||
while(1){
|
||||
if (try_lock_mtx){
|
||||
write unique_id
|
||||
}
|
||||
else{
|
||||
sleep();
|
||||
++tries;
|
||||
if(tries > 100)
|
||||
if(!robust_check()){
|
||||
tries = 0;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNLOCK
|
||||
if (fixing_mode){
|
||||
write_broken_id
|
||||
}
|
||||
else{
|
||||
write invalid_id
|
||||
}
|
||||
|
||||
unlock_mtx
|
||||
|
||||
ROBUST_CHECK
|
||||
|
||||
if(check_if_owner_dead_and_take_ownership_atomically()){
|
||||
return false;
|
||||
}
|
||||
write fixing_id
|
||||
|
||||
CHECK_IF_OWNER_DEAD_AND_TAKE_OWNERSHIP_ATOMICALLY
|
||||
|
||||
do{
|
||||
old_owner = read_owner_atomically()
|
||||
if(check_owner_unique_resource_is_dead(old_owner){
|
||||
return true;
|
||||
}
|
||||
}while(cas(old_owner, cur_owner) == old_owner);
|
||||
return false;
|
||||
|
||||
CHECK_OWNER_UNIQUE_RESOURCE_IS_DEAD(owner)
|
||||
|
||||
file = file_to_owner(owner);
|
||||
if(file_exists(file)){
|
||||
if(try_lock(file)){
|
||||
write_owner_atomically();
|
||||
remove(file);
|
||||
unlock(file)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
LOCK_OWN_UNIQUE_FILE
|
||||
class MyRobustMutexLockFile
|
||||
{
|
||||
int fd;
|
||||
};
|
||||
|
||||
MyRobustMutexLockFile()
|
||||
{
|
||||
//loop create_and_lock because another process
|
||||
//can lock and erase it
|
||||
|
||||
//better create, lock and rename?
|
||||
fd = create_file(lockfilename);
|
||||
while(1){
|
||||
lock_file(fd);
|
||||
int fd2 = create_exclusive(lockfilename);
|
||||
if(fd2){
|
||||
close(fd);
|
||||
fd = fd2;
|
||||
continue;
|
||||
}
|
||||
else if(already_exist_error){ //must already exist
|
||||
break;
|
||||
}
|
||||
else{
|
||||
close(fd);
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~MyRobustMutexLockFile()
|
||||
{
|
||||
close(fd);
|
||||
//No race condition because
|
||||
//if any other thread tries to create the file
|
||||
//the shm has a lock so constructor/destructor is serialized
|
||||
unlink(lockfilename)
|
||||
}
|
||||
|
||||
detail::intermodule_singleton<MyRobustMutexLockFile>::get();
|
||||
|
||||
@@ -199,10 +199,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_index_test", "null_ind
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recursive_mutex_test", "recursive_mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A14}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "semaphore_test", "semaphore_test.vcproj", "{5CE28C83-48FE-1676-4FA7-B50D3A76A013}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
@@ -435,6 +431,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_condition_test", "nam
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intermodule_singleton_test", "intermodule_singleton_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robust_recursive_emulation_test", "robust_recursive_emulation_test.vcproj", "{58CCE183-4AFE-C4F5-6292-B25062C3A898}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robust_emulation_test", "robust_emulation_test.vcproj", "{58CCE183-4AFE-6092-C4F5-BA0D3A692628}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recursive_mutex_test", "recursive_mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A14}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -641,10 +653,6 @@ Global
|
||||
{0000058C-0000-0000-0000-000000000021}.Debug.Build.0 = Debug|Win32
|
||||
{0000058C-0000-0000-0000-000000000021}.Release.ActiveCfg = Release|Win32
|
||||
{0000058C-0000-0000-0000-000000000021}.Release.Build.0 = Release|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.ActiveCfg = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.Build.0 = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.ActiveCfg = Release|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.Build.0 = Release|Win32
|
||||
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.ActiveCfg = Debug|Win32
|
||||
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.Build.0 = Debug|Win32
|
||||
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.ActiveCfg = Release|Win32
|
||||
@@ -877,6 +885,22 @@ Global
|
||||
{58CC2563-6092-48FE-FAF7-BA046A792658}.Debug.Build.0 = Debug|Win32
|
||||
{58CC2563-6092-48FE-FAF7-BA046A792658}.Release.ActiveCfg = Release|Win32
|
||||
{58CC2563-6092-48FE-FAF7-BA046A792658}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-4AFE-C4F5-6292-B25062C3A898}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-4AFE-C4F5-6292-B25062C3A898}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-4AFE-C4F5-6292-B25062C3A898}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-4AFE-C4F5-6292-B25062C3A898}.Release.Build.0 = Release|Win32
|
||||
{58CCE183-4AFE-6092-C4F5-BA0D3A692628}.Debug.ActiveCfg = Debug|Win32
|
||||
{58CCE183-4AFE-6092-C4F5-BA0D3A692628}.Debug.Build.0 = Debug|Win32
|
||||
{58CCE183-4AFE-6092-C4F5-BA0D3A692628}.Release.ActiveCfg = Release|Win32
|
||||
{58CCE183-4AFE-6092-C4F5-BA0D3A692628}.Release.Build.0 = Release|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.ActiveCfg = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.Build.0 = Debug|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.ActiveCfg = Release|Win32
|
||||
{83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
||||
138
proj/vc7ide/intermodule_singleton_test.vcproj
Normal file
138
proj/vc7ide/intermodule_singleton_test.vcproj
Normal file
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="intermodule_singleton_test"
|
||||
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/intermodule_singleton_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/intermodule_singleton_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/intermodule_singleton_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/intermodule_singleton_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/intermodule_singleton_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\..\test\intermodule_singleton_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -265,23 +265,23 @@
|
||||
Name="emulation"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\interprocess_barrier.hpp">
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\barrier.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\interprocess_condition.hpp">
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\condition.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\interprocess_mutex.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\interprocess_recursive_mutex.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\interprocess_semaphore.hpp">
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\mutex.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\named_creation_functor.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\recursive_mutex.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\sync\emulation\semaphore.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
@@ -344,6 +344,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\mapped_region.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\permissions.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\segment_manager.hpp">
|
||||
</File>
|
||||
@@ -429,6 +432,9 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\ptime_wrk.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\robust_emulation.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\interprocess\detail\segment_manager_helper.hpp">
|
||||
</File>
|
||||
@@ -534,15 +540,9 @@
|
||||
<File
|
||||
RelativePath="..\..\test\expand_bwd_test_template.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\get_compiler_name.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\get_process_id_name.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\itestvalue.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\test\list_test.hpp">
|
||||
</File>
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
@@ -80,7 +81,7 @@
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_windows_shared_memory2"
|
||||
ProjectGUID="{5E1D6C83-31DE-4F6F-6132-87A9FB663041}"
|
||||
Name="robust_emulation_test"
|
||||
ProjectGUID="{58CCE183-4AFE-6092-C4F5-BA0D3A692628}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
@@ -13,7 +13,7 @@
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/doc_windows_shared_memory2"
|
||||
IntermediateDirectory="Debug/robust_emulation_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
@@ -35,11 +35,11 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_windows_shared_memory2_d.exe"
|
||||
OutputFile="$(OutDir)/robust_emulation_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_windows_shared_memoryB.pdb"
|
||||
ProgramDatabaseFile="$(OutDir)/robust_emulation_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
@@ -67,7 +67,7 @@
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_windows_shared_memory2"
|
||||
IntermediateDirectory="Release/robust_emulation_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
@@ -86,7 +86,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_windows_shared_memoryB.exe"
|
||||
OutputFile="$(OutDir)/robust_emulation_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
@@ -122,9 +122,9 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{437F71DF-CA9B-6637-0366-3E52D735BAFF}">
|
||||
UniqueIdentifier="{4C737CF1-6C7A-A035-4376-A1A2C75F232F}">
|
||||
<File
|
||||
RelativePath="..\..\example\comp_doc_windows_shared_memoryB.cpp">
|
||||
RelativePath="..\..\test\robust_emulation_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
133
proj/vc7ide/robust_recursive_emulation_test.vcproj
Normal file
133
proj/vc7ide/robust_recursive_emulation_test.vcproj
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="robust_recursive_emulation_test"
|
||||
ProjectGUID="{58CCE183-4AFE-C4F5-6292-B25062C3A898}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/robust_recursive_emulation_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/robust_recursive_emulation_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/robust_recursive_emulation_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/robust_recursive_emulation_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/robust_recursive_emulation_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{473AF9C1-6C7A-A035-4376-A3C75F20372F}">
|
||||
<File
|
||||
RelativePath="..\..\test\robust_recursive_emulation_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -72,6 +72,8 @@
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
|
||||
@@ -27,6 +27,7 @@ rule test_all
|
||||
: # requirements
|
||||
<toolset>acc:<linkflags>-lrt
|
||||
<toolset>acc-pa_risc:<linkflags>-lrt
|
||||
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32"
|
||||
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
|
||||
] ;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,9 @@ int main ()
|
||||
//Fill vector at the beginning until there is no more memory
|
||||
MyVect myvec(myallocator);
|
||||
int i;
|
||||
InstanceCounter ic;
|
||||
for(i = 0; true; ++i){
|
||||
myvec.insert(myvec.begin(), i, InstanceCounter());
|
||||
myvec.insert(myvec.begin(), i, ic);
|
||||
}
|
||||
}
|
||||
catch(boost::interprocess::bad_alloc &){
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_TEST_HEADER
|
||||
#define BOOST_INTERPROCESS_TEST_HEADER
|
||||
#ifndef BOOST_INTERPROCESS_TEST_CHECK_HEADER
|
||||
#define BOOST_INTERPROCESS_TEST_CHECK_HEADER
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
@@ -18,10 +18,10 @@
|
||||
namespace boost { namespace interprocess { namespace test {
|
||||
|
||||
#define BOOST_INTERPROCES_CHECK( P ) \
|
||||
if(!(P)) do{ std::cout << "Failed: " << #P << " file: " << __FILE__ << " line : " << __LINE__ << std::endl; throw boost::interprocess::interprocess_exception();}while(0)
|
||||
if(!(P)) do{ std::cout << "Failed: " << #P << " file: " << __FILE__ << " line : " << __LINE__ << std::endl; throw boost::interprocess::interprocess_exception(#P);}while(0)
|
||||
|
||||
}}} //namespace boost { namespace interprocess { namespace test {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_TEST_HEADER
|
||||
#endif //BOOST_INTERPROCESS_TEST_CHECK_HEADER
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
#include <cstdio> //std::remove
|
||||
|
||||
using namespace boost::interprocess;
|
||||
|
||||
static const std::size_t FileSize = 1000;
|
||||
inline std::string get_filename()
|
||||
{
|
||||
std::string ret (detail::get_temporary_path());
|
||||
ret += "/";
|
||||
ret += test::get_process_id_name();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//This wrapper is necessary to have a default constructor
|
||||
//in generic mutex_test_template functions
|
||||
class file_lock_lock_test_wrapper
|
||||
@@ -27,7 +37,7 @@ class file_lock_lock_test_wrapper
|
||||
{
|
||||
public:
|
||||
file_lock_lock_test_wrapper()
|
||||
: boost::interprocess::file_lock(test::get_process_id_name())
|
||||
: boost::interprocess::file_lock(get_filename().c_str())
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -35,12 +45,12 @@ int main ()
|
||||
{
|
||||
//Destroy and create file
|
||||
{
|
||||
std::remove(test::get_process_id_name());
|
||||
std::ofstream file(test::get_process_id_name());
|
||||
std::remove(get_filename().c_str());
|
||||
std::ofstream file(get_filename().c_str());
|
||||
if(!file){
|
||||
return 1;
|
||||
}
|
||||
file_lock flock(test::get_process_id_name());
|
||||
file_lock flock(get_filename().c_str());
|
||||
{
|
||||
scoped_lock<file_lock> sl(flock);
|
||||
}
|
||||
@@ -53,7 +63,7 @@ int main ()
|
||||
}
|
||||
{
|
||||
//Now test move semantics
|
||||
file_lock mapping(test::get_process_id_name());
|
||||
file_lock mapping(get_filename().c_str());
|
||||
file_lock move_ctor(boost::interprocess::move(mapping));
|
||||
file_lock move_assign;
|
||||
move_assign = boost::interprocess::move(move_ctor);
|
||||
@@ -63,7 +73,7 @@ int main ()
|
||||
//test::test_all_lock<file_lock_lock_test_wrapper>();
|
||||
//test::test_all_mutex<false, file_lock_lock_test_wrapper>();
|
||||
//test::test_all_sharable_mutex<false, file_lock_lock_test_wrapper>();
|
||||
std::remove(test::get_process_id_name());
|
||||
std::remove(get_filename().c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,14 @@
|
||||
|
||||
using namespace boost::interprocess;
|
||||
|
||||
inline std::string get_filename()
|
||||
{
|
||||
std::string ret (detail::get_temporary_path());
|
||||
ret += "/";
|
||||
ret += test::get_process_id_name();
|
||||
return ret;
|
||||
}
|
||||
|
||||
file_mapping get_file_mapping()
|
||||
{
|
||||
file_mapping f;
|
||||
@@ -33,14 +41,14 @@ int main ()
|
||||
const std::size_t FileSize = 99999*2;
|
||||
{
|
||||
//Create file with given size
|
||||
std::ofstream file(test::get_process_id_name(), std::ios::binary | std::ios::trunc);
|
||||
std::ofstream file(get_filename().c_str(), std::ios::binary | std::ios::trunc);
|
||||
file.seekp(static_cast<std::streamoff>(FileSize-1));
|
||||
file.write("", 1);
|
||||
}
|
||||
|
||||
{
|
||||
//Create a file mapping
|
||||
file_mapping mapping(test::get_process_id_name(), read_write);
|
||||
file_mapping mapping(get_filename().c_str(), read_write);
|
||||
//Create two mapped regions, one half of the file each
|
||||
mapped_region region (mapping
|
||||
,read_write
|
||||
@@ -73,7 +81,7 @@ int main ()
|
||||
//See if the pattern is correct in the file
|
||||
{
|
||||
//Open the file
|
||||
std::ifstream file(test::get_process_id_name(), std::ios::binary);
|
||||
std::ifstream file(get_filename().c_str(), std::ios::binary);
|
||||
|
||||
//Create a memory buffer
|
||||
std::auto_ptr<unsigned char> memory (new unsigned char [FileSize/2 +1]);
|
||||
@@ -110,7 +118,7 @@ int main ()
|
||||
//Now check the pattern mapping a single read only mapped_region
|
||||
{
|
||||
//Create a file mapping
|
||||
file_mapping mapping(test::get_process_id_name(), read_only);
|
||||
file_mapping mapping(get_filename().c_str(), read_only);
|
||||
|
||||
//Create a single regions, mapping all the file
|
||||
mapped_region region (mapping
|
||||
@@ -129,7 +137,7 @@ int main ()
|
||||
}
|
||||
{
|
||||
//Now test move semantics
|
||||
file_mapping mapping(test::get_process_id_name(), read_only);
|
||||
file_mapping mapping(get_filename().c_str(), read_only);
|
||||
file_mapping move_ctor(boost::interprocess::move(mapping));
|
||||
file_mapping move_assign;
|
||||
move_assign = boost::interprocess::move(move_ctor);
|
||||
@@ -138,11 +146,11 @@ int main ()
|
||||
}
|
||||
}
|
||||
catch(std::exception &exc){
|
||||
file_mapping::remove(test::get_process_id_name());
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
std::cout << "Unhandled exception: " << exc.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
file_mapping::remove(test::get_process_id_name());
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
95
test/intermodule_singleton_test.cpp
Normal file
95
test/intermodule_singleton_test.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2009. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/intermodule_singleton.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost::interprocess;
|
||||
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
MyClass()
|
||||
{
|
||||
std::cout << "Constructor\n";
|
||||
}
|
||||
|
||||
void shout() const
|
||||
{
|
||||
std::cout << "Shout\n";
|
||||
}
|
||||
|
||||
~MyClass()
|
||||
{
|
||||
std::cout << "Destructor\n";
|
||||
}
|
||||
};
|
||||
|
||||
class MyDerivedClass
|
||||
: public MyClass
|
||||
{};
|
||||
|
||||
class MyThrowingClass
|
||||
{
|
||||
public:
|
||||
MyThrowingClass()
|
||||
{
|
||||
throw int(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
|
||||
bool exception_thrown = false;
|
||||
bool exception_2_thrown = false;
|
||||
|
||||
try{
|
||||
detail::intermodule_singleton<MyThrowingClass, true>::get();
|
||||
}
|
||||
catch(int &){
|
||||
exception_thrown = true;
|
||||
//Second try
|
||||
try{
|
||||
detail::intermodule_singleton<MyThrowingClass, true>::get();
|
||||
}
|
||||
catch(interprocess_exception &){
|
||||
exception_2_thrown = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!exception_thrown || !exception_2_thrown){
|
||||
return 1;
|
||||
}
|
||||
|
||||
MyClass & mc = detail::intermodule_singleton<MyClass>::get();
|
||||
mc.shout();
|
||||
detail::intermodule_singleton<MyClass>::get().shout();
|
||||
detail::intermodule_singleton<MyDerivedClass>::get().shout();
|
||||
|
||||
//Second try
|
||||
exception_2_thrown = false;
|
||||
try{
|
||||
detail::intermodule_singleton<MyThrowingClass, true>::get();
|
||||
}
|
||||
catch(interprocess_exception &){
|
||||
exception_2_thrown = true;
|
||||
}
|
||||
if(!exception_2_thrown){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
@@ -18,10 +18,17 @@
|
||||
|
||||
using namespace boost::interprocess;
|
||||
|
||||
inline std::string get_filename()
|
||||
{
|
||||
std::string ret (detail::get_temporary_path());
|
||||
ret += "/";
|
||||
ret += test::get_process_id_name();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
const int FileSize = 65536*10;
|
||||
const char *const FileName = test::get_process_id_name();
|
||||
|
||||
//STL compatible allocator object for memory-mapped file
|
||||
typedef allocator<int, managed_mapped_file::segment_manager>
|
||||
@@ -31,12 +38,12 @@ int main ()
|
||||
|
||||
{
|
||||
//Remove the file it is already created
|
||||
file_mapping::remove(FileName);
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
|
||||
const int max = 100;
|
||||
void *array[max];
|
||||
//Named allocate capable shared memory allocator
|
||||
managed_mapped_file mfile(create_only, FileName, FileSize);
|
||||
managed_mapped_file mfile(create_only, get_filename().c_str(), FileSize);
|
||||
|
||||
int i;
|
||||
//Let's allocate some memory
|
||||
@@ -52,10 +59,10 @@ int main ()
|
||||
|
||||
{
|
||||
//Remove the file it is already created
|
||||
file_mapping::remove(FileName);
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
|
||||
//Named allocate capable memory mapped file managed memory class
|
||||
managed_mapped_file mfile(create_only, FileName, FileSize);
|
||||
managed_mapped_file mfile(create_only, get_filename().c_str(), FileSize);
|
||||
|
||||
//Construct the STL-like allocator with the segment manager
|
||||
const allocator_int_t myallocator (mfile.get_segment_manager());
|
||||
@@ -80,7 +87,7 @@ int main ()
|
||||
}
|
||||
{
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
|
||||
//Check vector is still there
|
||||
MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
|
||||
@@ -91,7 +98,7 @@ int main ()
|
||||
{
|
||||
{
|
||||
//Map preexisting file again in copy-on-write
|
||||
managed_mapped_file mfile(open_copy_on_write, FileName);
|
||||
managed_mapped_file mfile(open_copy_on_write, get_filename().c_str());
|
||||
|
||||
//Check vector is still there
|
||||
MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
|
||||
@@ -109,7 +116,7 @@ int main ()
|
||||
//Now check vector is still in the file
|
||||
{
|
||||
//Map preexisting file again in copy-on-write
|
||||
managed_mapped_file mfile(open_copy_on_write, FileName);
|
||||
managed_mapped_file mfile(open_copy_on_write, get_filename().c_str());
|
||||
|
||||
//Check vector is still there
|
||||
MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
|
||||
@@ -119,7 +126,7 @@ int main ()
|
||||
}
|
||||
{
|
||||
//Map preexisting file again in copy-on-write
|
||||
managed_mapped_file mfile(open_read_only, FileName);
|
||||
managed_mapped_file mfile(open_read_only, get_filename().c_str());
|
||||
|
||||
//Check vector is still there
|
||||
MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
|
||||
@@ -130,15 +137,15 @@ int main ()
|
||||
std::size_t old_free_memory;
|
||||
{
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
old_free_memory = mfile.get_free_memory();
|
||||
}
|
||||
|
||||
//Now grow the file
|
||||
managed_mapped_file::grow(FileName, FileSize);
|
||||
managed_mapped_file::grow(get_filename().c_str(), FileSize);
|
||||
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
|
||||
//Check vector is still there
|
||||
MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
|
||||
@@ -155,17 +162,17 @@ int main ()
|
||||
old_file_size, next_file_size, final_file_size;
|
||||
{
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
old_free_memory = mfile.get_free_memory();
|
||||
old_file_size = mfile.get_size();
|
||||
}
|
||||
|
||||
//Now shrink the file
|
||||
managed_mapped_file::shrink_to_fit(FileName);
|
||||
managed_mapped_file::shrink_to_fit(get_filename().c_str());
|
||||
|
||||
{
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
next_file_size = mfile.get_size();
|
||||
|
||||
//Check vector is still there
|
||||
@@ -183,7 +190,7 @@ int main ()
|
||||
//Now destroy the vector
|
||||
{
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
|
||||
//Destroy and check it is not present
|
||||
mfile.destroy<MyVect>("MyVector");
|
||||
@@ -192,17 +199,17 @@ int main ()
|
||||
}
|
||||
|
||||
//Now shrink the file
|
||||
managed_mapped_file::shrink_to_fit(FileName);
|
||||
managed_mapped_file::shrink_to_fit(get_filename().c_str());
|
||||
{
|
||||
//Map preexisting file again in memory
|
||||
managed_mapped_file mfile(open_only, FileName);
|
||||
managed_mapped_file mfile(open_only, get_filename().c_str());
|
||||
final_file_size = mfile.get_size();
|
||||
if(next_file_size <= final_file_size)
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
//Now test move semantics
|
||||
managed_mapped_file original(open_only, FileName);
|
||||
managed_mapped_file original(open_only, get_filename().c_str());
|
||||
managed_mapped_file move_ctor(boost::interprocess::move(original));
|
||||
managed_mapped_file move_assign;
|
||||
move_assign = boost::interprocess::move(move_ctor);
|
||||
@@ -210,7 +217,7 @@ int main ()
|
||||
}
|
||||
}
|
||||
|
||||
file_mapping::remove(FileName);
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,19 +18,26 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include "get_process_id_name.hpp"
|
||||
|
||||
using namespace boost::interprocess;
|
||||
|
||||
static const std::size_t FileSize = 1000;
|
||||
static const char * FileName = test::get_process_id_name();
|
||||
inline std::string get_filename()
|
||||
{
|
||||
std::string ret (detail::get_temporary_path());
|
||||
ret += "/";
|
||||
ret += test::get_process_id_name();
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct file_destroyer
|
||||
{
|
||||
~file_destroyer()
|
||||
{
|
||||
//The last destructor will destroy the file
|
||||
file_mapping::remove(FileName);
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,15 +52,15 @@ class mapped_file_creation_test_wrapper
|
||||
<boost::interprocess::detail::file_wrapper> mapped_file;
|
||||
public:
|
||||
mapped_file_creation_test_wrapper(boost::interprocess::create_only_t)
|
||||
: mapped_file(boost::interprocess::create_only, FileName, FileSize)
|
||||
: mapped_file(boost::interprocess::create_only, get_filename().c_str(), FileSize, read_write, 0, permissions())
|
||||
{}
|
||||
|
||||
mapped_file_creation_test_wrapper(boost::interprocess::open_only_t)
|
||||
: mapped_file(boost::interprocess::open_only, FileName)
|
||||
: mapped_file(boost::interprocess::open_only, get_filename().c_str(), read_write, 0)
|
||||
{}
|
||||
|
||||
mapped_file_creation_test_wrapper(boost::interprocess::open_or_create_t)
|
||||
: mapped_file(boost::interprocess::open_or_create, FileName, FileSize)
|
||||
: mapped_file(boost::interprocess::open_or_create, get_filename().c_str(), FileSize, read_write, 0, permissions())
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -61,15 +68,15 @@ int main ()
|
||||
{
|
||||
typedef boost::interprocess::detail::managed_open_or_create_impl
|
||||
<boost::interprocess::detail::file_wrapper> mapped_file;
|
||||
file_mapping::remove(FileName);
|
||||
file_mapping::remove(get_filename().c_str());
|
||||
test::test_named_creation<mapped_file_creation_test_wrapper>();
|
||||
|
||||
//Create and get name, size and address
|
||||
{
|
||||
mapped_file file1(create_only, FileName, FileSize);
|
||||
mapped_file file1(create_only, get_filename().c_str(), FileSize, read_write, 0, permissions());
|
||||
|
||||
//Compare name
|
||||
if(std::strcmp(file1.get_name(), FileName) != 0){
|
||||
if(std::strcmp(file1.get_name(), get_filename().c_str()) != 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -81,7 +88,7 @@ int main ()
|
||||
mapped_file move_assign;
|
||||
move_assign = boost::interprocess::move(move_ctor);
|
||||
}
|
||||
file_mapping::remove(FileName);
|
||||
// file_mapping::remove(get_filename().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -501,17 +501,23 @@ bool test_clear_free_memory(Allocator &a)
|
||||
|
||||
//Now test all allocated memory is zero
|
||||
//Allocate memory
|
||||
const char *first_addr = 0;
|
||||
for(int i = 0; true; ++i){
|
||||
void *ptr = a.allocate(i, std::nothrow);
|
||||
if(!ptr)
|
||||
break;
|
||||
if(i == 0){
|
||||
first_addr = (char*)ptr;
|
||||
}
|
||||
std::size_t memsize = a.size(ptr);
|
||||
buffers.push_back(ptr);
|
||||
}
|
||||
|
||||
//Test allocated memory is zero
|
||||
for(int i = 0, max = buffers.size(); i < max; ++i){
|
||||
for(int j = 0; j < i; ++j){
|
||||
if(static_cast<char*>(buffers[i])[j]) return false;
|
||||
for(int j = 0; j < (int)memsize; ++j){
|
||||
if(static_cast<char*>((char*)ptr)[j]){
|
||||
std::cout << "Zero memory test failed. in buffer " << i
|
||||
<< " byte " << j << " first address " << (void*) first_addr << " offset " << ((char*)ptr+j) - (char*)first_addr << " memsize: " << memsize << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ std::basic_ostream<E, T> & operator<<
|
||||
|
||||
class movable_and_copyable_int
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
|
||||
BOOST_INTERPROCESS_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
|
||||
public:
|
||||
|
||||
movable_and_copyable_int()
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "mutex_test_template.hpp"
|
||||
#include "named_creation_template.hpp"
|
||||
|
||||
int main ()
|
||||
{
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "util.hpp"
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <iostream>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
|
||||
namespace boost { namespace interprocess { namespace test {
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ inline void create_then_open_then_open_or_create()
|
||||
}
|
||||
catch(...){
|
||||
//This shouldn't throw so show the error
|
||||
BOOST_INTERPROCES_CHECK(false);
|
||||
BOOST_INTERPROCES_CHECK( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_PRINTCONTAINER_HPP
|
||||
#define BOOST_PRINTCONTAINER_HPP
|
||||
#ifndef BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP
|
||||
#define BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <functional>
|
||||
@@ -61,4 +61,4 @@ void PrintContainers(MyShmCont *shmcont, MyStdCont *stdcont)
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_PRINTCONTAINER_HPP
|
||||
#endif //#ifndef BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP
|
||||
|
||||
22
test/robust_emulation_test.cpp
Normal file
22
test/robust_emulation_test.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2010-2010. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include "robust_mutex_test.hpp"
|
||||
#include <boost/interprocess/detail/robust_emulation.hpp>
|
||||
#include <boost/interprocess/sync/emulation/mutex.hpp>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
using namespace boost::interprocess;
|
||||
return test::robust_mutex_test
|
||||
< detail::robust_emulation_mutex<detail::emulation_mutex> >(argc, argv);
|
||||
}
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
204
test/robust_mutex_test.hpp
Normal file
204
test/robust_mutex_test.hpp
Normal file
@@ -0,0 +1,204 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2010-2010. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_TEST_ROBUST_MUTEX_TEST_HEADER
|
||||
#define BOOST_INTERPROCESS_TEST_ROBUST_MUTEX_TEST_HEADER
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <iostream>
|
||||
#include <cstdlib> //std::system
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
#include "get_process_id_name.hpp"
|
||||
#include "mutex_test_template.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace test{
|
||||
|
||||
template<class RobustMutex>
|
||||
int robust_mutex_test(int argc, char *argv[])
|
||||
{
|
||||
try{
|
||||
if(argc == 1){ //Parent process
|
||||
//First usual mutex tests
|
||||
{
|
||||
// test_all_lock<RobustMutex>();
|
||||
// test_all_mutex<true, RobustMutex>();
|
||||
}
|
||||
std::cout << "robust mutex recovery test" << std::endl;
|
||||
|
||||
//Remove shared memory on construction and destruction
|
||||
class shm_remove
|
||||
{
|
||||
public:
|
||||
shm_remove(){ shared_memory_object::remove
|
||||
(::boost::interprocess::test::get_process_id_name()); }
|
||||
~shm_remove(){ shared_memory_object::remove
|
||||
(::boost::interprocess::test::get_process_id_name()); }
|
||||
} remover;
|
||||
|
||||
//Construct managed shared memory
|
||||
managed_shared_memory segment(create_only, get_process_id_name(), 65536);
|
||||
|
||||
//Create two robust mutexes
|
||||
RobustMutex *instance = segment.construct<RobustMutex>
|
||||
("robust mutex")[2]();
|
||||
|
||||
//Create a flag to notify that both mutexes are
|
||||
//locked and the owner is going to die soon.
|
||||
bool *go_ahead = segment.construct<bool> ("go ahead")(false);
|
||||
|
||||
//Launch child process
|
||||
std::string s(argv[0]); s += " child ";
|
||||
s += get_process_id_name();
|
||||
std::cout << "... launching child" << std::endl;
|
||||
if(0 != std::system(s.c_str()))
|
||||
return 1;
|
||||
|
||||
//Wait until child locks the mutexes and dies
|
||||
while(!*go_ahead){
|
||||
detail::thread_yield();
|
||||
}
|
||||
|
||||
std::cout << "... recovering mutex[0]" << std::endl;
|
||||
//First try to recover lock[0], put into consistent
|
||||
//state and relock it again
|
||||
{
|
||||
//Done, now try to lock it to see if robust
|
||||
//mutex recovery works
|
||||
instance[0].lock();
|
||||
if(!instance[0].previous_owner_dead())
|
||||
return 1;
|
||||
instance[0].consistent();
|
||||
instance[0].unlock();
|
||||
//Since it's consistent, locking is possible again
|
||||
instance[0].lock();
|
||||
instance[0].unlock();
|
||||
}
|
||||
//Now with lock[1], but dont' put it in consistent state
|
||||
//so the mutex is no longer usable
|
||||
std::cout << "... recovering mutex[1]" << std::endl;
|
||||
{
|
||||
//Done, now try to lock it to see if robust
|
||||
//mutex recovery works
|
||||
instance[1].lock();
|
||||
if(!instance[1].previous_owner_dead())
|
||||
return 1;
|
||||
//Unlock a recovered mutex without putting it into
|
||||
//into consistent state marks mutex as unusable.
|
||||
instance[1].unlock();
|
||||
//Since it's NOT consistent, locking is NOT possible again
|
||||
bool exception_thrown = false;
|
||||
try{
|
||||
instance[1].lock();
|
||||
}
|
||||
catch(interprocess_exception &){
|
||||
exception_thrown = true;
|
||||
}
|
||||
if(!exception_thrown){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//Now with lock[2], this was locked by child but not
|
||||
//unlocked
|
||||
std::cout << "... recovering mutex[2]" << std::endl;
|
||||
{
|
||||
//Done, now try to lock it to see if robust
|
||||
//mutex recovery works
|
||||
instance[2].lock();
|
||||
if(!instance[2].previous_owner_dead())
|
||||
return 1;
|
||||
//Unlock a recovered mutex without putting it into
|
||||
//into consistent state marks mutex as unusable.
|
||||
instance[2].unlock();
|
||||
//Since it's NOT consistent, locking is NOT possible again
|
||||
bool exception_thrown = false;
|
||||
try{
|
||||
instance[2].lock();
|
||||
}
|
||||
catch(interprocess_exception &){
|
||||
exception_thrown = true;
|
||||
}
|
||||
if(!exception_thrown){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Open managed shared memory
|
||||
managed_shared_memory segment(open_only, argv[2]);
|
||||
//Find mutexes
|
||||
RobustMutex *instance = segment.find<RobustMutex>("robust mutex").first;
|
||||
assert(instance);
|
||||
if(std::string(argv[1]) == std::string("child")){
|
||||
std::cout << "launched child" << std::endl;
|
||||
//Find flag
|
||||
bool *go_ahead = segment.find<bool>("go ahead").first;
|
||||
assert(go_ahead);
|
||||
//Lock, flag and die
|
||||
bool try_lock_res = instance[0].try_lock() && instance[1].try_lock();
|
||||
assert(try_lock_res);
|
||||
if(!try_lock_res)
|
||||
return 1;
|
||||
|
||||
bool *go_ahead2 = segment.construct<bool>("go ahead2")(false);
|
||||
assert(go_ahead2);
|
||||
//Launch grandchild
|
||||
std::string s(argv[0]); s += " grandchild ";
|
||||
s += argv[2];
|
||||
std::cout << "... launching grandchild" << std::endl;
|
||||
if(0 != std::system(s.c_str())){
|
||||
std::cout << "launched terminated with error" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Wait until child locks the 2nd mutex and dies
|
||||
while(!*go_ahead2){
|
||||
detail::thread_yield();
|
||||
}
|
||||
|
||||
//Done, now try to lock number 3 to see if robust
|
||||
//mutex recovery works
|
||||
instance[2].lock();
|
||||
if(!instance[2].previous_owner_dead()){
|
||||
return 1;
|
||||
}
|
||||
*go_ahead = true;
|
||||
}
|
||||
else{
|
||||
std::cout << "launched grandchild" << std::endl;
|
||||
//grandchild locks the lock and dies
|
||||
bool *go_ahead2 = segment.find<bool>("go ahead2").first;
|
||||
assert(go_ahead2);
|
||||
//Lock, flag and die
|
||||
bool try_lock_res = instance[2].try_lock();
|
||||
assert(try_lock_res);
|
||||
if(!try_lock_res){
|
||||
return 1;
|
||||
}
|
||||
*go_ahead2 = true;
|
||||
}
|
||||
}
|
||||
}catch(...){
|
||||
std::cout << "Exception thrown error!" << std::endl;
|
||||
throw;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} //namespace test{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_TEST_ROBUST_EMULATION_TEST_HEADER
|
||||
23
test/robust_recursive_emulation_test.cpp
Normal file
23
test/robust_recursive_emulation_test.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2010-2010. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include "robust_mutex_test.hpp"
|
||||
#include <boost/interprocess/detail/robust_emulation.hpp>
|
||||
#include <boost/interprocess/sync/emulation/recursive_mutex.hpp>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
using namespace boost::interprocess;
|
||||
|
||||
return test::robust_mutex_test
|
||||
< detail::robust_emulation_mutex<detail::emulation_recursive_mutex> >(argc, argv);
|
||||
}
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
@@ -69,6 +69,9 @@ int main ()
|
||||
;++i){
|
||||
*filler++ = static_cast<unsigned char>(i);
|
||||
}
|
||||
if(!region.flush()){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//See if the pattern is correct in the file using two mapped regions
|
||||
|
||||
@@ -42,15 +42,15 @@ class shared_memory_creation_test_wrapper
|
||||
|
||||
public:
|
||||
shared_memory_creation_test_wrapper(create_only_t)
|
||||
: shared_memory(create_only, ShmName, ShmSize)
|
||||
: shared_memory(create_only, ShmName, ShmSize, read_write, 0, permissions())
|
||||
{}
|
||||
|
||||
shared_memory_creation_test_wrapper(open_only_t)
|
||||
: shared_memory(open_only, ShmName)
|
||||
: shared_memory(open_only, ShmName, read_write, 0)
|
||||
{}
|
||||
|
||||
shared_memory_creation_test_wrapper(open_or_create_t)
|
||||
: shared_memory(open_or_create, ShmName, ShmSize)
|
||||
: shared_memory(open_or_create, ShmName, ShmSize, read_write, 0, permissions())
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ int main ()
|
||||
//Create and get name, size and address
|
||||
{
|
||||
shared_memory_object::remove(ShmName);
|
||||
shared_memory shm1(create_only, ShmName, ShmSize);
|
||||
shared_memory shm1(create_only, ShmName, ShmSize, read_write, 0, permissions());
|
||||
|
||||
//Compare name
|
||||
if(std::strcmp(shm1.get_name(), ShmName) != 0){
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER
|
||||
#define BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
@@ -246,3 +249,5 @@ int vector_test()
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,15 +42,15 @@ class shared_memory_creation_test_wrapper
|
||||
{
|
||||
public:
|
||||
shared_memory_creation_test_wrapper(create_only_t)
|
||||
: windows_shared_memory_t(create_only, name_initialization_routine(), ShmSize)
|
||||
: windows_shared_memory_t(create_only, name_initialization_routine(), ShmSize, read_write, 0, permissions())
|
||||
{}
|
||||
|
||||
shared_memory_creation_test_wrapper(open_only_t)
|
||||
: windows_shared_memory_t(open_only, name_initialization_routine())
|
||||
: windows_shared_memory_t(open_only, name_initialization_routine(), read_write, 0)
|
||||
{}
|
||||
|
||||
shared_memory_creation_test_wrapper(open_or_create_t)
|
||||
: windows_shared_memory_t(open_or_create, name_initialization_routine(), ShmSize)
|
||||
: windows_shared_memory_t(open_or_create, name_initialization_routine(), ShmSize, read_write, 0, permissions())
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user