robotology / yarp-ros

Repo under construction! please do not use it!
1 stars 1 forks source link

the Nodes system is not threadsafe by design #18

Open damn1 opened 6 years ago

damn1 commented 6 years ago

Describe the bug When calling topic() function on a Publisher object YARP is supposed to create a port /topic@/node nested to the latest (temporal order) instantiated Node. So instantiating multiple yarp::os::Nodes in multithreaded environment is not safe or not supported...

To Reproduce A simple program to obtain some address conflicts when multiple Publishers are instantiated to publish on the same topic from different threads, each with its own Node:

#include <stdio.h>
#include <thread>
#include <signal.h>
#include <functional>
#include <yarp/os/Network.h>
#include <yarp/os/Publisher.h>
#include <yarp/os/Time.h>
#include <yarp/os/Nodes.h>
#include <yarp/os/Node.h>
#include <yarp/rosmsg/std_msgs/String.h>

void _threadRoutine(int i)
{
    yarp::os::Node n("/node" + std::to_string(i));
    yarp::os::Publisher<yarp::rosmsg::std_msgs::String> p;
    bool a = p.topic("/test");
    while (true)
    {
        auto& m = p.prepare();
        m.data =  "publisher number " + std::to_string(i);
        p.write();
        yarp::os::Time::delay(.01);
    }
}

int main(int argc, char* argv[])
{
    yarp::os::Network yarp;

    if (!yarp.checkNetwork())
        return -1;

    int num_threads = 50;
    if (argc > 1)
        num_threads = std::stoi(std::string(argv[1]));

    std::vector<std::thread*> t;
    for (int i = 0; i < num_threads; ++i)
        t.emplace_back(new std::thread(std::bind(&_threadRoutine, i)));

    while (true)
        yarp::os::Time::delay(1);
}

Expected behavior Undocumented

Configuration (please complete the following information): Should not affect the bug reproduction (apart from the fact that Windows does not spawn address conflicts)

Additional context Related issue: robotology/yarp-ros#17