0

I've spent some time scouring the boost interprocess documentation but I remain stumped by this weird bug. I've seen this code work on boost version 1.42, x86, but not on the versions mentioned in the title.

This is a simple client-server model that shares strings. The server sets up and waits. When the client shares new strings with the server, it prints the newly shared strings. The code is as follows:

Server:

//compile this with: g++ -g server.cc -o server -lrt -lboost_thread-mt -lpthread -lcurses
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>
#include <boost/interprocess/containers/vector.hpp>
#include <iostream>
#include<curses.h>
#include<unistd.h>

using namespace std;
using namespace boost::interprocess;


int main()
{

typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> opString;
typedef boost::interprocess::allocator<opString, managed_shared_memory::segment_manager> StrAlloc;
typedef vector<opString, StrAlloc> opStringVector;

struct shm_remove
{
      shm_remove() { shared_memory_object::remove("opSHM"); }
      ~shm_remove(){ shared_memory_object::remove("opSHM"); }
} remover;

managed_shared_memory managed_shm(open_or_create, "opSHM", 1000);

CharAllocator     charallocator  (managed_shm.get_segment_manager());
    StrAlloc   stralloc(managed_shm.get_segment_manager());

opStringVector * ID_Descript = managed_shm.construct<opStringVector>("ID_DESCRIPTOR")(stralloc);
opStringVector * ID_Handle = managed_shm.construct<opStringVector>("ID_HANDLE")(stralloc);

std::string serD = "This is the server";
std::string serI = "SERVER";

opString st1(charallocator);
opString st2(charallocator);
st1 = serD.c_str();
st2 = serI.c_str();

ID_Descript->push_back(st1);
ID_Handle->push_back(st2);

int i=0;

initscr();     //in ncurses
timeout(0);

int lastSize = 0;//ID_Handle2->size();
printw("\n Registration List: \n");
while(!i)
{
    usleep(10000);
    i=getch();
if(ID_Handle->size()!=lastSize)
{   
    for(int j = lastSize;j<ID_Handle->size();j++)
    {   
        const char * hand_st = ID_Handle->at(j).c_str();
        const char * desc_st = ID_Descript->at(j).c_str();
        std::string hID = hand_st;
        std::string dID = desc_st;
        std::string newstr = "New process registered: " + hID + "\t" + dID;
        const char * st = newstr.c_str();
            printw("%s \n",st);
    }
    lastSize = ID_Handle->size();
}
    if(i>0)
        i=1;
    else
        i=0;

}
endwin();   

}

Client:

//Compile this with: g++ -g client.cc -o client -lrt -lboost_thread-mt -lpthread -lcurses

#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>
#include <boost/interprocess/containers/vector.hpp>
#include <iostream>
#include<curses.h>
#include<unistd.h>

using namespace std;
using namespace boost::interprocess;

int main()
{


    typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator;
    typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> opString;
    typedef boost::interprocess::allocator<opString, managed_shared_memory::segment_manager> StrAlloc;
    typedef vector<opString, StrAlloc> opStringVector;

    managed_shared_memory managed_shm(open_only, "opSHM");
    CharAllocator     charallocator  (managed_shm.get_segment_manager());
        StrAlloc   stralloc(managed_shm.get_segment_manager());

    opStringVector * ID_Descript2 = managed_shm.find<opStringVector>("ID_DESCRIPTOR").first;
    opStringVector * ID_Handle2 = managed_shm.find<opStringVector>("ID_HANDLE").first;

    opString st1(charallocator);
    opString st2(charallocator);

    std::string des; 
    std::string handle;

    des = "A Dummy registration";
    handle = "DU";
    st1 = des.c_str();
    st2 = handle.c_str();
    ID_Descript2->push_back(st1);
    ID_Handle2->push_back(st2);
    cout << ID_Descript2->back() << '\t' << ID_Handle2->back()  << endl;

    des = "Null Algorithm\0";
    handle = "OP_NULL";
    st1 = des.c_str();
    st2 = handle.c_str();
    ID_Descript2->push_back(st1);
    ID_Handle2->push_back(st2);
    cout << ID_Descript2->back() << '\t' << ID_Handle2->back()  << endl;

    des = "First Algorithm";
    handle = "OP_ALG_FIRST";
    st1 = des.c_str();
    st2 = handle.c_str();
    ID_Descript2->push_back(st1);
    ID_Handle2->push_back(st2);
    cout << ID_Descript2->back() << '\t' << ID_Handle2->back()  << endl;

    des = "Last Algorithm";
    handle = "OP_ALG_LAST";
    st1 = des.c_str();
    st2 = handle.c_str();
    ID_Descript2->push_back(st1);
    ID_Handle2->push_back(st2);
    cout << ID_Descript2->back() << '\t' << ID_Handle2->back()  << endl;

}

This is the Server output:

Registration List:
New process registered: SERVER  This is the server
New process registered: DU  A Dummy registration
New process registered: OP_NULL Null AlgorithmTver
New process registered: OP_ALG_FIRST    First AlgorithmAtion
New process registered: OP_ALG_LAST     Last Algorithm

This is the client output:

A Dummy registration    DU
Null Algorithm  OP_NULL
First Algorithm OP_ALG_FIRST
Last Algorithm  OP_ALG_LAST

As you can see, the server get's the string data, but due to incorrect string termination prints extra/overlapping characters in its output (4th and 5th lines). The client side data is uncorrupted. I'm wondering if something else important is not being done. Would appreciate any pointers on this. Also weird how it works on the Boost 1.42 x86 version without any corruption on the server side. Thanks alot!

P.S: As I am using the managed shared memory feature, I did not explicitly use any synchronization (mutex) mechanisms. Do I have to?

sk7
  • 43
  • 5
  • What exactly is *managed shared memory feature*? I thought that is for windows, no? – BЈовић May 01 '12 at 19:28
  • No. To quote from the boost docs: **mangaged_shared_memory** is an advanced class that combines a shared memory object and a mapped region that covers all the shared memory object. [Managed shared memory docs](http://www.boost.org/doc/libs/1_41_0/doc/html/interprocess/managed_memory_segments.html#interprocess.managed_memory_segments.managed_memory_segment_features.synchronization) – sk7 May 01 '12 at 19:35

0 Answers0