From 66006b223324521288de1eb034755c32777f8105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 26 Aug 2010 09:27:50 +0000 Subject: [PATCH] Fixes for Boost 1.45 [SVN r65013] --- doc/Jamfile.v2 | 1 + doc/interprocess.qbk | 114 +++++++--- example/Jamfile.v2 | 1 + example/comp_doc_anonymous_conditionA.cpp | 1 - proj/to-do.txt | 181 +++++++++++++++- proj/vc7ide/Interprocess.sln | 40 +++- proj/vc7ide/intermodule_singleton_test.vcproj | 138 ++++++++++++ proj/vc7ide/interprocesslib.vcproj | 30 +-- proj/vc7ide/memory_algorithm_test.vcproj | 3 +- ...y2.vcproj => robust_emulation_test.vcproj} | 18 +- .../robust_recursive_emulation_test.vcproj | 133 ++++++++++++ proj/vc7ide/stable_vector_test.vcproj | 2 + test/Jamfile.v2 | 1 + test/allocexcept_test.cpp | 3 +- test/boost_interprocess_check.hpp | 8 +- test/file_lock_test.cpp | 22 +- test/file_mapping_test.cpp | 22 +- test/intermodule_singleton_test.cpp | 95 ++++++++ test/managed_mapped_file_test.cpp | 47 ++-- test/mapped_file_test.cpp | 25 ++- test/memory_algorithm_test_template.hpp | 16 +- test/movable_int.hpp | 2 +- test/mutex_test.cpp | 3 - test/mutex_test_template.hpp | 2 + test/named_creation_template.hpp | 2 +- test/print_container.hpp | 6 +- test/robust_emulation_test.cpp | 22 ++ test/robust_mutex_test.hpp | 204 ++++++++++++++++++ test/robust_recursive_emulation_test.cpp | 23 ++ test/shared_memory_mapping_test.cpp | 3 + test/shared_memory_test.cpp | 8 +- test/vector_test.hpp | 5 + test/windows_shared_memory_test.cpp | 6 +- 33 files changed, 1057 insertions(+), 130 deletions(-) create mode 100644 proj/vc7ide/intermodule_singleton_test.vcproj rename proj/vc7ide/{doc_windows_shared_memory2.vcproj => robust_emulation_test.vcproj} (85%) create mode 100644 proj/vc7ide/robust_recursive_emulation_test.vcproj create mode 100644 test/intermodule_singleton_test.cpp create mode 100644 test/robust_emulation_test.cpp create mode 100644 test/robust_mutex_test.hpp create mode 100644 test/robust_recursive_emulation_test.cpp diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 8ea5052..09a99b0 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -44,6 +44,7 @@ boostbook standalone interprocess : boost.root=../../../.. + boost.libraries=../../../../libs/libraries.htm toc.max.depth=1 toc.section.depth=2 chunk.first.sections=1 diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index f74a6af..e679a82 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -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. diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index e1a68bc..9c9a8da 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -36,6 +36,7 @@ rule test_all : # requirements acc:-lrt acc-pa_risc:-lrt + gcc-mingw:"-lole32 -loleaut32" hpux,gcc:"-Wl,+as,mpas" ] ; } diff --git a/example/comp_doc_anonymous_conditionA.cpp b/example/comp_doc_anonymous_conditionA.cpp index 3071013..8893deb 100644 --- a/example/comp_doc_anonymous_conditionA.cpp +++ b/example/comp_doc_anonymous_conditionA.cpp @@ -77,4 +77,3 @@ int main () return 0; } //] -#include diff --git a/proj/to-do.txt b/proj/to-do.txt index 1b65de1..379042f 100644 --- a/proj/to-do.txt +++ b/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 \ No newline at end of file +-> 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(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: + +->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::get(); diff --git a/proj/vc7ide/Interprocess.sln b/proj/vc7ide/Interprocess.sln index b003676..950df02 100644 --- a/proj/vc7ide/Interprocess.sln +++ b/proj/vc7ide/Interprocess.sln @@ -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 diff --git a/proj/vc7ide/intermodule_singleton_test.vcproj b/proj/vc7ide/intermodule_singleton_test.vcproj new file mode 100644 index 0000000..1326a3a --- /dev/null +++ b/proj/vc7ide/intermodule_singleton_test.vcproj @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/interprocesslib.vcproj b/proj/vc7ide/interprocesslib.vcproj index 90df035..ee979a3 100644 --- a/proj/vc7ide/interprocesslib.vcproj +++ b/proj/vc7ide/interprocesslib.vcproj @@ -265,23 +265,23 @@ Name="emulation" Filter=""> + RelativePath="..\..\..\..\boost\interprocess\sync\emulation\barrier.hpp"> + RelativePath="..\..\..\..\boost\interprocess\sync\emulation\condition.hpp"> - - - - + RelativePath="..\..\..\..\boost\interprocess\sync\emulation\mutex.hpp"> + + + + + + @@ -429,6 +432,9 @@ + + @@ -534,15 +540,9 @@ - - - - diff --git a/proj/vc7ide/memory_algorithm_test.vcproj b/proj/vc7ide/memory_algorithm_test.vcproj index a161276..70c8ac3 100644 --- a/proj/vc7ide/memory_algorithm_test.vcproj +++ b/proj/vc7ide/memory_algorithm_test.vcproj @@ -72,6 +72,7 @@ CharacterSet="2"> + DebugInformationFormat="3"/> @@ -67,7 +67,7 @@ + UniqueIdentifier="{4C737CF1-6C7A-A035-4376-A1A2C75F232F}"> + RelativePath="..\..\test\robust_emulation_test.cpp"> diff --git a/proj/vc7ide/robust_recursive_emulation_test.vcproj b/proj/vc7ide/robust_recursive_emulation_test.vcproj new file mode 100644 index 0000000..78f4d65 --- /dev/null +++ b/proj/vc7ide/robust_recursive_emulation_test.vcproj @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/stable_vector_test.vcproj b/proj/vc7ide/stable_vector_test.vcproj index fdc2192..de7251d 100644 --- a/proj/vc7ide/stable_vector_test.vcproj +++ b/proj/vc7ide/stable_vector_test.vcproj @@ -72,6 +72,8 @@ CharacterSet="2"> acc:-lrt acc-pa_risc:-lrt + gcc-mingw:"-lole32 -loleaut32" hpux,gcc:"-Wl,+as,mpas" ] ; } diff --git a/test/allocexcept_test.cpp b/test/allocexcept_test.cpp index 3c59fd6..9de6540 100644 --- a/test/allocexcept_test.cpp +++ b/test/allocexcept_test.cpp @@ -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 &){ diff --git a/test/boost_interprocess_check.hpp b/test/boost_interprocess_check.hpp index da1affc..0487387 100644 --- a/test/boost_interprocess_check.hpp +++ b/test/boost_interprocess_check.hpp @@ -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 #include @@ -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 -#endif //BOOST_INTERPROCESS_TEST_HEADER +#endif //BOOST_INTERPROCESS_TEST_CHECK_HEADER diff --git a/test/file_lock_test.cpp b/test/file_lock_test.cpp index a76412d..039f669 100644 --- a/test/file_lock_test.cpp +++ b/test/file_lock_test.cpp @@ -20,6 +20,16 @@ #include //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 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(); //test::test_all_mutex(); //test::test_all_sharable_mutex(); - std::remove(test::get_process_id_name()); + std::remove(get_filename().c_str()); return 0; } diff --git a/test/file_mapping_test.cpp b/test/file_mapping_test.cpp index 35817a4..044933b 100644 --- a/test/file_mapping_test.cpp +++ b/test/file_mapping_test.cpp @@ -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(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 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; } diff --git a/test/intermodule_singleton_test.cpp b/test/intermodule_singleton_test.cpp new file mode 100644 index 0000000..56821d3 --- /dev/null +++ b/test/intermodule_singleton_test.cpp @@ -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 +#include +#include + +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::get(); + } + catch(int &){ + exception_thrown = true; + //Second try + try{ + detail::intermodule_singleton::get(); + } + catch(interprocess_exception &){ + exception_2_thrown = true; + } + } + + if(!exception_thrown || !exception_2_thrown){ + return 1; + } + + MyClass & mc = detail::intermodule_singleton::get(); + mc.shout(); + detail::intermodule_singleton::get().shout(); + detail::intermodule_singleton::get().shout(); + + //Second try + exception_2_thrown = false; + try{ + detail::intermodule_singleton::get(); + } + catch(interprocess_exception &){ + exception_2_thrown = true; + } + if(!exception_2_thrown){ + return 1; + } + + return 0; +} + +#include + diff --git a/test/managed_mapped_file_test.cpp b/test/managed_mapped_file_test.cpp index d21dd7b..0de0908 100644 --- a/test/managed_mapped_file_test.cpp +++ b/test/managed_mapped_file_test.cpp @@ -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 @@ -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("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("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("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("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("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("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; } diff --git a/test/mapped_file_test.cpp b/test/mapped_file_test.cpp index 9828643..7f8866e 100644 --- a/test/mapped_file_test.cpp +++ b/test/mapped_file_test.cpp @@ -18,19 +18,26 @@ #include #include #include +#include #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 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 mapped_file; - file_mapping::remove(FileName); + file_mapping::remove(get_filename().c_str()); test::test_named_creation(); //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; } diff --git a/test/memory_algorithm_test_template.hpp b/test/memory_algorithm_test_template.hpp index 08436af..0e76468 100644 --- a/test/memory_algorithm_test_template.hpp +++ b/test/memory_algorithm_test_template.hpp @@ -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(buffers[i])[j]) return false; + for(int j = 0; j < (int)memsize; ++j){ + if(static_cast((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; + } } } diff --git a/test/movable_int.hpp b/test/movable_int.hpp index 1026bdc..c58a883 100644 --- a/test/movable_int.hpp +++ b/test/movable_int.hpp @@ -79,7 +79,7 @@ std::basic_ostream & 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() diff --git a/test/mutex_test.cpp b/test/mutex_test.cpp index 229b158..0fcdb6e 100644 --- a/test/mutex_test.cpp +++ b/test/mutex_test.cpp @@ -10,10 +10,7 @@ #include #include -#include -#include #include "mutex_test_template.hpp" -#include "named_creation_template.hpp" int main () { diff --git a/test/mutex_test_template.hpp b/test/mutex_test_template.hpp index 2b40b75..5e6f455 100644 --- a/test/mutex_test_template.hpp +++ b/test/mutex_test_template.hpp @@ -27,6 +27,8 @@ #include "util.hpp" #include #include +#include +#include namespace boost { namespace interprocess { namespace test { diff --git a/test/named_creation_template.hpp b/test/named_creation_template.hpp index 1c169ca..3d76828 100644 --- a/test/named_creation_template.hpp +++ b/test/named_creation_template.hpp @@ -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 ); } } diff --git a/test/print_container.hpp b/test/print_container.hpp index 2eca310..2965ec9 100644 --- a/test/print_container.hpp +++ b/test/print_container.hpp @@ -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 #include @@ -61,4 +61,4 @@ void PrintContainers(MyShmCont *shmcont, MyStdCont *stdcont) #include -#endif //#ifndef BOOST_PRINTCONTAINER_HPP +#endif //#ifndef BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP diff --git a/test/robust_emulation_test.cpp b/test/robust_emulation_test.cpp new file mode 100644 index 0000000..188c292 --- /dev/null +++ b/test/robust_emulation_test.cpp @@ -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 +#include "robust_mutex_test.hpp" +#include +#include + +int main(int argc, char *argv[]) +{ + using namespace boost::interprocess; + return test::robust_mutex_test + < detail::robust_emulation_mutex >(argc, argv); +} + +#include diff --git a/test/robust_mutex_test.hpp b/test/robust_mutex_test.hpp new file mode 100644 index 0000000..a229cd8 --- /dev/null +++ b/test/robust_mutex_test.hpp @@ -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 +#include +#include //std::system +#include +#include +#include "get_process_id_name.hpp" +#include "mutex_test_template.hpp" +#include + +namespace boost{ +namespace interprocess{ +namespace test{ + +template +int robust_mutex_test(int argc, char *argv[]) +{ + try{ + if(argc == 1){ //Parent process + //First usual mutex tests + { + // test_all_lock(); +// test_all_mutex(); + } + 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 + ("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 ("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("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("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("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("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 + +#endif //BOOST_INTERPROCESS_TEST_ROBUST_EMULATION_TEST_HEADER diff --git a/test/robust_recursive_emulation_test.cpp b/test/robust_recursive_emulation_test.cpp new file mode 100644 index 0000000..52d8462 --- /dev/null +++ b/test/robust_recursive_emulation_test.cpp @@ -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 +#include "robust_mutex_test.hpp" +#include +#include + +int main(int argc, char *argv[]) +{ + using namespace boost::interprocess; + + return test::robust_mutex_test + < detail::robust_emulation_mutex >(argc, argv); +} + +#include diff --git a/test/shared_memory_mapping_test.cpp b/test/shared_memory_mapping_test.cpp index ab0d886..4cc3cea 100644 --- a/test/shared_memory_mapping_test.cpp +++ b/test/shared_memory_mapping_test.cpp @@ -69,6 +69,9 @@ int main () ;++i){ *filler++ = static_cast(i); } + if(!region.flush()){ + return 1; + } } //See if the pattern is correct in the file using two mapped regions diff --git a/test/shared_memory_test.cpp b/test/shared_memory_test.cpp index 796206d..00f062e 100644 --- a/test/shared_memory_test.cpp +++ b/test/shared_memory_test.cpp @@ -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){ diff --git a/test/vector_test.hpp b/test/vector_test.hpp index 3d7799a..f515769 100644 --- a/test/vector_test.hpp +++ b/test/vector_test.hpp @@ -8,6 +8,9 @@ // ////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER +#define BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER + #include #include #include @@ -246,3 +249,5 @@ int vector_test() } //namespace boost{ #include + +#endif diff --git a/test/windows_shared_memory_test.cpp b/test/windows_shared_memory_test.cpp index 15350cf..6087447 100644 --- a/test/windows_shared_memory_test.cpp +++ b/test/windows_shared_memory_test.cpp @@ -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()) {} };