RaGa__M
RaGa__M

Reputation: 2571

How io_service matches a completion event with a completion handler

I have been reading boost asio docs, Specifically about Proactor design.

when I came across this tittle

The Proactor Design Pattern: Concurrency Without Threads

What I sort of understand is, The users of asio don't need to create additional threads for doing an asynchronous IO as threads are already prevail in the form of Asynchronous Operation Processor in this pattern.

So just to confirm the io_service is going to act as a proactor(fetch the completion event and dispatch it to the completion handler)

Whenever an async process got initiated it is going to take care by a background thread.

socket.async_connect(server_endpoint, your_completion_handler);

Is the below sequence correct?

1) Connect operation going to be handled by a thread.

2) Completion_handler going to be pushed into some queue (or any DS)?.

3) Once the async_connect has finished, It's result/Errorcode will be placed in a completion event queue.

4) The proactor(io_service?)fetch the completion event maps it to the handler

I just wonder how this mapping has been done, As the Asynchronous Operation Processor has made out of threads(doesn't it ?) anything that finishes first will trigger a completion event and how the io_service will know which completion handler should be called for this event and which one for that event( I thought of looking into the implementation, But to me it seems a bit heavy now.)

Upvotes: 0

Views: 500

Answers (1)

The Quantum Physicist
The Quantum Physicist

Reputation: 26286

io_service is basically a function queue. When you instantiate your socket, you pass a reference of io_service to it. Now when you do the call:

socket.async_connect(server_endpoint, your_completion_handler);

You're starting an asynchronous operation, where ASIO pushes a synchronous function to io_service, which is your function queue. The function that ASIO pushes to io_service contains your handler. When the time comes, io_service pops an element (a function) from the queue and does the operation for you, and finally calls your handler with the result from that operation.

A little more info on queuing: If you start the io_service object (with io_service::run()) in one thread, then you'll have a real serial queue where everything is executed in order. On the other hand, if you call io_service::run() on multiple threads, the queue will be distributed on these threads. Non-blocking thread-safety can be achieved using ASIO's strand.

Upvotes: 1

Related Questions