Sending data in second thread with Mongoose server

1.4k Views Asked by At

I'm trying to create a multithread server application using mongoose web server library. I have main thread serving connections and sending requests to processors that are working in their own threads. Then processors place results into queue and queue observer must send results back to clients.

Sources are looking that way:

Here I prepare the data for processors and place it to queue.

typedef std::pair<struct mg_connection*, const char*> TransferData; 


int server_app::event_handler(struct mg_connection *conn, enum mg_event ev)
{
    Request req;
    if (ev == MG_AUTH) 
        return MG_TRUE;   // Authorize all requests
    else if (ev == MG_REQUEST) 
    {
        req = parse_request(conn);
        task_queue->push(TransferData(conn,req.second));
        mg_printf(conn, "%s", "");  // (1)
        return MG_MORE;  // (2)
    }
    else
        return MG_FALSE;  // Rest of the events are not processed
}

And here I'm trying to send the result back. This function is working in it's own thread.

void server_app::check_results()
{
    while(true)
    {
        TransferData res;
        if(!res_queue->pop(res))
        {
            boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
            continue;
        }
        mg_printf_data(res.first, "%s", res.second); // (3)
    }
}

The problem is a client doesn't receive anything from the server.
If I run check_result function manualy in the event_handler after placing a task into the queue and then pass computed result back to event_handler, I'm able to send it to client using mg_printf_data (with returning MG_TRUE). Any other way - I'm not.

What exactly should I change in this sources to make it works?

1

There are 1 best solutions below

0
On

Ok... It looks like I've solved it myself.

I'd been looking into mongoose.c code and an hour later I found the piece of code below:

static void write_terminating_chunk(struct connection *conn) {
   mg_write(&conn->mg_conn, "0\r\n\r\n", 5);
}

static int call_request_handler(struct connection *conn) {
   int result;
   conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
   if ((result = call_user(conn, MG_REQUEST)) == MG_TRUE) {
       if (conn->ns_conn->flags & MG_HEADERS_SENT) {
           write_terminating_chunk(conn);
       }
       close_local_endpoint(conn);
   }
   return result;
} 

So I've tried to do mg_write(&conn->mg_conn, "0\r\n\r\n", 5); after line (3) and now it's working.