0

I have a problem in multi-threading. Whenever I create a new thread for a state machine, and during the transition from one state to other state. In one of the states "ho_preparation_state" , the state machine has to call a function to asynchronously send a request message and I assign a handler for the response as following:

void src_transaction::run()
{
ho_preparation_state:
{
    // Serialize a MIH N2N_HO_Commit Request
    m << mih::request(mih::request::n2n_ho_commit)
        & mih::tlv_mobile_node_mihf_id(mobile_id)
        & mih::tlv_mn_link_id(mn_addr)
        & mih::tlv_poa(poa_addr)
        & mih::tlv_request_resource_set(request_res);

    // The destination is the target Cloud-Server
    m.destination(dst);

    // The handler is n2n_ho_commit_confirm_handler
    mMihf->async_send(m, boost::bind(&src_transaction::n2n_ho_commit_confirm_handler, this, _1, _2));
    goto ho_commit_confirm_state;
}
  }

The handler is part of the State Machine class "src_transaction":

void src_transaction::n2n_ho_commit_confirm_handler(mih::message &msg, const boost::system::error_code &ec)
{
if (ec)
{
    log_(0, __FUNCTION__, " error: ", ec.message());
    return;
}

mih::status         st;
mih::id             mobile_id;                  // Mobile node MIHF ID TLV
mih::link_tuple_id  target_id;;
mih::asgn_res_set   res_set;

// Deserialize the received MIH message
msg >> mih::confirm()
    & mih::tlv_status(st)                       // Status of operation.
    & mih::tlv_mobile_node_mihf_id(mobile_id)
    & mih::tlv_link_identifier(target_id)
    & mih::tlv_assigned_resource_set(res_set);

log_(0, "has received a N2N_Handover_Commit.Confirm with status ", st.get(), " For Mobile IP=", mobile_id.to_string());

if (st == mih::status_success)
{
    ho_commit_confirm_received = true;
    run();
}
}

I found out, that when the state machine makes the callback. It changes back to the main thread. For example the main thread which is running everything has PID=0x267890, when a new State machine thread is created, it will have new PID=0x267B90. During all the transitions, whenever I print out the PID its 0x267B90, but when the handler is called, the PID which is running it is the main thread's PID ,PID=0x267890.

So why this is happening? Is it maybe something related to the implementation of the async_send? Or is it something wrong I did.

Thanks a lot.

IoT
  • 607
  • 1
  • 11
  • 23
  • If my assumption is right, can you please add the [tag:boost-asio] tag and clarify what mMihf is? – sehe Mar 16 '14 at 00:22

1 Answers1

0

Assuming that mMihf is a boost::asio::io_service, the callback will be invoked on the thread that is running the io_service::run().

If more than 1 thread is running the io_service, then one of these threads will receive the callback execution.

If you want more control either

  • restrict the io_service to a single thread
  • use a separate io_service (e.g. ui_service for the ui thread, workers_service for worker threads). Think of scalability requirements here, though
  • use Boost Asio strands (see here for background: Why do I need strand per connection when using boost::asio?)
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks a lot @sehe, MIHF is a part of an open source tool called "ODTONE" [link](http://helios.av.it.pt/projects/odtone/) When you create this object, you have to pass the ios_Service to it. And the i_service was run from the main thread. Now actually all my previous posts are solved. I will check the strand topic and come back to you. – IoT Mar 16 '14 at 01:05
  • I read the strand, as what I understood it's for ensuring the sequence of operations in multi-threading. So my question what does it enefit me in my case, if the callback is returning back to the main thread? Currently I solved this issue by having a conditional variable and searching again for the thread which was suspended. Second what's the difference between defining multiple io_service for each thread, and generating multiple threads from one io_service. Thanks a lot. – IoT Mar 16 '14 at 14:26