diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 new file mode 100644 index 0000000..c5bb35b --- /dev/null +++ b/doc/Jamfile.v2 @@ -0,0 +1,85 @@ +# Boost.Interproces library documentation Jamfile --------------------------------- +# +# Copyright Ion Gaztañaga 2005-2006. Use, modification and +# distribution is 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) +# +# See http://www.boost.org for updates, documentation, and revision history. + +project boost/interprocess/doc ; + +import boostbook : boostbook ; +using quickbook ; +#import doxygen : doxygen ; + +boostbook interprocess +: + interprocess.xml +# interprocess.doxygen +: + boost.root=../../../.. +; + +#doxygen interprocess.doxygen +#: +# ../../../boost/interprocess/errors.hpp +# ../../../boost/interprocess/exceptions.hpp +# ../../../boost/interprocess/mapped_file.hpp +# ../../../boost/interprocess/interprocess_fwd.hpp +# ../../../boost/interprocess/managed_external_buffer.hpp +# ../../../boost/interprocess/managed_heap_memory.hpp +# ../../../boost/interprocess/managed_mapped_file.hpp +# ../../../boost/interprocess/managed_shared_memory.hpp +# ../../../boost/interprocess/mapped_file.hpp +# ../../../boost/interprocess/offset_ptr.hpp +# ../../../boost/interprocess/shared_memory.hpp +# ../../../boost/interprocess/segment_manager.hpp + # allocators +# ../../../boost/interprocess/allocators/allocator.hpp +# ../../../boost/interprocess/allocators/cached_node_allocator.hpp +# ../../../boost/interprocess/allocators/node_allocator.hpp +# ../../../boost/interprocess/allocators/private_node_allocator.hpp +# ../../../boost/interprocess/allocators/detail/node_pool.hpp + # indexes +# ../../../boost/interprocess/indexes/flat_map_index.hpp +# ../../../boost/interprocess/indexes/map_index.hpp +# ../../../boost/interprocess/indexes/null_index.hpp +# ../../../boost/interprocess/indexes/unordered_map_index.hpp + # ipc +# ../../../boost/interprocess/ipc/message_queue.hpp + # mem_algo +# ../../../boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp +# ../../../boost/interprocess/mem_algo/multi_simple_seq_fit.hpp +# ../../../boost/interprocess/mem_algo/simple_seq_fit.hpp + # smart_ptr +# ../../../boost/interprocess/smart_ptr/intrusive_ptr.hpp +# ../../../boost/interprocess/smart_ptr/scoped_ptr.hpp + # streams +# ../../../boost/interprocess/streams/bufferstream.hpp +# ../../../boost/interprocess/streams/vectorstream.hpp + # sync +# ../../../boost/interprocess/sync/interprocess_barrier.hpp +# ../../../boost/interprocess/sync/interprocess_condition.hpp +# ../../../boost/interprocess/sync/lock_options.hpp +# ../../../boost/interprocess/sync/interprocess_mutex.hpp +# ../../../boost/interprocess/sync/mutex_family.hpp +# ../../../boost/interprocess/sync/named_mutex.hpp +# ../../../boost/interprocess/sync/named_recursive_mutex.hpp +# ../../../boost/interprocess/sync/named_semaphore.hpp +# ../../../boost/interprocess/sync/null_mutex.hpp +# ../../../boost/interprocess/sync/interprocess_recursive_mutex.hpp +# ../../../boost/interprocess/sync/scoped_lock.hpp +# ../../../boost/interprocess/sync/interprocess_semaphore.hpp +# ../../../boost/interprocess/sync/sharable_lock.hpp +# ../../../boost/interprocess/sync/interprocess_sharable_mutex.hpp +#: +# HIDE_SCOPE_NAMES=YES +# HIDE_UNDOC_MEMBERS=YES +# EXTRACT_ALL=NO +# EXTRACT_PRIVATE=NO +# ENABLE_PREPROCESSING=YES +# MACRO_EXPANSION=YES +# EXPAND_ONLY_PREDEF=YES +# SEARCH_INCLUDES=YES +#; diff --git a/doc/code/Attic/doc_bufferstream.cpp b/doc/code/Attic/doc_bufferstream.cpp new file mode 100644 index 0000000..8506890 --- /dev/null +++ b/doc/code/Attic/doc_bufferstream.cpp @@ -0,0 +1,70 @@ + #include + #include + + #include + #include + #include + #include + + using namespace boost::interprocess; + + int main () + { + managed_shared_memory::remove("MySharedMemory"); + //Create shared memory + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + + //Fill data + std::vector data, data2; + data.reserve(100); + for(int i = 0; i < 100; ++i){ + data.push_back(i); + } + + //Allocate a buffer in shared memory to write data + char *my_cstring = + segment.construct("MyCString")[100*5](0); + bufferstream mybufstream(my_cstring, 100*5); + + //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. + data2.reserve(100); + std::istream_iterator 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; i < 500; ++i){ + mybufstream << data[i] << 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 diff --git a/doc/code/Attic/doc_cont.cpp b/doc/code/Attic/doc_cont.cpp new file mode 100644 index 0000000..a481591 --- /dev/null +++ b/doc/code/Attic/doc_cont.cpp @@ -0,0 +1,49 @@ + #include + #include + + #include + #include + + int main () + { + using namespace boost::interprocess; + + managed_shared_memory::remove("MySharedMemory"); + //Shared memory front-end that is able to construct objects + //associated with a c-string + managed_shared_memory segment(create_only, + "MySharedMemory", //segment name + 65536); + + //Alias an STL-like allocator of ints that allocates ints from the segment + typedef allocator + ShmemAllocator; + + //Alias a vector that uses the previous STL-like allocator + typedef vector 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")/*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"); + return 0; + } + + #include diff --git a/doc/code/Attic/doc_intrusive.cpp b/doc/code/Attic/doc_intrusive.cpp new file mode 100644 index 0000000..ec1a0aa --- /dev/null +++ b/doc/code/Attic/doc_intrusive.cpp @@ -0,0 +1,89 @@ + #include + #include + + #include + #include + + 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 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 > 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 () + { + managed_shared_memory::remove("my_shmem"); + //Create shared memory + managed_shared_memory shmem(create_only, "my_shmem", 10000); + //Create the unique reference counted object in shared memory + N::reference_counted_class *ref_counted = + shmem.construct + ("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 + (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("ref_counted").first) + return 1; + //Success! + return 0; + } + + #include diff --git a/doc/code/Attic/doc_ipc_messageA.cpp b/doc/code/Attic/doc_ipc_messageA.cpp new file mode 100644 index 0000000..760e554 --- /dev/null +++ b/doc/code/Attic/doc_ipc_messageA.cpp @@ -0,0 +1,39 @@ + #include + #include + + #include + #include + + int main () + { + using namespace boost::interprocess; + + //A shared memory front-end that is able to + //allocate raw memory buffers from a shared memory segment + //Create the shared memory segment and initialize needed resources + managed_shared_memory::remove("MySharedMemory"); + managed_shared_memory segment + (create_only, + "MySharedMemory", //segment name + 65536); //segment size in bytes + + //Allocate a portion of the segment + void * shptr = segment.allocate(1024/*bytes to allocate*/); + + //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); + (void)handle; + // Copy message to buffer + // . . . + // Send handle to other process + // . . . + // Wait response from other process + // . . . + + //Deallocate the portion previously allocated + segment.deallocate(shptr); + return 0; + } + + #include diff --git a/doc/code/Attic/doc_ipc_messageB.cpp b/doc/code/Attic/doc_ipc_messageB.cpp new file mode 100644 index 0000000..50aa8bf --- /dev/null +++ b/doc/code/Attic/doc_ipc_messageB.cpp @@ -0,0 +1,31 @@ + #include + #include + + #include + #include + + int main () + { + using namespace boost::interprocess; + + //A shared memory front-end that is able to + //allocate raw memory buffers from a shared memory segment + //Connect to the shared memory segment and initialize needed resources + managed_shared_memory segment(open_only, "MySharedMemory"); //segment name + + //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; + + //Wait handle msg from the other process and put it in + //"handle" local variable + //Get buffer local address from handle + void *msg = segment.get_address_from_handle(handle); + (void)msg; + //Do anything with msg + //. . . + //Send ack to sender process + return 0; + } + + #include diff --git a/doc/code/Attic/doc_managed_heap_memory.cpp b/doc/code/Attic/doc_managed_heap_memory.cpp new file mode 100644 index 0000000..0d9ebeb --- /dev/null +++ b/doc/code/Attic/doc_managed_heap_memory.cpp @@ -0,0 +1,66 @@ + #include + #include + + #include + #include + #include + #include + + using namespace boost::interprocess; + typedef list > + 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") + (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 + std::size_t old_size = mylist->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 + (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 + std::size_t new_size = mylist->size(); + + assert(new_size > old_size); + + //Destroy list + heap_memory.destroy_ptr(mylist); + + return 0; + } + + #include diff --git a/doc/code/Attic/doc_managed_mapped_file.cpp b/doc/code/Attic/doc_managed_mapped_file.cpp new file mode 100644 index 0000000..f34a163 --- /dev/null +++ b/doc/code/Attic/doc_managed_mapped_file.cpp @@ -0,0 +1,68 @@ + #include + #include + + #include + #include + #include + #include + #include + + using namespace boost::interprocess; + typedef list > + MyList; + + int main () + { + const char *FileName = "file_mapping"; + const std::size_t FileSize = 1000; + std::remove(FileName); + managed_mapped_file mfile_memory(create_only, FileName, FileSize); + MyList * mylist = mfile_memory.construct("MyList") + (mfile_memory.get_segment_manager()); + + //Obtain handle, that identifies the list in the buffer + managed_mapped_file::handle_t 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 + std::size_t old_size = mylist->size(); + + //To make the list bigger, let's increase the mapped file + //in FileSize bytes more. +// mfile_memory.grow(FileSize); + + //If mapping address has changed, the old pointer is invalid, + //so use previously obtained handle to find the new pointer. + mylist = static_cast + (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 + std::size_t new_size = mylist->size(); + + assert(new_size > old_size); + + //Destroy list + mfile_memory.destroy_ptr(mylist); + + return 0; + } + + #include diff --git a/doc/code/Attic/doc_named_allocA.cpp b/doc/code/Attic/doc_named_allocA.cpp new file mode 100644 index 0000000..abd3016 --- /dev/null +++ b/doc/code/Attic/doc_named_allocA.cpp @@ -0,0 +1,35 @@ + #include + #include + + #include + + int main () + { + using namespace boost::interprocess; + typedef std::pair MyType; + + //A shared memory front-end that is able to construct + //objects associated with a c-string + //Create the shared memory segment and initialize resources + managed_shared_memory::remove("MySharedMemory"); + managed_shared_memory segment( + create_only, + "MySharedMemory", //segment name + 65536); //segment size in bytes + + //Create an object of MyType initialized to {0.0, 0} + MyType *instance = segment.construct + ("MyType instance") /*name of the object*/ + (0.0 /*ctor first argument*/, + 0 /*ctor second argument*/); + + //Create an array of 10 elements of MyType initialized to {0.0, 0} + MyType *array = segment.construct + ("MyType array") /*name of the object*/ + [10] /*number of elements*/ + (0.0 /*ctor first argument*/, + 0 /*ctor second argument*/); + return 0; + } + + #include diff --git a/doc/code/Attic/doc_named_allocB.cpp b/doc/code/Attic/doc_named_allocB.cpp new file mode 100644 index 0000000..d6f1d56 --- /dev/null +++ b/doc/code/Attic/doc_named_allocB.cpp @@ -0,0 +1,46 @@ + #include + #include + + #include + #include + #include + + int main () + { + using namespace boost::interprocess; + typedef std::pair MyType; + + //A shared memory front-end that is able to construct + //objects associated with a c-string + managed_shared_memory segment( + open_only, + "MySharedMemory"); + + //Find the array and object + std::pair res; + res = segment.find ("MyType array"); + + std::size_t array_len = res.second; + //Length should be 10 + assert(array_len == 10); + + //Find the array and the object + res = segment.find ("MyType instance"); + + std::size_t len = res.second; + + //Length should be 1 + assert(len == 1); + + //Use data + // . . . + + //We're done, delete array from memory + segment.destroy("MyType array"); + + //We're done, delete object from memory + segment.destroy("MyType instance"); + return 0; + } + + #include diff --git a/doc/code/Attic/doc_offset_ptr.cpp b/doc/code/Attic/doc_offset_ptr.cpp new file mode 100644 index 0000000..19c6c9b --- /dev/null +++ b/doc/code/Attic/doc_offset_ptr.cpp @@ -0,0 +1,51 @@ + #include + #include + + #include + #include + + using namespace boost::interprocess; + + //Shared memory linked list node + struct list_node + { + offset_ptr next; + int value; + }; + + int main () + { + //Create shared memory + managed_shared_memory::remove("MySharedMemory"); + managed_shared_memory segment( + create_only, + "MySharedMemory",//segment name + 65536); //segment size in bytes + + //Create linked list with 10 nodes in shared memory + offset_ptr prev = 0, current, first; + + int i; + for(i = 0; i < 10; ++i, prev = current){ + current = static_cast(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 diff --git a/doc/code/Attic/doc_scoped_ptr.cpp b/doc/code/Attic/doc_scoped_ptr.cpp new file mode 100644 index 0000000..cf17e08 --- /dev/null +++ b/doc/code/Attic/doc_scoped_ptr.cpp @@ -0,0 +1,90 @@ + #include + #include + + #include + #include + + using namespace boost::interprocess; + + class my_class + {}; + + class my_exception + {}; + + //A functor that destroys the shared memory object + template + 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 + managed_shared_memory::remove("my_shmem"); + managed_shared_memory shmem(create_only, "my_shmem", 10000); + + //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_object")(); + + //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 d(shmem.get_segment_manager()); + + try{ + scoped_ptr > 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_object").first){ + return 1; + } + //Now we can use it and delete it manually + shmem.destroy("my_object"); + } + else{ + //Make sure the object has been deleted + if(shmem.find("my_object").first){ + return 1; + } + } + } + return 0; + } + + #include diff --git a/doc/code/Attic/doc_vectorstream.cpp b/doc/code/Attic/doc_vectorstream.cpp new file mode 100644 index 0000000..7ff921f --- /dev/null +++ b/doc/code/Attic/doc_vectorstream.cpp @@ -0,0 +1,96 @@ + #include + #include + + #include + #include + #include + #include + #include + + using namespace boost::interprocess; + + typedef allocator + IntAllocator; + typedef allocator + CharAllocator; + typedef vector MyVector; + typedef basic_string + , CharAllocator> MyString; + typedef basic_vectorstream MyVectorStream; + + int main () + { + //Create shared memory + managed_shared_memory::remove("MySharedMemory"); + managed_shared_memory segment( + create_only, + "MySharedMemory",//segment name + 65536); //segment size in bytes + + //Construct shared memory vector + MyVector *myvector = + segment.construct("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("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 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") + (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 diff --git a/doc/code/Attic/doc_where_allocate.cpp b/doc/code/Attic/doc_where_allocate.cpp new file mode 100644 index 0000000..b451b97 --- /dev/null +++ b/doc/code/Attic/doc_where_allocate.cpp @@ -0,0 +1,58 @@ + #include + #include + + #include + #include + #include + #include + + int main () + { + using namespace boost::interprocess; + //Typedefs + typedef allocator + CharAllocator; + typedef basic_string, CharAllocator> + MyShmString; + typedef allocator + StringAllocator; + typedef vector + MyShmStringVector; + + //Open shared memory + managed_shared_memory::remove("myshm"); + managed_shared_memory shm(create_only, "myshm", 10000); + + //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("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 diff --git a/doc/code/Jamfile b/doc/code/Jamfile new file mode 100644 index 0000000..0ba6d4d --- /dev/null +++ b/doc/code/Jamfile @@ -0,0 +1,43 @@ +# Boost interprocess Library test Jamfile +# (C) Copyright Ion Gaztañaga 2004-2006. +# 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) +# +# See http://www.boost.org/libs/test for the library home page. + +# Declare the location of this subproject relative to the root. +subproject libs/interprocess/doc/code ; + +# bring in rules for testing +import testing ; + +{ + template boost_interprocess_test_dll + : ## sources ## + ../../../test/build/boost_unit_test_framework + ../../../thread/build/boost_thread + : ## requirements ## + $(BOOST_ROOT) + dynamic + multi + : ## default build ## + release + ; + + test-suite "interprocess" + : + [ run doc_bufferstream.cpp