views:

683

answers:

2

Im new to network programming and in particular to async-processes. Start also new with the boost-lib

Im implementing a class, to access an imap-server. I can send and receive the commands and the response, in general

The response is queued in a dequeue inside the class. I put simple the response lines in the queue, for further processing.

What's now the best way to process the queued response?

  1. An extra thread to check(time based) the queue, for new entries?
  2. Each time a new entries is pushed to the queue make some callback?
    How can I implement and integrate this callback?

Maybe someone have a short example for this.

Thanks

+1  A: 

One possible way to implement the queue processor is to use a signaling semaphore.

For example the pthread condition type (description) if you are on a POSIX compliant platform.

You could have N number of "queue-processing threads" waiting in the background.

  1. Each time something is shoved in the queue your semaphore sends it's signal.

  2. The signal is received by sleeping "queue-processing" threads which start processing the queue because they know they have data.

  3. When the thread finishes processing it's data, check queue size to see if it should grab something else, if not then go back to waiting for a signal.

Brian Gianforcaro
+1  A: 

Each time a new entries is pushed to the queue make some callback? How can I implement and integrate this callback?

I assume you are working with single thread synchronous connection.

Do something like that:

class worker {

 deque<message> messages;
 bool is_writing_;

 push_message(message msg) {
  messages.push_back(msg);
  notify();
 }

 void notify()
 {
  if(!is_writing_) {
   is_writing_=true;
   init();
  }
 } 

 void init()
 {
  if(messages.empty()) { is_writing_=false; return; }
  messamge msg=messages.pop();
  convert_to_vector(v);
  async_write(socket,buffer(v),
   boost::bind(&worker::complete,this,placehoders::error));
 }
 void complete(error_code const &e)
 {
  if(!e) {
      init();
  }
  else { cleanup(); }
 }

};

Note!!!

This is single thread implementation. If you want notify from other thread you should not call some_worker->push_message(msg), you should use iosrvice:

service.post(boost::bind(&worker::push_message,some_worker,msg));

And push_message would be called from the same thread that runs ioservice.

Artyom
The connection self is asynchron, and the worker I think should be then in another thread, so I give you example a try to see how far I come.I've an error in my thinking of how I should start. Now its a little bit more clear, put the response in an new object that do the work. I put it only the the queuethanks
ingo.thierack
I sugget take a look on the examples and try to implement some simple TCP/IP clinet/server to understand how stuff works, then try doing real things. I must note that "worker" may be misleading -- it is more like an object that holds socket and does all tcp/ip over it.
Artyom