Fixes for Boost 1.45

[SVN r65013]
This commit is contained in:
Ion Gaztañaga
2010-08-26 09:27:50 +00:00
parent 13cc42b4bb
commit 66006b2233
33 changed files with 1057 additions and 130 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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"
] ;
}

View File

@@ -77,4 +77,3 @@ int main ()
return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>

View File

@@ -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();

View File

@@ -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

View 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>

View File

@@ -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>

View 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

View File

@@ -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>

View 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>

View File

@@ -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"

View File

@@ -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"
] ;
}

View File

@@ -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 &){

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View 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>

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}
}

View File

@@ -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()

View File

@@ -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 ()
{

View File

@@ -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 {

View File

@@ -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 );
}
}

View File

@@ -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

View 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
View 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

View 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>

View File

@@ -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

View File

@@ -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){

View File

@@ -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

View File

@@ -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())
{}
};