2
votes

I am building an application based on an example on the boost website. These are the relevant definitions to know of:

typedef boost::shared_ptr&lt connection &gt connection_ptr;
std::set&lt connection_ptr&gt connections_;
std::vector&lt boost::shared_ptr&lt boost::thread&gt &gt threads;

where connection is a class.

In one of the files, connection_manager.cpp, they are doing like this:

void connection_manager::start(connection_ptr c)
{
  connections_.insert(c);
  c->start();
}

Now, I want to start every new connection in a separate thread due to my program structure. So I have modified the above according to:

void connection_manager::start(connection_ptr c)
{
    boost::shared_ptr&lt boost::thread &gt thread(new boost::thread(
                        boost::bind(&connection::start, c)));

    // push the newely created thread into the vector
    threads.push_back(thread);

    // save the connection in our set
    connections_.insert(c);
}

My problem, and hence this question, is when I want to only one of these connection_ objects. In the link provided earlier, they do like this:

void connection_manager::stop(connection_ptr c)
{
    connections_.erase(c);
    c->stop();

    // find the connection in among the threads and join that thread
}

But as the comment above suggests, how do I find c amongst all the threads and stop only that thread. I want to call the join() function for that thread.


Update:

I think that this is actually what I really want to have! So I declare my variable as

std::map &lt connection_ptr, boost::shared_ptr &lt boost::thread &gt &gt threads;

But then, how do I create a new tread, same way as before? Like:

boost::shared_ptr &lt boost::thread &gt thread(new boost::thread(
                        boost::bind(&connection::start, c)));

But what is then the next step? Sorry for being confused... :-)

2

2 Answers

2
votes

If you use a map (or other associative container) instead of vector you can maintain an association between connections and threads:

std::map<connection_ptr, boost::shared_ptr<boost::thread> > threads;

allows you to write:

threads[connection] = thread;

instead of the push_back call after you create the thread and then:

threads[connection]->stop();

later on when you want to look it up.

NB: As a general comment applications which maintain a 1:1 mapping between threads and network connections are quite vulnerable to Denial of Service (DoS) attacks.

1
votes

If your connection is always bound to a thread, it would make sense to simply have the connection object point to the thread it's running in and move the logic of starting in a thread to the connection class itself.