diff options
Diffstat (limited to 'src/boost/libs/interprocess/example')
57 files changed, 5082 insertions, 0 deletions
diff --git a/src/boost/libs/interprocess/example/Jamfile.v2 b/src/boost/libs/interprocess/example/Jamfile.v2 new file mode 100644 index 00000000..22da3e08 --- /dev/null +++ b/src/boost/libs/interprocess/example/Jamfile.v2 @@ -0,0 +1,55 @@ +# Boost Interprocess Library Example Jamfile + +# (C) Copyright Ion Gaztanaga 2006-2012. +# Use, modification and distribution are subject to 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) + +# Adapted from John Maddock's TR1 Jamfile.v2 +# Copyright John Maddock 2005. +# Use, modification and distribution are subject to 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) + +# this rule enumerates through all the sources and invokes +# the run rule for each source, the result is a list of all +# the run rules, which we can pass on to the test_suite rule: + +rule test_all +{ + local all_rules = ; + + for local fileb in [ glob comp*.cpp ] + { + all_rules += [ link $(fileb) + : # additional args + <toolset>acc:<linkflags>-lrt + <toolset>acc-pa_risc:<linkflags>-lrt + <toolset>gcc,<target-os>windows:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32" + <target-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas" + <target-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32" + <target-os>linux:<linkflags>"-lrt" + : # test-files + : # requirements + ] ; + } + + for local fileb in [ glob doc_*.cpp ] + { + all_rules += [ run $(fileb) + : # additional args + : # test-files + : # requirements + <toolset>acc:<linkflags>-lrt + <toolset>acc-pa_risc:<linkflags>-lrt + <toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32" + <target-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas" + <target-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32" + <target-os>linux:<linkflags>"-lrt" + ] ; + } + + return $(all_rules) ; +} + +test-suite interprocess_example : [ test_all r ] : <threading>multi ; diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_conditionA.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_conditionA.cpp new file mode 100644 index 00000000..79aef830 --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_conditionA.cpp @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_conditionA +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <boost/interprocess/sync/scoped_lock.hpp> +#include <iostream> +#include <cstdio> +#include "doc_anonymous_condition_shared_data.hpp" + +using namespace boost::interprocess; + +int main () +{ + + //Erase previous shared memory and schedule erasure on exit + struct shm_remove + { + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Create a shared memory object. + shared_memory_object shm + (create_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + try{ + //Set size + shm.truncate(sizeof(trace_queue)); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Construct the shared structure in memory + trace_queue * data = new (addr) trace_queue; + + const int NumMsg = 100; + + for(int i = 0; i < NumMsg; ++i){ + scoped_lock<interprocess_mutex> lock(data->mutex); + if(data->message_in){ + data->cond_full.wait(lock); + } + if(i == (NumMsg-1)) + std::sprintf(data->items, "%s", "last message"); + else + std::sprintf(data->items, "%s_%d", "my_trace", i); + + //Notify to the other process that there is a message + data->cond_empty.notify_one(); + + //Mark message buffer as full + data->message_in = true; + } + } + catch(interprocess_exception &ex){ + std::cout << ex.what() << std::endl; + return 1; + } + + return 0; +} +//] diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_conditionB.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_conditionB.cpp new file mode 100644 index 00000000..a1694dc4 --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_conditionB.cpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_conditionB +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <boost/interprocess/sync/scoped_lock.hpp> +#include <iostream> +#include <cstring> +#include "doc_anonymous_condition_shared_data.hpp" + +using namespace boost::interprocess; + +int main () +{ + //Create a shared memory object. + shared_memory_object shm + (open_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + try{ + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Obtain a pointer to the shared structure + trace_queue * data = static_cast<trace_queue*>(addr); + + //Print messages until the other process marks the end + bool end_loop = false; + do{ + scoped_lock<interprocess_mutex> lock(data->mutex); + if(!data->message_in){ + data->cond_empty.wait(lock); + } + if(std::strcmp(data->items, "last message") == 0){ + end_loop = true; + } + else{ + //Print the message + std::cout << data->items << std::endl; + //Notify the other process that the buffer is empty + data->message_in = false; + data->cond_full.notify_one(); + } + } + while(!end_loop); + } + catch(interprocess_exception &ex){ + std::cout << ex.what() << std::endl; + return 1; + } + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_mutexA.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_mutexA.cpp new file mode 100644 index 00000000..16793af6 --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_mutexA.cpp @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_mutexA +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <boost/interprocess/sync/scoped_lock.hpp> +#include "doc_anonymous_mutex_shared_data.hpp" +#include <iostream> +#include <cstdio> + +using namespace boost::interprocess; + +int main () +{ + try{ + //Remove shared memory on construction and destruction + struct shm_remove + { + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Create a shared memory object. + shared_memory_object shm + (create_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + //Set size + shm.truncate(sizeof(shared_memory_log)); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Construct the shared structure in memory + shared_memory_log * data = new (addr) shared_memory_log; + + //Write some logs + for(int i = 0; i < shared_memory_log::NumItems; ++i){ + //Lock the mutex + scoped_lock<interprocess_mutex> lock(data->mutex); + std::sprintf(data->items[(data->current_line++) % shared_memory_log::NumItems] + ,"%s_%d", "process_a", i); + if(i == (shared_memory_log::NumItems-1)) + data->end_a = true; + //Mutex is released here + } + + //Wait until the other process ends + while(1){ + scoped_lock<interprocess_mutex> lock(data->mutex); + if(data->end_b) + break; + } + } + catch(interprocess_exception &ex){ + std::cout << ex.what() << std::endl; + return 1; + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_mutexB.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_mutexB.cpp new file mode 100644 index 00000000..1365ad50 --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_mutexB.cpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_mutexB +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <boost/interprocess/sync/scoped_lock.hpp> +#include "doc_anonymous_mutex_shared_data.hpp" +#include <iostream> +#include <cstdio> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on destruction + struct shm_remove + { + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Open the shared memory object. + shared_memory_object shm + (open_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Construct the shared structure in memory + shared_memory_log * data = static_cast<shared_memory_log*>(addr); + + //Write some logs + for(int i = 0; i < 100; ++i){ + //Lock the mutex + scoped_lock<interprocess_mutex> lock(data->mutex); + std::sprintf(data->items[(data->current_line++) % shared_memory_log::NumItems] + ,"%s_%d", "process_a", i); + if(i == (shared_memory_log::NumItems-1)) + data->end_b = true; + //Mutex is released here + } + + //Wait until the other process ends + while(1){ + scoped_lock<interprocess_mutex> lock(data->mutex); + if(data->end_a) + break; + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_semaphoreA.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_semaphoreA.cpp new file mode 100644 index 00000000..34e9960b --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_semaphoreA.cpp @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_semaphoreA +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <iostream> +#include "doc_anonymous_semaphore_shared_data.hpp" + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Create a shared memory object. + shared_memory_object shm + (create_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + //Set size + shm.truncate(sizeof(shared_memory_buffer)); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Construct the shared structure in memory + shared_memory_buffer * data = new (addr) shared_memory_buffer; + + const int NumMsg = 100; + + //Insert data in the array + for(int i = 0; i < NumMsg; ++i){ + data->nempty.wait(); + data->mutex.wait(); + data->items[i % shared_memory_buffer::NumItems] = i; + data->mutex.post(); + data->nstored.post(); + } + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_semaphoreB.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_semaphoreB.cpp new file mode 100644 index 00000000..633283ac --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_semaphoreB.cpp @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_semaphoreB +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <iostream> +#include "doc_anonymous_semaphore_shared_data.hpp" + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on destruction + struct shm_remove + { + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Create a shared memory object. + shared_memory_object shm + (open_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Obtain the shared structure + shared_memory_buffer * data = static_cast<shared_memory_buffer*>(addr); + + const int NumMsg = 100; + + int extracted_data [NumMsg]; + //<- + (void)extracted_data; + //-> + + //Extract the data + for(int i = 0; i < NumMsg; ++i){ + data->nstored.wait(); + data->mutex.wait(); + extracted_data[i] = data->items[i % shared_memory_buffer::NumItems]; + data->mutex.post(); + data->nempty.post(); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexA.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexA.cpp new file mode 100644 index 00000000..7296990a --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexA.cpp @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_upgradable_mutexA +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <boost/interprocess/sync/scoped_lock.hpp> +#include "doc_upgradable_mutex_shared_data.hpp" +#include <iostream> +#include <cstdio> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on destruction + struct shm_remove + { + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Create a shared memory object. + shared_memory_object shm + (create_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + //Set size + shm.truncate(sizeof(shared_data)); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Construct the shared structure in memory + shared_data * data = new (addr) shared_data; + + //Write some logs + for(int i = 0; i < shared_data::NumItems; ++i){ + //Lock the upgradable_mutex + scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex); + std::sprintf(data->items[(data->current_line++) % shared_data::NumItems] + ,"%s_%d", "process_a", i); + if(i == (shared_data::NumItems-1)) + data->end_a = true; + //Mutex is released here + } + + //Wait until the other process ends + while(1){ + scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex); + if(data->end_b) + break; + } + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexB.cpp b/src/boost/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexB.cpp new file mode 100644 index 00000000..61c1b5ab --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexB.cpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> + +//[doc_anonymous_upgradable_mutexB +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <boost/interprocess/sync/scoped_lock.hpp> +#include "doc_upgradable_mutex_shared_data.hpp" +#include <iostream> +#include <cstdio> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on destruction + struct shm_remove + { + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + } remover; + //<- + (void)remover; + //-> + + //Open the shared memory object. + shared_memory_object shm + (open_only //only create + ,"MySharedMemory" //name + ,read_write //read-write mode + ); + + //Map the whole shared memory in this process + mapped_region region + (shm //What to map + ,read_write //Map it as read-write + ); + + //Get the address of the mapped region + void * addr = region.get_address(); + + //Construct the shared structure in memory + shared_data * data = static_cast<shared_data*>(addr); + + //Write some logs + for(int i = 0; i < 100; ++i){ + //Lock the upgradable_mutex + scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex); + std::sprintf(data->items[(data->current_line++) % shared_data::NumItems] + ,"%s_%d", "process_a", i); + if(i == (shared_data::NumItems-1)) + data->end_b = true; + //Mutex is released here + } + + //Wait until the other process ends + while(1){ + scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex); + if(data->end_a) + break; + } + return 0; +} +//] + +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_message_queueA.cpp b/src/boost/libs/interprocess/example/comp_doc_message_queueA.cpp new file mode 100644 index 00000000..66b02363 --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_message_queueA.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_message_queueA +#include <boost/interprocess/ipc/message_queue.hpp> +#include <iostream> +#include <vector> + +using namespace boost::interprocess; + +int main () +{ + try{ + //Erase previous message queue + message_queue::remove("message_queue"); + + //Create a message_queue. + message_queue mq + (create_only //only create + ,"message_queue" //name + ,100 //max message number + ,sizeof(int) //max message size + ); + + //Send 100 numbers + for(int i = 0; i < 100; ++i){ + mq.send(&i, sizeof(i), 0); + } + } + catch(interprocess_exception &ex){ + std::cout << ex.what() << std::endl; + return 1; + } + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/comp_doc_message_queueB.cpp b/src/boost/libs/interprocess/example/comp_doc_message_queueB.cpp new file mode 100644 index 00000000..a3efe293 --- /dev/null +++ b/src/boost/libs/interprocess/example/comp_doc_message_queueB.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_message_queueB +#include <boost/interprocess/ipc/message_queue.hpp> +#include <iostream> +#include <vector> + +using namespace boost::interprocess; + +int main () +{ + try{ + //Open a message queue. + message_queue mq + (open_only //only create + ,"message_queue" //name + ); + + unsigned int priority; + message_queue::size_type recvd_size; + + //Receive 100 numbers + for(int i = 0; i < 100; ++i){ + int number; + mq.receive(&number, sizeof(number), recvd_size, priority); + if(number != i || recvd_size != sizeof(number)) + return 1; + } + } + catch(interprocess_exception &ex){ + message_queue::remove("message_queue"); + std::cout << ex.what() << std::endl; + return 1; + } + message_queue::remove("message_queue"); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_adaptive_pool.cpp b/src/boost/libs/interprocess/example/doc_adaptive_pool.cpp new file mode 100644 index 00000000..9236ae20 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_adaptive_pool.cpp @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_adaptive_pool +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/adaptive_pool.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create a adaptive_pool that allocates ints from the managed segment + //The number of chunks per segment is the default value + typedef adaptive_pool<int, managed_shared_memory::segment_manager> + adaptive_pool_t; + adaptive_pool_t allocator_instance(segment.get_segment_manager()); + + //Create another adaptive_pool. Since the segment manager address + //is the same, this adaptive_pool will be + //attached to the same pool so "allocator_instance2" can deallocate + //nodes allocated by "allocator_instance" + adaptive_pool_t allocator_instance2(segment.get_segment_manager()); + + //Create another adaptive_pool using copy-constructor. This + //adaptive_pool will also be attached to the same pool + adaptive_pool_t allocator_instance3(allocator_instance2); + + //All allocators are equal + assert(allocator_instance == allocator_instance2); + assert(allocator_instance2 == allocator_instance3); + + //So memory allocated with one can be deallocated with another + allocator_instance2.deallocate(allocator_instance.allocate(1), 1); + allocator_instance3.deallocate(allocator_instance2.allocate(1), 1); + + //The common pool will be destroyed here, since no allocator is + //attached to the pool + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_allocator.cpp b/src/boost/libs/interprocess/example/doc_allocator.cpp new file mode 100644 index 00000000..529715f3 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_allocator.cpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_allocator +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create an allocator that allocates ints from the managed segment + allocator<int, managed_shared_memory::segment_manager> + allocator_instance(segment.get_segment_manager()); + + //Copy constructed allocator is equal + allocator<int, managed_shared_memory::segment_manager> + allocator_instance2(allocator_instance); + assert(allocator_instance2 == allocator_instance); + + //Allocate and deallocate memory for 100 ints + allocator_instance2.deallocate(allocator_instance.allocate(100), 100); + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_anonymous_condition_shared_data.hpp b/src/boost/libs/interprocess/example/doc_anonymous_condition_shared_data.hpp new file mode 100644 index 00000000..7cb31047 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_anonymous_condition_shared_data.hpp @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_condition_shared_data +#include <boost/interprocess/sync/interprocess_mutex.hpp> +#include <boost/interprocess/sync/interprocess_condition.hpp> + +struct trace_queue +{ + enum { LineSize = 100 }; + + trace_queue() + : message_in(false) + {} + + //Mutex to protect access to the queue + boost::interprocess::interprocess_mutex mutex; + + //Condition to wait when the queue is empty + boost::interprocess::interprocess_condition cond_empty; + + //Condition to wait when the queue is full + boost::interprocess::interprocess_condition cond_full; + + //Items to fill + char items[LineSize]; + + //Is there any message + bool message_in; +}; +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_anonymous_mutex_shared_data.hpp b/src/boost/libs/interprocess/example/doc_anonymous_mutex_shared_data.hpp new file mode 100644 index 00000000..3884f60c --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_anonymous_mutex_shared_data.hpp @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_mutex_shared_data +#include <boost/interprocess/sync/interprocess_mutex.hpp> + +struct shared_memory_log +{ + enum { NumItems = 100 }; + enum { LineSize = 100 }; + + shared_memory_log() + : current_line(0) + , end_a(false) + , end_b(false) + {} + + //Mutex to protect access to the queue + boost::interprocess::interprocess_mutex mutex; + + //Items to fill + char items[NumItems][LineSize]; + int current_line; + bool end_a; + bool end_b; +}; +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_anonymous_semaphore_shared_data.hpp b/src/boost/libs/interprocess/example/doc_anonymous_semaphore_shared_data.hpp new file mode 100644 index 00000000..65334f52 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_anonymous_semaphore_shared_data.hpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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. +// +////////////////////////////////////////////////////////////////////////////// +//[doc_anonymous_semaphore_shared_data +#include <boost/interprocess/sync/interprocess_semaphore.hpp> + +struct shared_memory_buffer +{ + enum { NumItems = 10 }; + + shared_memory_buffer() + : mutex(1), nempty(NumItems), nstored(0) + {} + + //Semaphores to protect and synchronize access + boost::interprocess::interprocess_semaphore + mutex, nempty, nstored; + + //Items to fill + int items[NumItems]; +}; +//] diff --git a/src/boost/libs/interprocess/example/doc_anonymous_shared_memory.cpp b/src/boost/libs/interprocess/example/doc_anonymous_shared_memory.cpp new file mode 100644 index 00000000..3fb49e1e --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_anonymous_shared_memory.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_anonymous_shared_memory +#include <boost/interprocess/anonymous_shared_memory.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <iostream> +#include <cstring> + +int main () +{ + using namespace boost::interprocess; + try{ + //Create an anonymous shared memory segment with size 1000 + mapped_region region(anonymous_shared_memory(1000)); + + //Write all the memory to 1 + std::memset(region.get_address(), 1, region.get_size()); + + //The segment is unmapped when "region" goes out of scope + } + catch(interprocess_exception &ex){ + std::cout << ex.what() << std::endl; + return 1; + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_bufferstream.cpp b/src/boost/libs/interprocess/example/doc_bufferstream.cpp new file mode 100644 index 00000000..0b51326d --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_bufferstream.cpp @@ -0,0 +1,110 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_bufferstream +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/streams/bufferstream.hpp> +#include <vector> +#include <iterator> +#include <cstddef> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Fill data + std::vector<int> data; + data.reserve(100); + for(int i = 0; i < 100; ++i){ + data.push_back(i); + } + const std::size_t BufferSize = 100*5; + + //Allocate a buffer in shared memory to write data + char *my_cstring = + segment.construct<char>("MyCString")[BufferSize](0); + bufferstream mybufstream(my_cstring, BufferSize); + + //Now write data to the buffer + for(int i = 0; i < 100; ++i){ + mybufstream << data[i] << std::endl; + } + + //Check there was no overflow attempt + assert(mybufstream.good()); + + //Extract all values from the shared memory string + //directly to a vector. + std::vector<int> data2; + std::istream_iterator<int> it(mybufstream), itend; + std::copy(it, itend, std::back_inserter(data2)); + + //This extraction should have ended will fail error since + //the numbers formatted in the buffer end before the end + //of the buffer. (Otherwise it would trigger eofbit) + assert(mybufstream.fail()); + + //Compare data + assert(std::equal(data.begin(), data.end(), data2.begin())); + + //Clear errors and rewind + mybufstream.clear(); + mybufstream.seekp(0, std::ios::beg); + + //Now write again the data trying to do a buffer overflow + for(int i = 0, m = data.size()*5; i < m; ++i){ + mybufstream << data[i%5] << std::endl; + } + + //Now make sure badbit is active + //which means overflow attempt. + assert(!mybufstream.good()); + assert(mybufstream.bad()); + segment.destroy_ptr(my_cstring); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_cached_adaptive_pool.cpp b/src/boost/libs/interprocess/example/doc_cached_adaptive_pool.cpp new file mode 100644 index 00000000..9e92cf52 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_cached_adaptive_pool.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_cached_adaptive_pool +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/cached_adaptive_pool.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create a cached_adaptive_pool that allocates ints from the managed segment + //The number of chunks per segment is the default value + typedef cached_adaptive_pool<int, managed_shared_memory::segment_manager> + cached_adaptive_pool_t; + cached_adaptive_pool_t allocator_instance(segment.get_segment_manager()); + + //The max cached nodes are configurable per instance + allocator_instance.set_max_cached_nodes(3); + + //Create another cached_adaptive_pool. Since the segment manager address + //is the same, this cached_adaptive_pool will be + //attached to the same pool so "allocator_instance2" can deallocate + //nodes allocated by "allocator_instance" + cached_adaptive_pool_t allocator_instance2(segment.get_segment_manager()); + + //The max cached nodes are configurable per instance + allocator_instance2.set_max_cached_nodes(5); + + //Create another cached_adaptive_pool using copy-constructor. This + //cached_adaptive_pool will also be attached to the same pool + cached_adaptive_pool_t allocator_instance3(allocator_instance2); + + //We can clear the cache + allocator_instance3.deallocate_cache(); + + //All allocators are equal + assert(allocator_instance == allocator_instance2); + assert(allocator_instance2 == allocator_instance3); + + //So memory allocated with one can be deallocated with another + allocator_instance2.deallocate(allocator_instance.allocate(1), 1); + allocator_instance3.deallocate(allocator_instance2.allocate(1), 1); + + //The common pool will be destroyed here, since no allocator is + //attached to the pool + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_cached_node_allocator.cpp b/src/boost/libs/interprocess/example/doc_cached_node_allocator.cpp new file mode 100644 index 00000000..a65559b7 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_cached_node_allocator.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_cached_node_allocator +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/cached_node_allocator.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create a cached_node_allocator that allocates ints from the managed segment + //The number of chunks per segment is the default value + typedef cached_node_allocator<int, managed_shared_memory::segment_manager> + cached_node_allocator_t; + cached_node_allocator_t allocator_instance(segment.get_segment_manager()); + + //The max cached nodes are configurable per instance + allocator_instance.set_max_cached_nodes(3); + + //Create another cached_node_allocator. Since the segment manager address + //is the same, this cached_node_allocator will be + //attached to the same pool so "allocator_instance2" can deallocate + //nodes allocated by "allocator_instance" + cached_node_allocator_t allocator_instance2(segment.get_segment_manager()); + + //The max cached nodes are configurable per instance + allocator_instance2.set_max_cached_nodes(5); + + //Create another cached_node_allocator using copy-constructor. This + //cached_node_allocator will also be attached to the same pool + cached_node_allocator_t allocator_instance3(allocator_instance2); + + //We can clear the cache + allocator_instance3.deallocate_cache(); + + //All allocators are equal + assert(allocator_instance == allocator_instance2); + assert(allocator_instance2 == allocator_instance3); + + //So memory allocated with one can be deallocated with another + allocator_instance2.deallocate(allocator_instance.allocate(1), 1); + allocator_instance3.deallocate(allocator_instance2.allocate(1), 1); + + //The common pool will be destroyed here, since no allocator is + //attached to the pool + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_complex_map.cpp b/src/boost/libs/interprocess/example/doc_complex_map.cpp new file mode 100644 index 00000000..63c90b61 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_complex_map.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_complex_map +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <boost/interprocess/containers/map.hpp> +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/containers/string.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +//Typedefs of allocators and containers +typedef managed_shared_memory::segment_manager segment_manager_t; +typedef allocator<void, segment_manager_t> void_allocator; +typedef allocator<int, segment_manager_t> int_allocator; +typedef vector<int, int_allocator> int_vector; +typedef allocator<int_vector, segment_manager_t> int_vector_allocator; +typedef vector<int_vector, int_vector_allocator> int_vector_vector; +typedef allocator<char, segment_manager_t> char_allocator; +typedef basic_string<char, std::char_traits<char>, char_allocator> char_string; + +class complex_data +{ + int id_; + char_string char_string_; + int_vector_vector int_vector_vector_; + + public: + //Since void_allocator is convertible to any other allocator<T>, we can simplify + //the initialization taking just one allocator for all inner containers. + complex_data(int id, const char *name, const void_allocator &void_alloc) + : id_(id), char_string_(name, void_alloc), int_vector_vector_(void_alloc) + {} + //Other members... + //<- + int get_id() { return id_; }; + char_string get_char_string() { return char_string_; }; + int_vector_vector get_int_vector_vector() { return int_vector_vector_; }; + //-> +}; + +//Definition of the map holding a string as key and complex_data as mapped type +typedef std::pair<const char_string, complex_data> map_value_type; +typedef std::pair<char_string, complex_data> movable_to_map_value_type; +typedef allocator<map_value_type, segment_manager_t> map_value_type_allocator; +typedef map< char_string, complex_data + , std::less<char_string>, map_value_type_allocator> complex_map_type; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only,"MySharedMemory", 65536); + //<- + #endif + //-> + + //An allocator convertible to any allocator<T, segment_manager_t> type + void_allocator alloc_inst (segment.get_segment_manager()); + + //Construct the shared memory map and fill it + complex_map_type *mymap = segment.construct<complex_map_type> + //(object name), (first ctor parameter, second ctor parameter) + ("MyMap")(std::less<char_string>(), alloc_inst); + + for(int i = 0; i < 100; ++i){ + //Both key(string) and value(complex_data) need an allocator in their constructors + char_string key_object(alloc_inst); + complex_data mapped_object(i, "default_name", alloc_inst); + map_value_type value(key_object, mapped_object); + //Modify values and insert them in the map + mymap->insert(value); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_cont.cpp b/src/boost/libs/interprocess/example/doc_cont.cpp new file mode 100644 index 00000000..889fc74f --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_cont.cpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_cont +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <boost/interprocess/managed_shared_memory.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main () +{ + using namespace boost::interprocess; + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //A managed shared memory where we can construct objects + //associated with a c-string + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Alias an STL-like allocator of ints that allocates ints from the segment + typedef allocator<int, managed_shared_memory::segment_manager> + ShmemAllocator; + + //Alias a vector that uses the previous STL-like allocator + typedef vector<int, ShmemAllocator> MyVector; + + int initVal[] = {0, 1, 2, 3, 4, 5, 6 }; + const int *begVal = initVal; + const int *endVal = initVal + sizeof(initVal)/sizeof(initVal[0]); + + //Initialize the STL-like allocator + const ShmemAllocator alloc_inst (segment.get_segment_manager()); + + //Construct the vector in the shared memory segment with the STL-like allocator + //from a range of iterators + MyVector *myvector = + segment.construct<MyVector> + ("MyVector")/*object name*/ + (begVal /*first ctor parameter*/, + endVal /*second ctor parameter*/, + alloc_inst /*third ctor parameter*/); + + //Use vector as your want + std::sort(myvector->rbegin(), myvector->rend()); + // . . . + //When done, destroy and delete vector from the segment + segment.destroy<MyVector>("MyVector"); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_file_mapping.cpp b/src/boost/libs/interprocess/example/doc_file_mapping.cpp new file mode 100644 index 00000000..4ae3b8f5 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_file_mapping.cpp @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_file_mapping +#include <boost/interprocess/file_mapping.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <iostream> +#include <fstream> +#include <string> +#include <vector> +#include <cstring> +#include <cstddef> +#include <cstdlib> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main(int argc, char *argv[]) +{ + using namespace boost::interprocess; + + //Define file names + //<- + #if 1 + std::string file_name(boost::interprocess::ipcdetail::get_temporary_path()); + file_name += "/"; file_name += test::get_process_id_name(); + const char *FileName = file_name.c_str(); + #else + //-> + const char *FileName = "file.bin"; + //<- + #endif + //-> + const std::size_t FileSize = 10000; + + if(argc == 1){ //Parent process executes this + { //Create a file + file_mapping::remove(FileName); + std::filebuf fbuf; + fbuf.open(FileName, std::ios_base::in | std::ios_base::out + | std::ios_base::trunc | std::ios_base::binary); + //Set the size + fbuf.pubseekoff(FileSize-1, std::ios_base::beg); + fbuf.sputc(0); + } + + //Remove on exit + struct file_remove + { + file_remove(const char *FileName) + : FileName_(FileName) {} + ~file_remove(){ file_mapping::remove(FileName_); } + const char *FileName_; + } remover(FileName); + + //Create a file mapping + file_mapping m_file(FileName, read_write); + + //Map the whole file with read-write permissions in this process + mapped_region region(m_file, read_write); + + //Get the address of the mapped region + void * addr = region.get_address(); + std::size_t size = region.get_size(); + + //Write all the memory to 1 + std::memset(addr, 1, size); + + //Launch child process + std::string s(argv[0]); s += " child "; + //<- + s += "\""; s+= FileName; s += "\""; + //-> + if(0 != std::system(s.c_str())) + return 1; + } + else{ //Child process executes this + { //Open the file mapping and map it as read-only + //<- + #if 1 + file_mapping m_file(argv[2], read_only); + #else + //-> + file_mapping m_file(FileName, read_only); + //<- + #endif + //-> + + mapped_region region(m_file, read_only); + + //Get the address of the mapped region + void * addr = region.get_address(); + std::size_t size = region.get_size(); + + //Check that memory was initialized to 1 + const char *mem = static_cast<char*>(addr); + for(std::size_t i = 0; i < size; ++i) + if(*mem++ != 1) + return 1; //Error checking memory + } + { //Now test it reading the file + std::filebuf fbuf; + //<- + #if 1 + fbuf.open(argv[2], std::ios_base::in | std::ios_base::binary); + #else + //-> + fbuf.open(FileName, std::ios_base::in | std::ios_base::binary); + //<- + #endif + //-> + + //Read it to memory + std::vector<char> vect(FileSize, 0); + fbuf.sgetn(&vect[0], std::streamsize(vect.size())); + + //Check that memory was initialized to 1 + const char *mem = static_cast<char*>(&vect[0]); + for(std::size_t i = 0; i < FileSize; ++i) + if(*mem++ != 1) + return 1; //Error checking memory + } + } + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_intrusive.cpp b/src/boost/libs/interprocess/example/doc_intrusive.cpp new file mode 100644 index 00000000..d3428554 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_intrusive.cpp @@ -0,0 +1,133 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_intrusive +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/smart_ptr/intrusive_ptr.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +namespace N { + +//A class that has an internal reference count +class reference_counted_class +{ + private: + //Non-copyable + reference_counted_class(const reference_counted_class &); + //Non-assignable + reference_counted_class & operator=(const reference_counted_class &); + //A typedef to save typing + typedef managed_shared_memory::segment_manager segment_manager; + //This is the reference count + unsigned int m_use_count; + //The segment manager allows deletion from shared memory segment + offset_ptr<segment_manager> mp_segment_manager; + + public: + //Constructor + reference_counted_class(segment_manager *s_mngr) + : m_use_count(0), mp_segment_manager(s_mngr){} + //Destructor + ~reference_counted_class(){} + + public: + //Returns the reference count + unsigned int use_count() const + { return m_use_count; } + + //Adds a reference + inline friend void intrusive_ptr_add_ref(reference_counted_class * p) + { ++p->m_use_count; } + + //Releases a reference + inline friend void intrusive_ptr_release(reference_counted_class * p) + { if(--p->m_use_count == 0) p->mp_segment_manager->destroy_ptr(p); } +}; + +} //namespace N { + +//A class that has an intrusive pointer to reference_counted_class +class intrusive_ptr_owner +{ + typedef intrusive_ptr<N::reference_counted_class, + offset_ptr<void> > intrusive_ptr_t; + intrusive_ptr_t m_intrusive_ptr; + + public: + //Takes a pointer to the reference counted class + intrusive_ptr_owner(N::reference_counted_class *ptr) + : m_intrusive_ptr(ptr){} +}; + +int main() +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000); + #else + //-> + managed_shared_memory shmem(create_only, "MySharedMemory", 10000); + //<- + #endif + //-> + + //Create the unique reference counted object in shared memory + N::reference_counted_class *ref_counted = + shmem.construct<N::reference_counted_class> + ("ref_counted")(shmem.get_segment_manager()); + + //Create an array of ten intrusive pointer owners in shared memory + intrusive_ptr_owner *intrusive_owner_array = + shmem.construct<intrusive_ptr_owner> + (anonymous_instance)[10](ref_counted); + + //Now test that reference count is ten + if(ref_counted->use_count() != 10) + return 1; + + //Now destroy the array of intrusive pointer owners + //This should destroy every intrusive_ptr and because of + //that reference_counted_class will be destroyed + shmem.destroy_ptr(intrusive_owner_array); + + //Now the reference counted object should have been destroyed + if(shmem.find<intrusive_ptr_owner>("ref_counted").first) + return 1; + //Success! + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_ipc_message.cpp b/src/boost/libs/interprocess/example/doc_ipc_message.cpp new file mode 100644 index 00000000..9e52e9fb --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_ipc_message.cpp @@ -0,0 +1,106 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_ipc_message +#include <boost/interprocess/managed_shared_memory.hpp> +#include <cstdlib> //std::system +#include <sstream> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main (int argc, char *argv[]) +{ + using namespace boost::interprocess; + if(argc == 1){ //Parent process + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create a managed shared memory segment + //<- + #if 1 + managed_shared_memory segment(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, "MySharedMemory", 65536); + //<- + #endif + //-> + + //Allocate a portion of the segment (raw memory) + managed_shared_memory::size_type free_memory = segment.get_free_memory(); + void * shptr = segment.allocate(1024/*bytes to allocate*/); + + //Check invariant + if(free_memory <= segment.get_free_memory()) + return 1; + + //An handle from the base address can identify any byte of the shared + //memory segment even if it is mapped in different base addresses + managed_shared_memory::handle_t handle = segment.get_handle_from_address(shptr); + std::stringstream s; + s << argv[0] << " " << handle; + //<- + s << " " << test::get_process_id_name(); + //-> + s << std::ends; + //Launch child process + if(0 != std::system(s.str().c_str())) + return 1; + //Check memory has been freed + if(free_memory != segment.get_free_memory()) + return 1; + } + else{ + //Open managed segment + //<- + #if 1 + managed_shared_memory segment(open_only, argv[2]); + #else + //-> + managed_shared_memory segment(open_only, "MySharedMemory"); + //<- + #endif + //-> + + //An handle from the base address can identify any byte of the shared + //memory segment even if it is mapped in different base addresses + managed_shared_memory::handle_t handle = 0; + + //Obtain handle value + std::stringstream s; s << argv[1]; s >> handle; + + //Get buffer local address from handle + void *msg = segment.get_address_from_handle(handle); + + //Deallocate previously allocated memory + segment.deallocate(msg); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_aligned_allocation.cpp b/src/boost/libs/interprocess/example/doc_managed_aligned_allocation.cpp new file mode 100644 index 00000000..167f20e0 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_aligned_allocation.cpp @@ -0,0 +1,118 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_managed_aligned_allocation +#include <boost/interprocess/managed_shared_memory.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main() +{ + using namespace boost::interprocess; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Managed memory segment that allocates portions of a shared memory + //segment with the default management algorithm + //<- + #if 1 + managed_shared_memory managed_shm(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory managed_shm(create_only, "MySharedMemory", 65536); + //<- + #endif + //-> + + const std::size_t Alignment = 128; + + //Allocate 100 bytes aligned to Alignment from segment, throwing version + void *ptr = managed_shm.allocate_aligned(100, Alignment); + + //Check alignment + assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0); + + //Deallocate it + managed_shm.deallocate(ptr); + + //Non throwing version + ptr = managed_shm.allocate_aligned(100, Alignment, std::nothrow); + + //Check alignment + assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0); + + //Deallocate it + managed_shm.deallocate(ptr); + + //If we want to efficiently allocate aligned blocks of memory + //use managed_shared_memory::PayloadPerAllocation value + assert(Alignment > managed_shared_memory::PayloadPerAllocation); + + //This allocation will maximize the size of the aligned memory + //and will increase the possibility of finding more aligned memory + ptr = managed_shm.allocate_aligned + (3*Alignment - managed_shared_memory::PayloadPerAllocation, Alignment); + + //Check alignment + assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0); + + //Deallocate it + managed_shm.deallocate(ptr); + + return 0; +} +//] +/* + +#include <vector> +#include <boost/interprocess/managed_windows_shared_memory.hpp> + +int main() +{ + using namespace boost::interprocess; + typedef boost::interprocess:: + managed_windows_shared_memory shared_segment; + + std::vector<void *> ptrs; + shared_segment m_segment(create_only, "shmem", 4096*16); + try{ + while(1){ + //Now I have several allocate_aligned operations: + ptrs.push_back(m_segment.allocate_aligned(128, 128)); + } + } + catch(...){ + m_segment.deallocate(ptrs.back()); + ptrs.pop_back(); + ptrs.push_back(m_segment.allocate_aligned(128, 128)); + } + return 0; +} +*/ +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_allocation_command.cpp b/src/boost/libs/interprocess/example/doc_managed_allocation_command.cpp new file mode 100644 index 00000000..e1e0cf40 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_allocation_command.cpp @@ -0,0 +1,124 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_managed_allocation_command +#include <boost/interprocess/managed_shared_memory.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main() +{ + using namespace boost::interprocess; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Managed memory segment that allocates portions of a shared memory + //segment with the default management algorithm + //<- + #if 1 + managed_shared_memory managed_shm(create_only, test::get_process_id_name(), 10000*sizeof(std::size_t)); + #else + //-> + managed_shared_memory managed_shm(create_only, "MySharedMemory", 10000*sizeof(std::size_t)); + //<- + #endif + //-> + + //Allocate at least 100 bytes, 1000 bytes if possible + managed_shared_memory::size_type min_size = 100; + managed_shared_memory::size_type first_received_size = 1000; + std::size_t *hint = 0; + std::size_t *ptr = managed_shm.allocation_command<std::size_t> + (boost::interprocess::allocate_new, min_size, first_received_size, hint); + + //Received size must be bigger than min_size + assert(first_received_size >= min_size); + + //Get free memory + managed_shared_memory::size_type free_memory_after_allocation = managed_shm.get_free_memory(); + //<- + (void)free_memory_after_allocation; + //-> + + //Now write the data + for(std::size_t i = 0; i < first_received_size; ++i) ptr[i] = i; + + //Now try to triplicate the buffer. We won't admit an expansion + //lower to the double of the original buffer. + //This "should" be successful since no other class is allocating + //memory from the segment + min_size = first_received_size*2; + managed_shared_memory::size_type expanded_size = first_received_size*3; + std::size_t * ret = managed_shm.allocation_command + (boost::interprocess::expand_fwd, min_size, expanded_size, ptr); + //<- + (void)ret; + //-> + //Check invariants + assert(ptr != 0); + assert(ret == ptr); + assert(expanded_size >= first_received_size*2); + + //Get free memory and compare + managed_shared_memory::size_type free_memory_after_expansion = managed_shm.get_free_memory(); + assert(free_memory_after_expansion < free_memory_after_allocation); + //<- + (void)free_memory_after_expansion; + //-> + + //Write new values + for(std::size_t i = first_received_size; i < expanded_size; ++i) ptr[i] = i; + + //Try to shrink approximately to min_size, but the new size + //should be smaller than min_size*2. + //This "should" be successful since no other class is allocating + //memory from the segment + managed_shared_memory::size_type shrunk_size = min_size; + ret = managed_shm.allocation_command + (boost::interprocess::shrink_in_place, min_size*2, shrunk_size, ptr); + + //Check invariants + assert(ptr != 0); + assert(ret == ptr); + assert(shrunk_size <= min_size*2); + assert(shrunk_size >= min_size); + + //Get free memory and compare + managed_shared_memory::size_type free_memory_after_shrinking = managed_shm.get_free_memory(); + assert(free_memory_after_shrinking > free_memory_after_expansion); + //<- + (void)free_memory_after_shrinking; + //-> + + //Deallocate the buffer + managed_shm.deallocate(ptr); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_construction_info.cpp b/src/boost/libs/interprocess/example/doc_managed_construction_info.cpp new file mode 100644 index 00000000..b267e972 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_construction_info.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_managed_construction_info +#include <boost/interprocess/managed_shared_memory.hpp> +#include <cassert> +#include <cstring> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +class my_class +{ + //... +}; + +int main() +{ + using namespace boost::interprocess; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory managed_shm(create_only, test::get_process_id_name(), 10000*sizeof(std::size_t)); + #else + //-> + managed_shared_memory managed_shm(create_only, "MySharedMemory", 10000*sizeof(std::size_t)); + //<- + #endif + //-> + + //Construct objects + my_class *named_object = managed_shm.construct<my_class>("Object name")[1](); + my_class *unique_object = managed_shm.construct<my_class>(unique_instance)[2](); + my_class *anon_object = managed_shm.construct<my_class>(anonymous_instance)[3](); + + //Now test "get_instance_name" function. + assert(0 == std::strcmp(managed_shared_memory::get_instance_name(named_object), "Object name")); + assert(0 == std::strcmp(managed_shared_memory::get_instance_name(unique_object), typeid(my_class).name())); + assert(0 == managed_shared_memory::get_instance_name(anon_object)); + + //Now test "get_instance_type" function. + assert(named_type == managed_shared_memory::get_instance_type(named_object)); + assert(unique_type == managed_shared_memory::get_instance_type(unique_object)); + assert(anonymous_type == managed_shared_memory::get_instance_type(anon_object)); + + //Now test "get_instance_length" function. + assert(1 == managed_shared_memory::get_instance_length(named_object)); + assert(2 == managed_shared_memory::get_instance_length(unique_object)); + assert(3 == managed_shared_memory::get_instance_length(anon_object)); + + managed_shm.destroy_ptr(named_object); + managed_shm.destroy_ptr(unique_object); + managed_shm.destroy_ptr(anon_object); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_copy_on_write.cpp b/src/boost/libs/interprocess/example/doc_managed_copy_on_write.cpp new file mode 100644 index 00000000..239f0323 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_copy_on_write.cpp @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/os_file_functions.hpp> +//[doc_managed_copy_on_write +#include <boost/interprocess/managed_mapped_file.hpp> +#include <fstream> //std::fstream +#include <iterator>//std::distance + +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main() +{ + using namespace boost::interprocess; + + //Define file names + //<- + #if 1 + const char *ManagedFile = 0; + const char *ManagedFile2 = 0; + std::string managed_file_name(boost::interprocess::ipcdetail::get_temporary_path()); + managed_file_name += "/"; managed_file_name += test::get_process_id_name(); + ManagedFile = managed_file_name.c_str(); + std::string managed_file2_name(boost::interprocess::ipcdetail::get_temporary_path()); + managed_file2_name += "/"; managed_file2_name += test::get_process_id_name(); managed_file2_name += "_2"; + ManagedFile2 = managed_file2_name.c_str(); + #else + //-> + const char *ManagedFile = "MyManagedFile"; + const char *ManagedFile2 = "MyManagedFile2"; + //<- + #endif + //-> + + //Try to erase any previous managed segment with the same name + file_mapping::remove(ManagedFile); + file_mapping::remove(ManagedFile2); + remove_file_on_destroy destroyer1(ManagedFile); + remove_file_on_destroy destroyer2(ManagedFile2); + + { + //Create an named integer in a managed mapped file + managed_mapped_file managed_file(create_only, ManagedFile, 65536); + managed_file.construct<int>("MyInt")(0u); + + //Now create a copy on write version + managed_mapped_file managed_file_cow(open_copy_on_write, ManagedFile); + + //Erase the int and create a new one + if(!managed_file_cow.destroy<int>("MyInt")) + throw int(0); + managed_file_cow.construct<int>("MyInt2"); + + //Check changes + if(managed_file_cow.find<int>("MyInt").first && !managed_file_cow.find<int>("MyInt2").first) + throw int(0); + + //Check the original is intact + if(!managed_file.find<int>("MyInt").first && managed_file.find<int>("MyInt2").first) + throw int(0); + + { //Dump the modified copy on write segment to a file + std::fstream file(ManagedFile2, std::ios_base::out | std::ios_base::binary); + if(!file) + throw int(0); + file.write(static_cast<const char *>(managed_file_cow.get_address()), (std::streamsize)managed_file_cow.get_size()); + } + + //Now open the modified file and test changes + managed_mapped_file managed_file_cow2(open_only, ManagedFile2); + if(managed_file_cow2.find<int>("MyInt").first && !managed_file_cow2.find<int>("MyInt2").first) + throw int(0); + } + { + //Now create a read-only version + managed_mapped_file managed_file_ro(open_read_only, ManagedFile); + + //Check the original is intact + if(!managed_file_ro.find<int>("MyInt").first && managed_file_ro.find<int>("MyInt2").first) + throw int(0); + + //Check the number of named objects using the iterators + if(std::distance(managed_file_ro.named_begin(), managed_file_ro.named_end()) != 1 && + std::distance(managed_file_ro.unique_begin(), managed_file_ro.unique_end()) != 0 ) + throw int(0); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_external_buffer.cpp b/src/boost/libs/interprocess/example/doc_managed_external_buffer.cpp new file mode 100644 index 00000000..f9d4b583 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_external_buffer.cpp @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_managed_external_buffer +#include <boost/interprocess/managed_external_buffer.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <boost/interprocess/containers/list.hpp> +#include <cstring> +#include <boost/aligned_storage.hpp> + +int main() +{ + using namespace boost::interprocess; + + //Create the static memory who will store all objects + const int memsize = 65536; + + static boost::aligned_storage<memsize>::type static_buffer; + + //This managed memory will construct objects associated with + //a wide string in the static buffer + wmanaged_external_buffer objects_in_static_memory + (create_only, &static_buffer, memsize); + + //We optimize resources to create 100 named objects in the static buffer + objects_in_static_memory.reserve_named_objects(100); + + //Alias an integer node allocator type + //This allocator will allocate memory inside the static buffer + typedef allocator<int, wmanaged_external_buffer::segment_manager> + allocator_t; + + //Alias a STL compatible list to be constructed in the static buffer + typedef list<int, allocator_t> MyBufferList; + + //The list must be initialized with the allocator + //All objects created with objects_in_static_memory will + //be stored in the static_buffer! + MyBufferList *list = objects_in_static_memory.construct<MyBufferList>(L"MyList") + (objects_in_static_memory.get_segment_manager()); + //<- + (void)list; + //-> + //Since the allocation algorithm from wmanaged_external_buffer uses relative + //pointers and all the pointers constructed int the static memory point + //to objects in the same segment, we can create another static buffer + //from the first one and duplicate all the data. + static boost::aligned_storage<memsize>::type static_buffer2; + std::memcpy(&static_buffer2, &static_buffer, memsize); + + //Now open the duplicated managed memory passing the memory as argument + wmanaged_external_buffer objects_in_static_memory2 + (open_only, &static_buffer2, memsize); + + //Check that "MyList" has been duplicated in the second buffer + if(!objects_in_static_memory2.find<MyBufferList>(L"MyList").first) + return 1; + + //Destroy the lists from the static buffers + objects_in_static_memory.destroy<MyBufferList>(L"MyList"); + objects_in_static_memory2.destroy<MyBufferList>(L"MyList"); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_grow.cpp b/src/boost/libs/interprocess/example/doc_managed_grow.cpp new file mode 100644 index 00000000..bc3062c0 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_grow.cpp @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_managed_grow +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/managed_mapped_file.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +class MyClass +{ + //... +}; + +int main() +{ + using namespace boost::interprocess; + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + { + //Create a managed shared memory + //<- + #if 1 + managed_shared_memory shm(create_only, test::get_process_id_name(), 1000); + #else + //-> + managed_shared_memory shm(create_only, "MySharedMemory", 1000); + //<- + #endif + //-> + + //Check size + assert(shm.get_size() == 1000); + //Construct a named object + MyClass *myclass = shm.construct<MyClass>("MyClass")(); + //The managed segment is unmapped here + //<- + (void)myclass; + //-> + } + { + //Now that the segment is not mapped grow it adding extra 500 bytes + //<- + #if 1 + managed_shared_memory::grow(test::get_process_id_name(), 500); + #else + //-> + managed_shared_memory::grow("MySharedMemory", 500); + //<- + #endif + //-> + + //Map it again + //<- + #if 1 + managed_shared_memory shm(open_only, test::get_process_id_name()); + #else + //-> + managed_shared_memory shm(open_only, "MySharedMemory"); + //<- + #endif + //-> + //Check size + assert(shm.get_size() == 1500); + //Check "MyClass" is still there + MyClass *myclass = shm.find<MyClass>("MyClass").first; + assert(myclass != 0); + //<- + (void)myclass; + //-> + //The managed segment is unmapped here + } + { + //Now minimize the size of the segment + //<- + #if 1 + managed_shared_memory::shrink_to_fit(test::get_process_id_name()); + #else + //-> + managed_shared_memory::shrink_to_fit("MySharedMemory"); + //<- + #endif + //-> + + //Map it again + //<- + #if 1 + managed_shared_memory shm(open_only, test::get_process_id_name()); + #else + //-> + managed_shared_memory shm(open_only, "MySharedMemory"); + //<- + #endif + //-> + //Check size + assert(shm.get_size() < 1000); + //Check "MyClass" is still there + MyClass *myclass = shm.find<MyClass>("MyClass").first; + assert(myclass != 0); + //The managed segment is unmapped here + //<- + (void)myclass; + //-> + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_heap_memory.cpp b/src/boost/libs/interprocess/example/doc_managed_heap_memory.cpp new file mode 100644 index 00000000..da7c6773 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_heap_memory.cpp @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_managed_heap_memory +#include <boost/interprocess/containers/list.hpp> +#include <boost/interprocess/managed_heap_memory.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <cstddef> + +using namespace boost::interprocess; +typedef list<int, allocator<int, managed_heap_memory::segment_manager> > + MyList; + +int main () +{ + //We will create a buffer of 1000 bytes to store a list + managed_heap_memory heap_memory(1000); + + MyList * mylist = heap_memory.construct<MyList>("MyList") + (heap_memory.get_segment_manager()); + + //Obtain handle, that identifies the list in the buffer + managed_heap_memory::handle_t list_handle = heap_memory.get_handle_from_address(mylist); + + //Fill list until there is no more memory in the buffer + try{ + while(1) { + mylist->insert(mylist->begin(), 0); + } + } + catch(const bad_alloc &){ + //memory is full + } + //Let's obtain the size of the list + MyList::size_type old_size = mylist->size(); + //<- + (void)old_size; + //-> + + //To make the list bigger, let's increase the heap buffer + //in 1000 bytes more. + heap_memory.grow(1000); + + //If memory has been reallocated, the old pointer is invalid, so + //use previously obtained handle to find the new pointer. + mylist = static_cast<MyList *> + (heap_memory.get_address_from_handle(list_handle)); + + //Fill list until there is no more memory in the buffer + try{ + while(1) { + mylist->insert(mylist->begin(), 0); + } + } + catch(const bad_alloc &){ + //memory is full + } + + //Let's obtain the new size of the list + MyList::size_type new_size = mylist->size(); + //<- + (void)new_size; + //-> + + assert(new_size > old_size); + + //Destroy list + heap_memory.destroy_ptr(mylist); + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_managed_mapped_file.cpp b/src/boost/libs/interprocess/example/doc_managed_mapped_file.cpp new file mode 100644 index 00000000..2b59626f --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_mapped_file.cpp @@ -0,0 +1,117 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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. +// +////////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_INTERPROCESS_MAPPED_FILES) + +#include <boost/interprocess/detail/config_begin.hpp> +#include <boost/interprocess/detail/workaround.hpp> + +#include <boost/interprocess/containers/list.hpp> +#include <boost/interprocess/managed_mapped_file.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <cstddef> +#include <cstdio> + +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; +typedef list<int, allocator<int, managed_mapped_file::segment_manager> > + MyList; + +int main () +{ + //Define file names + //<- + #if 1 + std::string file(boost::interprocess::ipcdetail::get_temporary_path()); + file += "/"; file += test::get_process_id_name(); + const char *FileName = file.c_str(); + #else + //-> + const char *FileName = "file_mapping"; + //<- + #endif + //-> + + const std::size_t FileSize = 1000; + file_mapping::remove(FileName); + + try{ + MyList::size_type old_size = 0; + managed_mapped_file::handle_t list_handle; + { + managed_mapped_file mfile_memory(create_only, FileName, FileSize); + MyList *mylist = mfile_memory.construct<MyList>("MyList") + (mfile_memory.get_segment_manager()); + + //Obtain handle, that identifies the list in the buffer + list_handle = mfile_memory.get_handle_from_address(mylist); + + //Fill list until there is no more room in the file + try{ + while(1) { + mylist->insert(mylist->begin(), 0); + } + } + catch(const bad_alloc &){ + //mapped file is full + } + //Let's obtain the size of the list + old_size = mylist->size(); + } + //To make the list bigger, let's increase the mapped file + //in FileSize bytes more. + managed_mapped_file::grow(FileName, FileSize*2); + + { + managed_mapped_file mfile_memory(open_only, FileName); + + + //If mapping address has changed, the old pointer is invalid, + //so use previously obtained handle to find the new pointer. + MyList *mylist = static_cast<MyList *> + (mfile_memory.get_address_from_handle(list_handle)); + + //Fill list until there is no more room in the file + try{ + while(1) { + mylist->insert(mylist->begin(), 0); + } + } + catch(const bad_alloc &){ + //mapped file is full + } + + //Let's obtain the new size of the list + MyList::size_type new_size = mylist->size(); + + assert(new_size > old_size); + + //Destroy list + mfile_memory.destroy_ptr(mylist); + } + } + catch(...){ + file_mapping::remove(FileName); + throw; + } + file_mapping::remove(FileName); + return 0; +} + +#include <boost/interprocess/detail/config_end.hpp> + +#else //#if defined(BOOST_INTERPROCESS_MAPPED_FILES) +int main() +{ + return 0; +} +#endif//#if defined(BOOST_INTERPROCESS_MAPPED_FILES) diff --git a/src/boost/libs/interprocess/example/doc_managed_multiple_allocation.cpp b/src/boost/libs/interprocess/example/doc_managed_multiple_allocation.cpp new file mode 100644 index 00000000..97835c56 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_multiple_allocation.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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. +// +////////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_INTERPROCESS_MAPPED_FILES) + +#include <boost/interprocess/detail/config_begin.hpp> +//[doc_managed_multiple_allocation +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/move/utility_core.hpp> //boost::move +#include <cassert>//assert +#include <cstring>//std::memset +#include <new> //std::nothrow +#include <vector> //std::vector +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main() +{ + using namespace boost::interprocess; + typedef managed_shared_memory::multiallocation_chain multiallocation_chain; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory managed_shm(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory managed_shm(create_only,"MySharedMemory", 65536); + //<- + #endif + //-> + + //Allocate 16 elements of 100 bytes in a single call. Non-throwing version. + multiallocation_chain chain; + managed_shm.allocate_many(std::nothrow, 100, 16, chain); + + //Check if the memory allocation was successful + if(chain.empty()) return 1; + + //Allocated buffers + std::vector<void*> allocated_buffers; + + //Initialize our data + while(!chain.empty()){ + void *buf = chain.pop_front(); + allocated_buffers.push_back(buf); + //The iterator must be incremented before overwriting memory + //because otherwise, the iterator is invalidated. + std::memset(buf, 0, 100); + } + + //Now deallocate + while(!allocated_buffers.empty()){ + managed_shm.deallocate(allocated_buffers.back()); + allocated_buffers.pop_back(); + } + + //Allocate 10 buffers of different sizes in a single call. Throwing version + managed_shared_memory::size_type sizes[10]; + for(std::size_t i = 0; i < 10; ++i) + sizes[i] = i*3; + + managed_shm.allocate_many(sizes, 10, 1, chain); + managed_shm.deallocate_many(chain); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> + +#else //#if defined(BOOST_INTERPROCESS_MAPPED_FILES) +int main() +{ + return 0; +} +#endif//#if defined(BOOST_INTERPROCESS_MAPPED_FILES) diff --git a/src/boost/libs/interprocess/example/doc_managed_raw_allocation.cpp b/src/boost/libs/interprocess/example/doc_managed_raw_allocation.cpp new file mode 100644 index 00000000..2ddc9974 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_managed_raw_allocation.cpp @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_managed_raw_allocation +#include <boost/interprocess/managed_shared_memory.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main() +{ + using namespace boost::interprocess; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Managed memory segment that allocates portions of a shared memory + //segment with the default management algorithm + //<- + #if 1 + managed_shared_memory managed_shm(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory managed_shm(create_only,"MySharedMemory", 65536); + //<- + #endif + //-> + + //Allocate 100 bytes of memory from segment, throwing version + void *ptr = managed_shm.allocate(100); + + //Deallocate it + managed_shm.deallocate(ptr); + + //Non throwing version + ptr = managed_shm.allocate(100, std::nothrow); + + //Deallocate it + managed_shm.deallocate(ptr); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_map.cpp b/src/boost/libs/interprocess/example/doc_map.cpp new file mode 100644 index 00000000..929e7bbd --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_map.cpp @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_map +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/containers/map.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <functional> +#include <utility> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main () +{ + using namespace boost::interprocess; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Shared memory front-end that is able to construct objects + //associated with a c-string. Erase previous shared memory with the name + //to be used and create the memory segment at the specified address and initialize resources + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment + (create_only + ,"MySharedMemory" //segment name + ,65536); //segment size in bytes + //<- + #endif + //-> + + //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>, + //so the allocator must allocate that pair. + typedef int KeyType; + typedef float MappedType; + typedef std::pair<const int, float> ValueType; + + //Alias an STL compatible allocator of for the map. + //This allocator will allow to place containers + //in managed shared memory segments + typedef allocator<ValueType, managed_shared_memory::segment_manager> + ShmemAllocator; + + //Alias a map of ints that uses the previous STL-like allocator. + //Note that the third parameter argument is the ordering function + //of the map, just like with std::map, used to compare the keys. + typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap; + + //Initialize the shared memory STL-compatible allocator + ShmemAllocator alloc_inst (segment.get_segment_manager()); + + //Construct a shared memory map. + //Note that the first parameter is the comparison function, + //and the second one the allocator. + //This the same signature as std::map's constructor taking an allocator + MyMap *mymap = + segment.construct<MyMap>("MyMap") //object name + (std::less<int>() //first ctor parameter + ,alloc_inst); //second ctor parameter + + //Insert data in the map + for(int i = 0; i < 100; ++i){ + mymap->insert(std::pair<const int, float>(i, (float)i)); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_move_containers.cpp b/src/boost/libs/interprocess/example/doc_move_containers.cpp new file mode 100644 index 00000000..46438f59 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_move_containers.cpp @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_move_containers +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/containers/string.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main () +{ + using namespace boost::interprocess; + + //Typedefs + typedef managed_shared_memory::segment_manager SegmentManager; + typedef allocator<char, SegmentManager> CharAllocator; + typedef basic_string<char, std::char_traits<char> + ,CharAllocator> MyShmString; + typedef allocator<MyShmString, SegmentManager> StringAllocator; + typedef vector<MyShmString, StringAllocator> MyShmStringVector; + + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory shm(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory shm(create_only, "MySharedMemory", 10000); + //<- + #endif + //-> + + //Create allocators + CharAllocator charallocator (shm.get_segment_manager()); + StringAllocator stringallocator(shm.get_segment_manager()); + + //Create a vector of strings in shared memory. + MyShmStringVector *myshmvector = + shm.construct<MyShmStringVector>("myshmvector")(stringallocator); + + //Insert 50 strings in shared memory. The strings will be allocated + //only once and no string copy-constructor will be called when inserting + //strings, leading to a great performance. + MyShmString string_to_compare(charallocator); + string_to_compare = "this is a long, long, long, long, long, long, string..."; + + myshmvector->reserve(50); + for(int i = 0; i < 50; ++i){ + MyShmString move_me(string_to_compare); + //In the following line, no string copy-constructor will be called. + //"move_me"'s contents will be transferred to the string created in + //the vector + myshmvector->push_back(boost::move(move_me)); + + //The source string is in default constructed state + assert(move_me.empty()); + + //The newly created string will be equal to the "move_me"'s old contents + assert(myshmvector->back() == string_to_compare); + } + + //Now erase a string... + myshmvector->pop_back(); + + //...And insert one in the first position. + //No string copy-constructor or assignments will be called, but + //move constructors and move-assignments. No memory allocation + //function will be called in this operations!! + myshmvector->insert(myshmvector->begin(), boost::move(string_to_compare)); + + //Destroy vector. This will free all strings that the vector contains + shm.destroy_ptr(myshmvector); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> + diff --git a/src/boost/libs/interprocess/example/doc_multi_index.cpp b/src/boost/libs/interprocess/example/doc_multi_index.cpp new file mode 100644 index 00000000..df4fd720 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_multi_index.cpp @@ -0,0 +1,118 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_multi_index +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <boost/interprocess/containers/string.hpp> + +//<- +//Shield against external warnings +#include <boost/interprocess/detail/config_external_begin.hpp> +//-> + +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/member.hpp> +#include <boost/multi_index/ordered_index.hpp> + +//<- +#include <boost/interprocess/detail/config_external_end.hpp> +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; +namespace bmi = boost::multi_index; + +typedef managed_shared_memory::allocator<char>::type char_allocator; +typedef basic_string<char, std::char_traits<char>, char_allocator>shm_string; + +//Data to insert in shared memory +struct employee +{ + int id; + int age; + shm_string name; + employee( int id_ + , int age_ + , const char *name_ + , const char_allocator &a) + : id(id_), age(age_), name(name_, a) + {} +}; + +//Tags +struct id{}; +struct age{}; +struct name{}; + +// Define a multi_index_container of employees with following indices: +// - a unique index sorted by employee::int, +// - a non-unique index sorted by employee::name, +// - a non-unique index sorted by employee::age. +typedef bmi::multi_index_container< + employee, + bmi::indexed_by< + bmi::ordered_unique + <bmi::tag<id>, bmi::member<employee,int,&employee::id> >, + bmi::ordered_non_unique< + bmi::tag<name>, bmi::member<employee,shm_string,&employee::name> >, + bmi::ordered_non_unique + <bmi::tag<age>, bmi::member<employee,int,&employee::age> > >, + managed_shared_memory::allocator<employee>::type +> employee_set; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only,test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only,"MySharedMemory", 65536); + //<- + #endif + //-> + + //Construct the multi_index in shared memory + employee_set *es = segment.construct<employee_set> + ("My MultiIndex Container") //Container's name in shared memory + ( employee_set::ctor_args_list() + , segment.get_allocator<employee>()); //Ctor parameters + + //Now insert elements + char_allocator ca(segment.get_allocator<char>()); + es->insert(employee(0,31, "Joe", ca)); + es->insert(employee(1,27, "Robert", ca)); + es->insert(employee(2,40, "John", ca)); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_named_alloc.cpp b/src/boost/libs/interprocess/example/doc_named_alloc.cpp new file mode 100644 index 00000000..99ffbcc2 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_named_alloc.cpp @@ -0,0 +1,137 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_named_alloc +#include <boost/interprocess/managed_shared_memory.hpp> +#include <cstdlib> //std::system +#include <cstddef> +#include <cassert> +#include <utility> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main(int argc, char *argv[]) +{ + using namespace boost::interprocess; + typedef std::pair<double, int> MyType; + + if(argc == 1){ //Parent process + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Construct managed shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, "MySharedMemory", 65536); + //<- + #endif + //-> + + //Create an object of MyType initialized to {0.0, 0} + MyType *instance = segment.construct<MyType> + ("MyType instance") //name of the object + (0.0, 0); //ctor first argument + + //Create an array of 10 elements of MyType initialized to {0.0, 0} + MyType *array = segment.construct<MyType> + ("MyType array") //name of the object + [10] //number of elements + (0.0, 0); //Same two ctor arguments for all objects + + //Create an array of 3 elements of MyType initializing each one + //to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}... + float float_initializer[3] = { 0.0, 1.0, 2.0 }; + int int_initializer[3] = { 0, 1, 2 }; + + MyType *array_it = segment.construct_it<MyType> + ("MyType array from it") //name of the object + [3] //number of elements + ( &float_initializer[0] //Iterator for the 1st ctor argument + , &int_initializer[0]); //Iterator for the 2nd ctor argument + + //Launch child process + std::string s(argv[0]); s += " child "; + //<- + s += test::get_process_id_name(); + //-> + if(0 != std::system(s.c_str())) + return 1; + + //<- + (void)instance; + (void)array; + (void)array_it; + //-> + + //Check child has destroyed all objects + if(segment.find<MyType>("MyType array").first || + segment.find<MyType>("MyType instance").first || + segment.find<MyType>("MyType array from it").first) + return 1; + } + else{ + //Open managed shared memory + //<- + #if 1 + managed_shared_memory segment(open_only, argv[2]); + #else + //-> + managed_shared_memory segment(open_only, "MySharedMemory"); + //<- + #endif + //-> + + std::pair<MyType*, managed_shared_memory::size_type> res; + + //Find the array + res = segment.find<MyType> ("MyType array"); + //Length should be 10 + if(res.second != 10) return 1; + + //Find the object + res = segment.find<MyType> ("MyType instance"); + //Length should be 1 + if(res.second != 1) return 1; + + //Find the array constructed from iterators + res = segment.find<MyType> ("MyType array from it"); + //Length should be 3 + if(res.second != 3) return 1; + + //We're done, delete all the objects + segment.destroy<MyType>("MyType array"); + segment.destroy<MyType>("MyType instance"); + segment.destroy<MyType>("MyType array from it"); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_named_condition_shared_data.hpp b/src/boost/libs/interprocess/example/doc_named_condition_shared_data.hpp new file mode 100644 index 00000000..ae94db6c --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_named_condition_shared_data.hpp @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/sync/interprocess_mutex.hpp> + #include <boost/interprocess/sync/interprocess_condition.hpp> + + struct trace_queue + { + enum { LineSize = 100 }; + + trace_queue() + : message_in(false) + {} + + //Mutex to protect access to the queue + boost::interprocess::interprocess_mutex mutex; + + //Condition to wait when the queue is empty + boost::interprocess::interprocess_condition cond_empty; + + //Condition to wait when the queue is full + boost::interprocess::interprocess_condition cond_full; + + //Items to fill + char items[LineSize]; + + //Is there any message + bool message_in; + }; diff --git a/src/boost/libs/interprocess/example/doc_named_mutex.cpp b/src/boost/libs/interprocess/example/doc_named_mutex.cpp new file mode 100644 index 00000000..98f5b379 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_named_mutex.cpp @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_named_mutex +#include <boost/interprocess/sync/scoped_lock.hpp> +#include <boost/interprocess/sync/named_mutex.hpp> +#include <fstream> +#include <iostream> +#include <cstdio> + +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main () +{ + using namespace boost::interprocess; + try{ + struct file_remove + { + //<- + #if 1 + file_remove() { std::remove(test::get_process_id_name()); } + ~file_remove(){ std::remove(test::get_process_id_name()); } + #else + //-> + file_remove() { std::remove("file_name"); } + ~file_remove(){ std::remove("file_name"); } + //<- + #endif + //-> + } file_remover; + struct mutex_remove + { + //<- + #if 1 + mutex_remove() { named_mutex::remove(test::get_process_id_name()); } + ~mutex_remove(){ named_mutex::remove(test::get_process_id_name()); } + #else + //-> + mutex_remove() { named_mutex::remove("fstream_named_mutex"); } + ~mutex_remove(){ named_mutex::remove("fstream_named_mutex"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Open or create the named mutex + //<- + #if 1 + named_mutex mutex(open_or_create, test::get_process_id_name()); + #else + //-> + named_mutex mutex(open_or_create, "fstream_named_mutex"); + //<- + #endif + //-> + + //<- + #if 1 + std::ofstream file(test::get_process_id_name()); + #else + //-> + std::ofstream file("file_name"); + //<- + #endif + //-> + + for(int i = 0; i < 10; ++i){ + + //Do some operations... + + //Write to file atomically + scoped_lock<named_mutex> lock(mutex); + file << "Process name, "; + file << "This is iteration #" << i; + file << std::endl; + } + } + catch(interprocess_exception &ex){ + std::cout << ex.what() << std::endl; + return 1; + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_node_allocator.cpp b/src/boost/libs/interprocess/example/doc_node_allocator.cpp new file mode 100644 index 00000000..dcedab49 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_node_allocator.cpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_node_allocator +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/node_allocator.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, + test::get_process_id_name(), //segment name + 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create a node_allocator that allocates ints from the managed segment + //The number of chunks per segment is the default value + typedef node_allocator<int, managed_shared_memory::segment_manager> + node_allocator_t; + node_allocator_t allocator_instance(segment.get_segment_manager()); + + //Create another node_allocator. Since the segment manager address + //is the same, this node_allocator will be + //attached to the same pool so "allocator_instance2" can deallocate + //nodes allocated by "allocator_instance" + node_allocator_t allocator_instance2(segment.get_segment_manager()); + + //Create another node_allocator using copy-constructor. This + //node_allocator will also be attached to the same pool + node_allocator_t allocator_instance3(allocator_instance2); + + //All allocators are equal + assert(allocator_instance == allocator_instance2); + assert(allocator_instance2 == allocator_instance3); + + //So memory allocated with one can be deallocated with another + allocator_instance2.deallocate(allocator_instance.allocate(1), 1); + allocator_instance3.deallocate(allocator_instance2.allocate(1), 1); + + //The common pool will be destroyed here, since no allocator is + //attached to the pool + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_offset_ptr.cpp b/src/boost/libs/interprocess/example/doc_offset_ptr.cpp new file mode 100644 index 00000000..118feabf --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_offset_ptr.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_offset_ptr +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/offset_ptr.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +//Shared memory linked list node +struct list_node +{ + offset_ptr<list_node> next; + int value; +}; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, + test::get_process_id_name(), //segment name + 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create linked list with 10 nodes in shared memory + offset_ptr<list_node> prev = 0, current, first; + + int i; + for(i = 0; i < 10; ++i, prev = current){ + current = static_cast<list_node*>(segment.allocate(sizeof(list_node))); + current->value = i; + current->next = 0; + + if(!prev) + first = current; + else + prev->next = current; + } + + //Communicate list to other processes + //. . . + //When done, destroy list + for(current = first; current; /**/){ + prev = current; + current = current->next; + segment.deallocate(prev.get()); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_private_adaptive_pool.cpp b/src/boost/libs/interprocess/example/doc_private_adaptive_pool.cpp new file mode 100644 index 00000000..3dd854a6 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_private_adaptive_pool.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_private_adaptive_pool +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/private_adaptive_pool.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, + test::get_process_id_name(), //segment name + 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create a private_adaptive_pool that allocates ints from the managed segment + //The number of chunks per segment is the default value + typedef private_adaptive_pool<int, managed_shared_memory::segment_manager> + private_adaptive_pool_t; + private_adaptive_pool_t allocator_instance(segment.get_segment_manager()); + + //Create another private_adaptive_pool. + private_adaptive_pool_t allocator_instance2(segment.get_segment_manager()); + + //Although the segment manager address + //is the same, this private_adaptive_pool will have its own pool so + //"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance". + //"allocator_instance2" is NOT equal to "allocator_instance" + assert(allocator_instance != allocator_instance2); + + //Create another adaptive_pool using copy-constructor. + private_adaptive_pool_t allocator_instance3(allocator_instance2); + + //This allocator is also unequal to allocator_instance2 + assert(allocator_instance2 != allocator_instance3); + + //Pools are destroyed with the allocators + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_private_node_allocator.cpp b/src/boost/libs/interprocess/example/doc_private_node_allocator.cpp new file mode 100644 index 00000000..8a75691c --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_private_node_allocator.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_private_node_allocator +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/private_node_allocator.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, + test::get_process_id_name(), //segment name + 65536); + #else + //-> + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + //<- + #endif + //-> + + //Create a private_node_allocator that allocates ints from the managed segment + //The number of chunks per segment is the default value + typedef private_node_allocator<int, managed_shared_memory::segment_manager> + private_node_allocator_t; + private_node_allocator_t allocator_instance(segment.get_segment_manager()); + + //Create another private_node_allocator. + private_node_allocator_t allocator_instance2(segment.get_segment_manager()); + + //Although the segment manager address + //is the same, this private_node_allocator will have its own pool so + //"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance". + //"allocator_instance2" is NOT equal to "allocator_instance" + assert(allocator_instance != allocator_instance2); + + //Create another node_allocator using copy-constructor. + private_node_allocator_t allocator_instance3(allocator_instance2); + + //This allocator is also unequal to allocator_instance2 + assert(allocator_instance2 != allocator_instance3); + + //Pools are destroyed with the allocators + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_scoped_ptr.cpp b/src/boost/libs/interprocess/example/doc_scoped_ptr.cpp new file mode 100644 index 00000000..b3e3e2e7 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_scoped_ptr.cpp @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_scoped_ptr +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/smart_ptr/scoped_ptr.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +class my_class +{}; + +class my_exception +{}; + +//A functor that destroys the shared memory object +template<class T> +class my_deleter +{ + private: + //A typedef to save typing + typedef managed_shared_memory::segment_manager segment_manager; + //This my_deleter is created in the stack, not in shared memory, + //so we can use raw pointers + segment_manager *mp_segment_manager; + + public: + //This typedef will specify the pointer type that + //scoped_ptr will store + typedef T *pointer; + //Constructor + my_deleter(segment_manager *s_mngr) + : mp_segment_manager(s_mngr){} + + void operator()(pointer object_to_delete) + { mp_segment_manager->destroy_ptr(object_to_delete); } +}; + +int main () +{ + //Create shared memory + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory shmem(create_only, test::get_process_id_name(), 10000); + #else + //-> + managed_shared_memory shmem(create_only, "MySharedMemory", 10000); + //<- + #endif + //-> + + //In the first try, there will be no exceptions + //in the second try we will throw an exception + for(int i = 0; i < 2; ++i){ + //Create an object in shared memory + my_class * my_object = shmem.construct<my_class>("my_object")(); + my_class * my_object2 = shmem.construct<my_class>(anonymous_instance)(); + shmem.destroy_ptr(my_object2); + + //Since the next shared memory allocation can throw + //assign it to a scoped_ptr so that if an exception occurs + //we destroy the object automatically + my_deleter<my_class> d(shmem.get_segment_manager()); + + try{ + scoped_ptr<my_class, my_deleter<my_class> > s_ptr(my_object, d); + //Let's emulate a exception capable operation + //In the second try, throw an exception + if(i == 1){ + throw(my_exception()); + } + //If we have passed the dangerous zone + //we can release the scoped pointer + //to avoid destruction + s_ptr.release(); + } + catch(const my_exception &){} + //Here, scoped_ptr is destroyed + //so it we haven't thrown an exception + //the object should be there, otherwise, destroyed + if(i == 0){ + //Make sure the object is alive + if(!shmem.find<my_class>("my_object").first){ + return 1; + } + //Now we can use it and delete it manually + shmem.destroy<my_class>("my_object"); + } + else{ + //Make sure the object has been deleted + if(shmem.find<my_class>("my_object").first){ + return 1; + } + } + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_shared_memory.cpp b/src/boost/libs/interprocess/example/doc_shared_memory.cpp new file mode 100644 index 00000000..cb553de9 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_shared_memory.cpp @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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> +//[doc_shared_memory +#include <boost/interprocess/shared_memory_object.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <cstring> +#include <cstdlib> +#include <string> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main(int argc, char *argv[]) +{ + using namespace boost::interprocess; + + if(argc == 1){ //Parent process + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create a shared memory object. + //<- + #if 1 + shared_memory_object shm (create_only, test::get_process_id_name(), read_write); + #else + //-> + shared_memory_object shm (create_only, "MySharedMemory", read_write); + //<- + #endif + //-> + + //Set size + shm.truncate(1000); + + //Map the whole shared memory in this process + mapped_region region(shm, read_write); + + //Write all the memory to 1 + std::memset(region.get_address(), 1, region.get_size()); + + //Launch child process + std::string s(argv[0]); s += " child "; + //<- + s += test::get_process_id_name(); + //-> + if(0 != std::system(s.c_str())) + return 1; + } + else{ + //Open already created shared memory object. + //<- + #if 1 + shared_memory_object shm (open_only, argv[2], read_only); + #else + //-> + shared_memory_object shm (open_only, "MySharedMemory", read_only); + //<- + #endif + //-> + + //Map the whole shared memory in this process + mapped_region region(shm, read_only); + + //Check that memory was initialized to 1 + char *mem = static_cast<char*>(region.get_address()); + for(std::size_t i = 0; i < region.get_size(); ++i) + if(*mem++ != 1) + return 1; //Error checking memory + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_shared_ptr.cpp b/src/boost/libs/interprocess/example/doc_shared_ptr.cpp new file mode 100644 index 00000000..6956816c --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_shared_ptr.cpp @@ -0,0 +1,144 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. +// 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/workaround.hpp> + +//[doc_shared_ptr +#include <boost/interprocess/managed_mapped_file.hpp> +#include <boost/interprocess/smart_ptr/shared_ptr.hpp> +#include <boost/interprocess/smart_ptr/weak_ptr.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +//This is type of the object we want to share +struct type_to_share +{}; + +//This is the type of a shared pointer to the previous type +//that will be built in the mapped file +typedef managed_shared_ptr<type_to_share, managed_mapped_file>::type shared_ptr_type; +typedef managed_weak_ptr<type_to_share, managed_mapped_file>::type weak_ptr_type; + +//This is a type holding a shared pointer +struct shared_ptr_owner +{ + shared_ptr_owner(const shared_ptr_type &other_shared_ptr) + : shared_ptr_(other_shared_ptr) + {} + + shared_ptr_owner(const shared_ptr_owner &other_owner) + : shared_ptr_(other_owner.shared_ptr_) + {} + + shared_ptr_type shared_ptr_; + //... +}; + +int main () +{ + //Define file names + //<- + #if 1 + std::string mapped_file(boost::interprocess::ipcdetail::get_temporary_path()); + mapped_file += "/"; mapped_file += test::get_process_id_name(); + const char *MappedFile = mapped_file.c_str(); + #else + //-> + const char *MappedFile = "MyMappedFile"; + //<- + #endif + //-> + + //Destroy any previous file with the name to be used. + struct file_remove + { + file_remove(const char *MappedFile) + : MappedFile_(MappedFile) { file_mapping::remove(MappedFile_); } + ~file_remove(){ file_mapping::remove(MappedFile_); } + const char *MappedFile_; + } remover(MappedFile); + { + managed_mapped_file file(create_only, MappedFile, 65536); + + //Construct the shared type in the file and + //pass ownership to this local shared pointer + shared_ptr_type local_shared_ptr = make_managed_shared_ptr + (file.construct<type_to_share>("object to share")(), file); + assert(local_shared_ptr.use_count() == 1); + + //Share ownership of the object between local_shared_ptr and a new "owner1" + shared_ptr_owner *owner1 = + file.construct<shared_ptr_owner>("owner1")(local_shared_ptr); + assert(local_shared_ptr.use_count() == 2); + + //local_shared_ptr releases object ownership + local_shared_ptr.reset(); + assert(local_shared_ptr.use_count() == 0); + assert(owner1->shared_ptr_.use_count() == 1); + + //Share ownership of the object between "owner1" and a new "owner2" + shared_ptr_owner *owner2 = + file.construct<shared_ptr_owner>("owner2")(*owner1); + assert(owner1->shared_ptr_.use_count() == 2); + assert(owner2->shared_ptr_.use_count() == 2); + assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get()); + //<- + (void)owner2; + //-> + //The mapped file is unmapped here. Objects have been flushed to disk + } + { + //Reopen the mapped file and find again all owners + managed_mapped_file file(open_only, MappedFile); + + shared_ptr_owner *owner1 = file.find<shared_ptr_owner>("owner1").first; + shared_ptr_owner *owner2 = file.find<shared_ptr_owner>("owner2").first; + assert(owner1 && owner2); + + //Check everything is as expected + assert(file.find<type_to_share>("object to share").first != 0); + assert(owner1->shared_ptr_.use_count() == 2); + assert(owner2->shared_ptr_.use_count() == 2); + assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get()); + + //Now destroy one of the owners, the reference count drops. + file.destroy_ptr(owner1); + assert(owner2->shared_ptr_.use_count() == 1); + + //Create a weak pointer + weak_ptr_type local_observer1(owner2->shared_ptr_); + assert(local_observer1.use_count() == owner2->shared_ptr_.use_count()); + + { //Create a local shared pointer from the weak pointer + shared_ptr_type local_shared_ptr = local_observer1.lock(); + assert(local_observer1.use_count() == owner2->shared_ptr_.use_count()); + assert(local_observer1.use_count() == 2); + } + + //Now destroy the remaining owner. "object to share" will be destroyed + file.destroy_ptr(owner2); + assert(file.find<type_to_share>("object to share").first == 0); + + //Test observer + assert(local_observer1.expired()); + assert(local_observer1.use_count() == 0); + + //The reference count will be deallocated when all weak pointers + //disappear. After that, the file is unmapped. + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_shared_ptr_explicit.cpp b/src/boost/libs/interprocess/example/doc_shared_ptr_explicit.cpp new file mode 100644 index 00000000..d084d3f6 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_shared_ptr_explicit.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. +// 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/workaround.hpp> + +//[doc_shared_ptr_explicit +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/smart_ptr/shared_ptr.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <boost/interprocess/smart_ptr/deleter.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +//This is type of the object we want to share +class MyType +{}; + +typedef managed_shared_memory::segment_manager segment_manager_type; +typedef allocator<void, segment_manager_type> void_allocator_type; +typedef deleter<MyType, segment_manager_type> deleter_type; +typedef shared_ptr<MyType, void_allocator_type, deleter_type> my_shared_ptr; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory segment(create_only, test::get_process_id_name(), 4096); + #else + //-> + managed_shared_memory segment(create_only, "MySharedMemory", 4096); + //<- + #endif + //-> + + //Create a shared pointer in shared memory + //pointing to a newly created object in the segment + my_shared_ptr &shared_ptr_instance = + *segment.construct<my_shared_ptr>("shared ptr") + //Arguments to construct the shared pointer + ( segment.construct<MyType>("object to share")() //object to own + , void_allocator_type(segment.get_segment_manager()) //allocator + , deleter_type(segment.get_segment_manager()) //deleter + ); + assert(shared_ptr_instance.use_count() == 1); + + //Destroy "shared ptr". "object to share" will be automatically destroyed + segment.destroy_ptr(&shared_ptr_instance); + + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_spawn_vector.cpp b/src/boost/libs/interprocess/example/doc_spawn_vector.cpp new file mode 100644 index 00000000..c2f0dfe7 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_spawn_vector.cpp @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_spawn_vector +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <string> +#include <cstdlib> //std::system +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +//Define an STL compatible allocator of ints that allocates from the managed_shared_memory. +//This allocator will allow placing containers in the segment +typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator; + +//Alias a vector that uses the previous STL-like allocator so that allocates +//its values from the segment +typedef vector<int, ShmemAllocator> MyVector; + +//Main function. For parent process argc == 1, for child process argc == 2 +int main(int argc, char *argv[]) +{ + if(argc == 1){ //Parent process + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create a new segment with given name and size + //<- + #if 1 + managed_shared_memory segment(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, "MySharedMemory", 65536); + //<- + #endif + //-> + + //Initialize shared memory STL-compatible allocator + const ShmemAllocator alloc_inst (segment.get_segment_manager()); + + //Construct a vector named "MyVector" in shared memory with argument alloc_inst + MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst); + + for(int i = 0; i < 100; ++i) //Insert data in the vector + myvector->push_back(i); + + //Launch child process + std::string s(argv[0]); s += " child "; + //<- + s += test::get_process_id_name(); + //-> + if(0 != std::system(s.c_str())) + return 1; + + //Check child has destroyed the vector + if(segment.find<MyVector>("MyVector").first) + return 1; + } + else{ //Child process + //Open the managed segment + //<- + #if 1 + managed_shared_memory segment(open_only, argv[2]); + #else + //-> + managed_shared_memory segment(open_only, "MySharedMemory"); + //<- + #endif + //-> + + //Find the vector using the c-string name + MyVector *myvector = segment.find<MyVector>("MyVector").first; + + //Use vector in reverse order + std::sort(myvector->rbegin(), myvector->rend()); + + //When done, destroy the vector from the segment + segment.destroy<MyVector>("MyVector"); + } + + return 0; +} + +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_unique_ptr.cpp b/src/boost/libs/interprocess/example/doc_unique_ptr.cpp new file mode 100644 index 00000000..c87f7983 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_unique_ptr.cpp @@ -0,0 +1,141 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. +// 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/workaround.hpp> + +//[doc_unique_ptr +#include <boost/interprocess/managed_mapped_file.hpp> +#include <boost/interprocess/smart_ptr/unique_ptr.hpp> +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/containers/list.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <cassert> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +//This is type of the object we'll allocate dynamically +struct MyType +{ + MyType(int number = 0) + : number_(number) + {} + int number_; +}; + +//This is the type of a unique pointer to the previous type +//that will be built in the mapped file +typedef managed_unique_ptr<MyType, managed_mapped_file>::type unique_ptr_type; + +//Define containers of unique pointer. Unique pointer simplifies object management +typedef vector + < unique_ptr_type + , allocator<unique_ptr_type, managed_mapped_file::segment_manager> + > unique_ptr_vector_t; + +typedef list + < unique_ptr_type + , allocator<unique_ptr_type, managed_mapped_file::segment_manager> + > unique_ptr_list_t; + +int main () +{ + //Define file names + //<- + #if 1 + std::string mapped_file(boost::interprocess::ipcdetail::get_temporary_path()); + mapped_file += "/"; mapped_file += test::get_process_id_name(); + const char *MappedFile = mapped_file.c_str(); + #else + //-> + const char *MappedFile = "MyMappedFile"; + //<- + #endif + //-> + + //Destroy any previous file with the name to be used. + struct file_remove + { + file_remove(const char *MappedFile) + : MappedFile_(MappedFile) { file_mapping::remove(MappedFile_); } + ~file_remove(){ file_mapping::remove(MappedFile_); } + const char *MappedFile_; + } remover(MappedFile); + { + managed_mapped_file file(create_only, MappedFile, 65536); + + //Construct an object in the file and + //pass ownership to this local unique pointer + unique_ptr_type local_unique_ptr (make_managed_unique_ptr + (file.construct<MyType>("unique object")(), file)); + assert(local_unique_ptr.get() != 0); + + //Reset the unique pointer. The object is automatically destroyed + local_unique_ptr.reset(); + assert(file.find<MyType>("unique object").first == 0); + + //Now create a vector of unique pointers + unique_ptr_vector_t *unique_vector = + file.construct<unique_ptr_vector_t>("unique vector")(file.get_segment_manager()); + + //Speed optimization + unique_vector->reserve(100); + + //Now insert all values + for(int i = 0; i < 100; ++i){ + unique_ptr_type p(make_managed_unique_ptr(file.construct<MyType>(anonymous_instance)(i), file)); + unique_vector->push_back(boost::move(p)); + assert(unique_vector->back()->number_ == i); + } + + //Now create a list of unique pointers + unique_ptr_list_t *unique_list = + file.construct<unique_ptr_list_t>("unique list")(file.get_segment_manager()); + + //Pass ownership of all values to the list + for(int i = 99; !unique_vector->empty(); --i){ + unique_list->push_front(boost::move(unique_vector->back())); + //The unique ptr of the vector is now empty... + assert(unique_vector->back() == 0); + unique_vector->pop_back(); + //...and the list has taken ownership of the value + assert(unique_list->front() != 0); + assert(unique_list->front()->number_ == i); + } + assert(unique_list->size() == 100); + + //Now destroy the empty vector. + file.destroy_ptr(unique_vector); + //The mapped file is unmapped here. Objects have been flushed to disk + } + { + //Reopen the mapped file and find again the list + managed_mapped_file file(open_only, MappedFile); + + unique_ptr_list_t *unique_list = + file.find<unique_ptr_list_t>("unique list").first; + assert(unique_list); + assert(unique_list->size() == 100); + + unique_ptr_list_t::const_iterator list_it = unique_list->begin(); + for(int i = 0; i < 100; ++i, ++list_it){ + assert((*list_it)->number_ == i); + } + + //Now destroy the list. All elements will be automatically deallocated. + file.destroy_ptr(unique_list); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_unordered_map.cpp b/src/boost/libs/interprocess/example/doc_unordered_map.cpp new file mode 100644 index 00000000..02f048ab --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_unordered_map.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_unordered_map +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/allocators/allocator.hpp> + +//<- +//Shield against external warnings +#include <boost/interprocess/detail/config_external_begin.hpp> +//-> + +#include <boost/unordered_map.hpp> //boost::unordered_map + +//<- +#include <boost/interprocess/detail/config_external_end.hpp> +#include "../test/get_process_id_name.hpp" +//-> + +#include <functional> //std::equal_to +#include <boost/functional/hash.hpp> //boost::hash + +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main () +{ + using namespace boost::interprocess; + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //Create shared memory + //<- + #if 1 + managed_shared_memory segment(create_only, test::get_process_id_name(), 65536); + #else + //-> + managed_shared_memory segment(create_only, "MySharedMemory", 65536); + //<- + #endif + //-> + + //Note that unordered_map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>, + //so the allocator must allocate that pair. + typedef int KeyType; + typedef float MappedType; + typedef std::pair<const int, float> ValueType; + + //Typedef the allocator + typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator; + + //Alias an unordered_map of ints that uses the previous STL-like allocator. + typedef boost::unordered_map + < KeyType , MappedType + , boost::hash<KeyType> ,std::equal_to<KeyType> + , ShmemAllocator> + MyHashMap; + + //Construct a shared memory hash map. + //Note that the first parameter is the initial bucket count and + //after that, the hash function, the equality function and the allocator + MyHashMap *myhashmap = segment.construct<MyHashMap>("MyHashMap") //object name + ( 3, boost::hash<int>(), std::equal_to<int>() // + , segment.get_allocator<ValueType>()); //allocator instance + + //Insert data in the hash map + for(int i = 0; i < 100; ++i){ + myhashmap->insert(ValueType(i, (float)i)); + } + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_upgradable_mutex_shared_data.hpp b/src/boost/libs/interprocess/example/doc_upgradable_mutex_shared_data.hpp new file mode 100644 index 00000000..09c5a393 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_upgradable_mutex_shared_data.hpp @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/sync/interprocess_upgradable_mutex.hpp> + + struct shared_data + { + enum { NumItems = 100 }; + enum { LineSize = 100 }; + + shared_data() + : current_line(0) + , end_a(false) + , end_b(false) + {} + + //Mutex to protect access to the queue + boost::interprocess::interprocess_upgradable_mutex upgradable_mutex; + + //Items to fill + char items[NumItems][LineSize]; + int current_line; + bool end_a; + bool end_b; + }; diff --git a/src/boost/libs/interprocess/example/doc_vectorstream.cpp b/src/boost/libs/interprocess/example/doc_vectorstream.cpp new file mode 100644 index 00000000..fbfa6c55 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_vectorstream.cpp @@ -0,0 +1,137 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_vectorstream +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/containers/string.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/streams/vectorstream.hpp> +#include <iterator> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +using namespace boost::interprocess; + +typedef allocator<int, managed_shared_memory::segment_manager> + IntAllocator; +typedef allocator<char, managed_shared_memory::segment_manager> + CharAllocator; +typedef vector<int, IntAllocator> MyVector; +typedef basic_string + <char, std::char_traits<char>, CharAllocator> MyString; +typedef basic_vectorstream<MyString> MyVectorStream; + +int main () +{ + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory segment( + create_only, + test::get_process_id_name(), //segment name + 65536); //segment size in bytes + #else + //-> + managed_shared_memory segment( + create_only, + "MySharedMemory", //segment name + 65536); //segment size in bytes + //<- + #endif + //-> + + //Construct shared memory vector + MyVector *myvector = + segment.construct<MyVector>("MyVector") + (IntAllocator(segment.get_segment_manager())); + + //Fill vector + myvector->reserve(100); + for(int i = 0; i < 100; ++i){ + myvector->push_back(i); + } + + //Create the vectorstream. To create the internal shared memory + //basic_string we need to pass the shared memory allocator as + //a constructor argument + MyVectorStream myvectorstream(CharAllocator(segment.get_segment_manager())); + + //Reserve the internal string + myvectorstream.reserve(100*5); + + //Write all vector elements as text in the internal string + //Data will be directly written in shared memory, because + //internal string's allocator is a shared memory allocator + for(std::size_t i = 0, max = myvector->size(); i < max; ++i){ + myvectorstream << (*myvector)[i] << std::endl; + } + + //Auxiliary vector to compare original data + MyVector *myvector2 = + segment.construct<MyVector>("MyVector2") + (IntAllocator(segment.get_segment_manager())); + + //Avoid reallocations + myvector2->reserve(100); + + //Extract all values from the internal + //string directly to a shared memory vector. + std::istream_iterator<int> it(myvectorstream), itend; + std::copy(it, itend, std::back_inserter(*myvector2)); + + //Compare vectors + assert(std::equal(myvector->begin(), myvector->end(), myvector2->begin())); + + //Create a copy of the internal string + MyString stringcopy (myvectorstream.vector()); + + //Now we create a new empty shared memory string... + MyString *mystring = + segment.construct<MyString>("MyString") + (CharAllocator(segment.get_segment_manager())); + + //...and we swap vectorstream's internal string + //with the new one: after this statement mystring + //will be the owner of the formatted data. + //No reallocations, no data copies + myvectorstream.swap_vector(*mystring); + + //Let's compare both strings + assert(stringcopy == *mystring); + + //Done, destroy and delete vectors and string from the segment + segment.destroy_ptr(myvector2); + segment.destroy_ptr(myvector); + segment.destroy_ptr(mystring); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_where_allocate.cpp b/src/boost/libs/interprocess/example/doc_where_allocate.cpp new file mode 100644 index 00000000..c8f14f16 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_where_allocate.cpp @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> +//[doc_where_allocate +#include <boost/interprocess/managed_shared_memory.hpp> +#include <boost/interprocess/containers/vector.hpp> +#include <boost/interprocess/containers/string.hpp> +#include <boost/interprocess/allocators/allocator.hpp> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main () +{ + using namespace boost::interprocess; + //Typedefs + typedef allocator<char, managed_shared_memory::segment_manager> + CharAllocator; + typedef basic_string<char, std::char_traits<char>, CharAllocator> + MyShmString; + typedef allocator<MyShmString, managed_shared_memory::segment_manager> + StringAllocator; + typedef vector<MyShmString, StringAllocator> + MyShmStringVector; + + //Open shared memory + //Remove shared memory on construction and destruction + struct shm_remove + { + //<- + #if 1 + shm_remove() { shared_memory_object::remove(test::get_process_id_name()); } + ~shm_remove(){ shared_memory_object::remove(test::get_process_id_name()); } + #else + //-> + shm_remove() { shared_memory_object::remove("MySharedMemory"); } + ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); } + //<- + #endif + //-> + } remover; + //<- + (void)remover; + //-> + + //<- + #if 1 + managed_shared_memory shm(create_only, test::get_process_id_name(), 10000); + #else + //-> + managed_shared_memory shm(create_only, "MySharedMemory", 10000); + //<- + #endif + //-> + + //Create allocators + CharAllocator charallocator (shm.get_segment_manager()); + StringAllocator stringallocator(shm.get_segment_manager()); + + //This string is in only in this process (the pointer pointing to the + //buffer that will hold the text is not in shared memory). + //But the buffer that will hold "this is my text" is allocated from + //shared memory + MyShmString mystring(charallocator); + mystring = "this is my text"; + + //This vector is only in this process (the pointer pointing to the + //buffer that will hold the MyShmString-s is not in shared memory). + //But the buffer that will hold 10 MyShmString-s is allocated from + //shared memory using StringAllocator. Since strings use a shared + //memory allocator (CharAllocator) the 10 buffers that hold + //"this is my text" text are also in shared memory. + MyShmStringVector myvector(stringallocator); + myvector.insert(myvector.begin(), 10, mystring); + + //This vector is fully constructed in shared memory. All pointers + //buffers are constructed in the same shared memory segment + //This vector can be safely accessed from other processes. + MyShmStringVector *myshmvector = + shm.construct<MyShmStringVector>("myshmvector")(stringallocator); + myshmvector->insert(myshmvector->begin(), 10, mystring); + + //Destroy vector. This will free all strings that the vector contains + shm.destroy_ptr(myshmvector); + return 0; +} +//] +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_windows_shared_memory.cpp b/src/boost/libs/interprocess/example/doc_windows_shared_memory.cpp new file mode 100644 index 00000000..17f1f821 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_windows_shared_memory.cpp @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> + +#if defined(BOOST_INTERPROCESS_WINDOWS) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + +//[doc_windows_shared_memory +#include <boost/interprocess/windows_shared_memory.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <cstring> +#include <cstdlib> +#include <string> +//<- +#include "../test/get_process_id_name.hpp" +//-> + +int main(int argc, char *argv[]) +{ + using namespace boost::interprocess; + + if(argc == 1){ //Parent process + //Create a native windows shared memory object. + //<- + #if 1 + windows_shared_memory shm (create_only, test::get_process_id_name(), read_write, 1000); + #else + //-> + windows_shared_memory shm (create_only, "MySharedMemory", read_write, 1000); + //<- + #endif + //-> + + //Map the whole shared memory in this process + mapped_region region(shm, read_write); + + //Write all the memory to 1 + std::memset(region.get_address(), 1, region.get_size()); + + //Launch child process + std::string s(argv[0]); s += " child "; + //<- + s += test::get_process_id_name(); + //-> + if(0 != std::system(s.c_str())) + return 1; + //windows_shared_memory is destroyed when the last attached process dies... + } + else{ + //Open already created shared memory object. + //<- + #if 1 + windows_shared_memory shm (open_only, argv[2], read_only); + #else + //-> + windows_shared_memory shm (open_only, "MySharedMemory", read_only); + //<- + #endif + //-> + + //Map the whole shared memory in this process + mapped_region region(shm, read_only); + + //Check that memory was initialized to 1 + char *mem = static_cast<char*>(region.get_address()); + for(std::size_t i = 0; i < region.get_size(); ++i) + if(*mem++ != 1) + return 1; //Error checking memory + return 0; + } + return 0; +} +//] + +#else //BOOST_INTERPROCESS_WINDOWS + +int main() +{ + return 0; +} + +#endif //BOOST_INTERPROCESS_WINDOWS + +#include <boost/interprocess/detail/config_end.hpp> diff --git a/src/boost/libs/interprocess/example/doc_xsi_shared_memory.cpp b/src/boost/libs/interprocess/example/doc_xsi_shared_memory.cpp new file mode 100644 index 00000000..bdd878a4 --- /dev/null +++ b/src/boost/libs/interprocess/example/doc_xsi_shared_memory.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2012. 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/workaround.hpp> + +#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + +//[doc_xsi_shared_memory +#include <boost/interprocess/xsi_shared_memory.hpp> +#include <boost/interprocess/mapped_region.hpp> +#include <cstring> +#include <cstdlib> +#include <string> + +using namespace boost::interprocess; + +void remove_old_shared_memory(const xsi_key &key) +{ + try{ + xsi_shared_memory xsi(open_only, key); + xsi_shared_memory::remove(xsi.get_shmid()); + } + catch(interprocess_exception &e){ + if(e.get_error_code() != not_found_error) + throw; + } +} + +int main(int argc, char *argv[]) +{ + if(argc == 1){ //Parent process + //Build XSI key (ftok based) + xsi_key key(argv[0], 1); + + remove_old_shared_memory(key); + + //Create a shared memory object. + xsi_shared_memory shm (create_only, key, 1000); + + //Remove shared memory on destruction + struct shm_remove + { + int shmid_; + shm_remove(int shmid) : shmid_(shmid){} + ~shm_remove(){ xsi_shared_memory::remove(shmid_); } + } remover(shm.get_shmid()); + + //Map the whole shared memory in this process + mapped_region region(shm, read_write); + + //Write all the memory to 1 + std::memset(region.get_address(), 1, region.get_size()); + + //Launch child process + std::string s(argv[0]); s += " child "; + if(0 != std::system(s.c_str())) + return 1; + } + else{ + //Build XSI key (ftok based) + xsi_key key(argv[0], 1); + + //Create a shared memory object. + xsi_shared_memory shm (open_only, key); + + //Map the whole shared memory in this process + mapped_region region(shm, read_only); + + //Check that memory was initialized to 1 + char *mem = static_cast<char*>(region.get_address()); + for(std::size_t i = 0; i < region.get_size(); ++i) + if(*mem++ != 1) + return 1; //Error checking memory + } + return 0; +} +//] + +#else //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS + +int main() +{ + return 0; +} + +#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS + +#include <boost/interprocess/detail/config_end.hpp> |