Hi,
I was able to track down the problem to code independent from ours.
The following piece of code terminates with the known exception.
Code: Select all
#include <string>
#include <iostream>
#include <RCF/RCF.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/lexical_cast.hpp>
RCF_BEGIN(I_AlertClient, "I_AlertClient")
// send AlertStatusNotification messages
RCF_METHOD_V0(void, sendAlertStatusNotification)
// register alert client
RCF_METHOD_V1(void, registerAlertClient, std::string const &)
RCF_END(I_AlertClient)
class SimpleAlertClientReceiver
{
public:
void sendAlertStatusNotification() { std::cout << "Status!" << std::endl; }
void registerAlertClient(std::string const &name) { std::cout << "Register: " << name << std::endl; }
};
boost::container::flat_map<std::string, RcfClient<I_AlertClient> > m_clients {};
RcfClient<I_AlertClient> &getClient(std::string const &alertClient)
{
std::cout << "GetClient for " << alertClient << std::endl;
if (m_clients.find(alertClient) == m_clients.end())
{
RcfClient<I_AlertClient> client(RCF::TcpEndpoint{ "localhost", 10052 });
m_clients[alertClient] = client;
m_clients[alertClient].getClientStub().connect();
m_clients[alertClient].registerAlertClient(alertClient);
}
return m_clients[alertClient];
}
int main()
{
RCF::RcfInitDeinit deinit {};
RCF::RcfServer server{ RCF::TcpEndpoint{ "localhost", 10052 }};
SimpleAlertClientReceiver sacr {};
server.bind<I_AlertClient>(sacr);
server.start();
for (unsigned int i = 0; i < 20; ++i)
{
getClient("Client" + boost::lexical_cast<std::string>(i)).sendAlertStatusNotification();
getClient("Client" + boost::lexical_cast<std::string>(i)).sendAlertStatusNotification();
}
server.stop();
return 0;
}
The problem disappears if the getClient() function returns a shared pointer to an client instead of a reference. That saves some assignment operations.
I tried to debug the RcfClient's interface name, by replacing the macros with the preprocessed code, but the modifications we saw didn't seem reasonable for me.
But the problem seems to be related to the assignment in the getClient function. On my machine exception occurs on for i=18, all the time.
EDIT: I further found out that the boost::container::flat_map plays a key role. During the assignment
m_clients[alertClient] = client;
the mInterfaceName of the
default constructed lhs is overwritten with the empty string. Using a std::map doesn't reveal the issue. Since the performance of the flat_map is crucial to us I also tried to fix the assignment operator
from
const std::string &targetName = mInterfaceName;
to
const std::string &targetName = rhs.mInterfaceName;
. This also solved the problem.
Finally I'll stay with the shared pointers for now to avoid assignment at all. But maybe the assignment operator is worth to have a look at.
Regards,
Jan