thinking asynchronously: designing applications with boost...the basics asio::io_service io_service;...
TRANSCRIPT
![Page 1: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/1.jpg)
Thinking Asynchronously:Designing Applications with Boost.Asio
Chris Kohlhoff
![Page 2: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/2.jpg)
The Basics
![Page 3: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/3.jpg)
The BasicsThe Basics
asio::io_service io_service;
// ...
tcp::socket socket(io_service);
// ...
socket.async_connect( server_endpoint, your_completion_handler);
// ...
io_service.run();
![Page 4: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/4.jpg)
The BasicsThe Basics
asio::io_service io_service;
// ...
tcp::socket socket(io_service);
// ...
socket.async_connect( server_endpoint, your_completion_handler);
// ...
io_service.run();
![Page 5: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/5.jpg)
The BasicsThe Basics
asio::io_service io_service;
// ...
tcp::socket socket(io_service);
// ...
socket.async_connect( server_endpoint, your_completion_handler);
// ...
io_service.run();
I/O Object
![Page 6: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/6.jpg)
The BasicsThe Basics
asio::io_service io_service;
// ...
tcp::socket socket(io_service);
// ...
socket.async_connect( server_endpoint, your_completion_handler);
// ...
io_service.run();
Asynchronousoperation
![Page 7: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/7.jpg)
The BasicsThe Basics
asio::io_service io_service;
// ...
tcp::socket socket(io_service);
// ...
socket.async_connect( server_endpoint, your_completion_handler);
// ...
io_service.run();
![Page 8: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/8.jpg)
The BasicsThe Basics
socket.async_connect( server_endpoint, your_completion_handler);
![Page 9: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/9.jpg)
The BasicsThe Basics
socket.async_connect( server_endpoint, your_completion_handler);
I/O Object
![Page 10: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/10.jpg)
The BasicsThe Basics
socket.async_connect( server_endpoint, your_completion_handler);
Initiatingfunction
![Page 11: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/11.jpg)
The BasicsThe Basics
socket.async_connect( server_endpoint, your_completion_handler);
Arguments
![Page 12: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/12.jpg)
socket.async_connect( server_endpoint, your_completion_handler);
The BasicsThe Basics
Completionhandler
![Page 13: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/13.jpg)
socket.async_connect( server_endpoint, your_completion_handler);
The BasicsThe Basics
void your_completion_handler( const boost::system::error_code& ec);
Completionhandler
![Page 14: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/14.jpg)
socket.async_connect( server_endpoint, your_completion_handler);
The BasicsThe Basics
io_service
Operating System
![Page 15: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/15.jpg)
socket.async_connect( server_endpoint, your_completion_handler);
The BasicsThe Basics
io_service
Operating System
work
handler
creates
![Page 16: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/16.jpg)
The BasicsThe Basics
io_service
Operating System
work
handler
io_service.run()
![Page 17: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/17.jpg)
The BasicsThe Basics
io_service
Operating System
work
handler
io_service.run()
notifies
![Page 18: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/18.jpg)
The BasicsThe Basics
io_service
Operating System
work
handler
io_service.run()dequeues
![Page 19: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/19.jpg)
The BasicsThe Basics
io_service
Operating System
work
handler
io_service.run()
result
handler
dequeues
![Page 20: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/20.jpg)
The BasicsThe Basics
io_service
Operating System
io_service.run()
result
handler
your_completion_handler(ec);
![Page 21: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/21.jpg)
The BasicsThe Basics
io_service
work
handler
timerserialport
socketsocket
timer
work
handler
work
handler
work
handler
work
handler
![Page 22: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/22.jpg)
The BasicsThe Basics
io_service
work
handler
work
handler
work
handler
work
handler
work
handler
io_service.run()
![Page 23: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/23.jpg)
The BasicsThe Basics
io_service
work
handler
work
handler
work
handler
work
handler
work
handler
io_service.run()dequeues
![Page 24: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/24.jpg)
The BasicsThe Basics
io_service
work
handler
work
handler
work
handler
work
handler
io_service.run()
work
handler
result
handler
dequeues
![Page 25: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/25.jpg)
The BasicsThe Basics
io_service
work
handler
work
handler
work
handler
work
handler
io_service.run()
result
handler
![Page 26: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/26.jpg)
The BasicsThe Basics
io_service
work
handler
work
handler
work
handler
work
handler
io_service.run()
![Page 27: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/27.jpg)
The BasicsThe Basics
io_service
work
handler
work
handler
work
handler
work
handler
io_service.run()
dequeues
![Page 28: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/28.jpg)
The BasicsThe Basics
io_service
work
handlerwork
handler
work
handler
io_service.run()
work
handler
result
handler
dequeues
![Page 29: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/29.jpg)
The BasicsThe Basics
io_service
work
handlerwork
handler
work
handler
io_service.run()
result
handler
![Page 30: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/30.jpg)
The BasicsThe Basics
io_service
work
handlerwork
handler
work
handler
io_service.run()
result
handler
socket.async_read_some(...);
![Page 31: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/31.jpg)
The BasicsThe Basics
io_service
work
handlerwork
handler
work
handler
io_service.run()
result
handler
socket.async_read_some(...);
![Page 32: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/32.jpg)
The BasicsThe Basics
io_service
work
handlerwork
handler
work
handler
io_service.run()
result
handler
socket.async_read_some(...);
work
handler
creates
![Page 33: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/33.jpg)
The BasicsThe Basics
io_service
work
handler
work
handlerwork
handler
work
handler
io_service.run()
![Page 34: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/34.jpg)
The BasicsThe Basics
socket.async_connect( server_endpoint, your_completion_handler);
Completionhandler
Asynchronousoperation
![Page 35: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/35.jpg)
The BasicsThe Basics
socket.async_connect(...);
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
![Page 36: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/36.jpg)
Challenges:● Object lifetimes● Thinking asynchronously● Threads● Managing complexity
![Page 37: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/37.jpg)
Object Lifetimes
![Page 38: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/38.jpg)
Object LifetimesObject Lifetimes
socket.async_connect(server_endpoint, your_completion_handler_1);
socket.async_read_some(buffers, your_completion_handler_2);
async_write(socket, buffers, your_completion_handler_3);
acceptor.async_accept(socket, peer_endpoint, your_completion_handler_4);
![Page 39: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/39.jpg)
Object LifetimesObject Lifetimes
socket.async_connect(server_endpoint, your_completion_handler_1);
socket.async_read_some(buffers, your_completion_handler_2);
async_write(socket, buffers, your_completion_handler_3);
acceptor.async_accept(socket, peer_endpoint, your_completion_handler_4);
By value
![Page 40: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/40.jpg)
Object LifetimesObject Lifetimes
socket.async_connect(server_endpoint, your_completion_handler_1);
socket.async_read_some(buffers, your_completion_handler_2);
async_write(socket, buffers, your_completion_handler_3);
acceptor.async_accept(socket, peer_endpoint, your_completion_handler_4);
By constreference
![Page 41: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/41.jpg)
socket.async_connect(server_endpoint, your_completion_handler_1);
socket.async_read_some(buffers, your_completion_handler_2);
async_write(socket, buffers, your_completion_handler_3);
acceptor.async_accept(socket, peer_endpoint, your_completion_handler_4);
Object LifetimesObject Lifetimes
By non-constreference
![Page 42: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/42.jpg)
socket.async_connect(server_endpoint, your_completion_handler_1);
socket.async_read_some(buffers, your_completion_handler_2);
async_write(socket, buffers, your_completion_handler_3);
acceptor.async_accept(socket, peer_endpoint, your_completion_handler_4);
Object LifetimesObject Lifetimes
thispointer
![Page 43: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/43.jpg)
Object LifetimesObject Lifetimes
void do_write(){ std::string message = ...; async_write(socket, asio::buffer(message), your_completion_handler);}
What's wrong with this code?
![Page 44: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/44.jpg)
Object LifetimesObject Lifetimes
socket.async_connect(...);
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
![Page 45: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/45.jpg)
Object LifetimesObject Lifetimes
int main{ asio::io_service io_service;
connection conn(io_service);
io_service.run();}
![Page 46: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/46.jpg)
Object LifetimesObject Lifetimes
Question:● When does object lifetime begin and end?
![Page 47: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/47.jpg)
Object LifetimesObject Lifetimes
class connection{ tcp::socket socket_; vector<unsigned char> data_; // ... ~connection() { socket_.close(); } // ...};
What's wrong with this code?
![Page 48: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/48.jpg)
Object LifetimesObject Lifetimes
socket.async_connect(...);
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
![Page 49: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/49.jpg)
Object LifetimesObject Lifetimes
io_service
work
handlerwork
handler
work
handler
socket.async_read_some(...);
work
handler
creates
![Page 50: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/50.jpg)
Object LifetimesObject Lifetimes
socket.async_connect(server_endpoint, your_completion_handler_1);
socket.async_read_some(buffers, your_completion_handler_2);
async_write(socket, buffers, your_completion_handler_3);
acceptor.async_accept(socket, peer_endpoint, your_completion_handler_4);
By value
![Page 51: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/51.jpg)
Object LifetimesObject Lifetimes
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ...};
![Page 52: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/52.jpg)
Object LifetimesObject Lifetimes
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... void start_write() { async_write(socket_, asio::buffer(data_), bind(&connection::handle_write, shared_from_this(), _1, _2)); } // ...};
![Page 53: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/53.jpg)
Object LifetimesObject Lifetimes
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... void stop() { socket_.close(); } // ...};
![Page 54: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/54.jpg)
Object LifetimesObject Lifetimes
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... void start() { socket_.async_connect(...); } // ...};
![Page 55: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/55.jpg)
Object LifetimesObject Lifetimes
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... void start() { socket_.async_connect(...); } // ...};
// ...
make_shared<connection>(...)->start();
![Page 56: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/56.jpg)
Thinking Asynchronously
![Page 57: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/57.jpg)
Thinking AsynchronouslyThinking Asynchronously
class connection{ tcp::socket socket_; vector<unsigned char> data_; // ... ~connection() { socket_.close(); } // ...};
![Page 58: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/58.jpg)
Thinking AsynchronouslyThinking Asynchronously
double Now(){ timeval tv; gettimeofday(&tv, 0); return time(0) + tv.tv_usec / 1000000.0;}
What's wrong with this code?
![Page 59: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/59.jpg)
Thinking AsynchronouslyThinking Asynchronously
Operating System
gettimeofday() time()
![Page 60: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/60.jpg)
Thinking AsynchronouslyThinking Asynchronously
if (socket.IsConnected()){ socket.Write(data);}
What's wrong with this code?
![Page 61: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/61.jpg)
Thinking AsynchronouslyThinking Asynchronously
Operating System
IsConnected() Write()
TCP State Machine
![Page 62: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/62.jpg)
Thinking AsynchronouslyThinking Asynchronously
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... void stop() { socket_.close(); } // ...};
![Page 63: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/63.jpg)
Thinking AsynchronouslyThinking Asynchronously
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... void handle_write(error_code ec) { if (!socket_.is_open()) return; // ... } // ...};
![Page 64: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/64.jpg)
Thinking AsynchronouslyThinking Asynchronously
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ... bool is_stopped() const { return !socket_.is_open(); } // ...};
![Page 65: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/65.jpg)
Thinking AsynchronouslyThinking Asynchronously
class connection : enable_shared_from_this<connection>{ // ... void start(); void stop(); bool is_stopped() const; // ...};
![Page 66: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/66.jpg)
Threads
![Page 67: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/67.jpg)
ThreadsThreads
Spectrum of approaches:● Single-threaded● Use threads for long-running tasks● Multiple io_services, one thread each● One io_service, many threads
![Page 68: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/68.jpg)
ThreadsThreads
Single-threaded:● Preferred starting point● Keep handlers short and non-blocking
![Page 69: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/69.jpg)
ThreadsThreads
Use threads for long running tasks:● Logic stays in main thread● Pass work to background thread● Pass result back to main thread
![Page 70: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/70.jpg)
ThreadsThreads
io_service
work
handlerwork
handler
work
handler
io_service.run()
![Page 71: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/71.jpg)
ThreadsThreads
work
handlerwork
handler
work
handler
launch task in threadwork
handler
Thread
creates
![Page 72: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/72.jpg)
ThreadsThreads
io_service
work
handlerwork
handler
work
handler
io_service.run()
Thread
work
handler
![Page 73: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/73.jpg)
ThreadsThreads
io_service
work
handlerwork
handler
work
handler
io_service.run()
Thread
work
handler
work
result
handler
posts
![Page 74: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/74.jpg)
ThreadsThreads
io_service
work
handlerwork
handler
work
handler
io_service.run()
result
handler
work
result
handler
dequeues
![Page 75: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/75.jpg)
ThreadsThreads
io_service
work
handlerwork
handler
work
handler
io_service.run()
result
handler
![Page 76: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/76.jpg)
ThreadsThreads
work
handler
asio::io_service::work
![Page 77: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/77.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... asio::io_service& io_service_; // ... void start_work() { async( bind(&connection::do_work, shared_from_this(), ...args..., asio::io_service::work(io_service_))); } // ...};
![Page 78: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/78.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... asio::io_service& io_service_; // ... void do_work(...args..., asio::io_service::work) { // long running task ... io_service_.post( bind(&connection::work_done, shared_from_this(), ...result...)); } // ...};
![Page 79: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/79.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... void work_done(...result...) { // ... } // ...};
![Page 80: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/80.jpg)
ThreadsThreads
asio::io_service async_io_service;asio::io_service::work async_work(async_io_service);boost::thread async_thread( bind(&asio::io_service::run, &async_io_service));
// ...
template <class Handler>void async(Handler h){ async_io_service.post(h);}
![Page 81: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/81.jpg)
ThreadsThreads
Multiple io_services, one thread each:● Logic stays in each object's “home” thread● Keep handlers short and non-blocking● Objects communicate via “message passing”
![Page 82: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/82.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... asio::io_service& io_service_; // ... void do_foobar(...args...) { ... }public: void foobar(...args...) { io_service_.post( bind(&connection::do_foobar, shared_from_this(), ...args...)); } // ...};
![Page 83: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/83.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... asio::io_service& io_service_; // ... void do_foobar(...args...) { ... }public: void foobar(...args...) { io_service_.dispatch( bind(&connection::do_foobar, shared_from_this(), ...args...)); } // ...};
![Page 84: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/84.jpg)
ThreadsThreads
One io_service, multiple threads:● Handlers can be called on any thread● Perform logic in strands● Objects communicate via “message passing”
![Page 85: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/85.jpg)
ThreadsThreads
Strands:● Non-concurrent invocation of handlers● May be implicit or explicit
![Page 86: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/86.jpg)
ThreadsThreads
connectionsocket.async_connect(... );
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
connectionsocket.async_connect(... );
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
connectionsocket.async_connect(... );
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
connectionsocket.async_connect(... );
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
connectionsocket.async_connect(... );
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
connectionsocket.async_connect(... );
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
![Page 87: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/87.jpg)
ThreadsThreads
socket.async_connect(...);
if (!ec){ socket.async_read_some(...);}
if (!ec){ async_write(socket, ...);}
![Page 88: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/88.jpg)
ThreadsThreads
if (!ec){ socket1.async_read_some(...); socket2.async_read_some(...);}
if (!ec){ async_write(socket1, ...);}
if (!ec){ socket2.async_read_some(...);}
if (!ec){ socket2.async_connect(...);}
if (!ec){ async_write(socket2, ...);}
if (!ec){ socket1.async_read_some(...);}
acceptor.async_accept(socket1, ...);
![Page 89: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/89.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; asio::io_service::strand strand_; // ... void start_write() { async_write(socket_, asio::buffer(data_), strand_.wrap( bind(&connection::handle_write, shared_from_this(), _1, _2))); } // ...};
![Page 90: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/90.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... asio::io_service::strand strand_; // ... void do_foobar(...args...) { ... }public: void foobar(...args...) { strand_.post( bind(&connection::do_foobar, shared_from_this(), ...args...)); } // ...};
![Page 91: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/91.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ // ... asio::io_service::strand strand_; // ... void do_foobar(...args...) { ... }public: void foobar(...args...) { strand_.dispatch( bind(&connection::do_foobar, shared_from_this(), ...args...)); } // ...};
![Page 92: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/92.jpg)
ThreadsThreads
if (!ec){ socket1.async_read_some(...); socket2.async_read_some(...);}
if (!ec){ async_write(socket1, ...);}
if (!ec){ socket2.async_read_some(...);}
if (!ec){ socket2.async_connect(...);}
if (!ec){ async_write(socket2, ...);}
if (!ec){ socket1.async_read_some(...);}
acceptor.async_accept(socket1, ...);
![Page 93: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/93.jpg)
ThreadsThreads
if (!ec){ socket1.async_read_some(...); socket2.async_read_some(...);}
if (!ec){ async_write(socket1, ...);}
if (!ec){ socket2.async_read_some(...);}
if (!ec){ socket2.async_connect(...);}
if (!ec){ async_write(socket2, ...);}
if (!ec){ socket1.async_read_some(...);}
acceptor.async_accept(socket1, ...);
![Page 94: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/94.jpg)
ThreadsThreads
if (!ec){ socket1.async_read_some(...); socket2.async_read_some(...);}
if (!ec){
}
if (!ec){ socket2.async_read_some(...);}
if (!ec){ socket2.async_connect(...);}
if (!ec){
}
if (!ec){ socket1.async_read_some(...);}
acceptor.async_accept(socket1, ...);
socket2.async_write_some(...)
socket1.async_write_some(...)
![Page 95: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/95.jpg)
ThreadsThreads
template <class Handler>struct mutex_wrapper{ mutex& mutex_; Handler handler_;
mutex_wrapper(mutex& m, Handler h) : mutex_(m), handler_(h) {}
void operator()() { handler_(); }
template <class Arg1> void operator()(Arg1 a1) { handler_(a1); }
template <class Arg1, class Arg2> void operator()(Arg1 a1, Arg2 a2) { handler_(a1, a2); }};
![Page 96: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/96.jpg)
ThreadsThreads
template <class Handler>mutex_wrapper<Handler> wrap(mutex& m, Handler h){ return mutex_wrapper<Handler>(m, h);}
![Page 97: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/97.jpg)
ThreadsThreads
template <class Function, class Handler>void asio_handler_invoke( Function f, mutex_wrapper<Handler>* w){ mutex::scoped_lock lock(w->mutex_); f();}
Invocationhook
![Page 98: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/98.jpg)
ThreadsThreads
class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; mutex mutex_; // ... void start_write() { async_write(socket_, asio::buffer(data_), wrap(mutex_, bind(&connection::handle_write, shared_from_this(), _1, _2))); } // ...};
![Page 99: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/99.jpg)
Managing Complexity
![Page 100: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/100.jpg)
Managing ComplexityManaging Complexity
Approaches:● Pass the buck● The buck stops here
![Page 101: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/101.jpg)
Managing ComplexityManaging Complexity
Approaches:● Pass the buck
● Functions● Classes
● The buck stops here● Classes
![Page 102: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/102.jpg)
Managing ComplexityManaging Complexity
if (!ec){ socket1.async_read_some(...); socket2.async_read_some(...);}
if (!ec){ async_write(socket1, ...);}
if (!ec){ socket2.async_read_some(...);}
if (!ec){ socket2.async_connect(...);}
if (!ec){ async_write(socket2, ...);}
if (!ec){ socket1.async_read_some(...);}
acceptor.async_accept(socket1, ...);
![Page 103: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/103.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void async_transfer( tcp::socket& socket1, tcp::socket& socket2, asio::mutable_buffers_1 working_buffer, Handler handler);
A “pass the buck” function:
Also known as a“composed operation”
![Page 104: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/104.jpg)
Managing ComplexityManaging Complexity
Initiating function
if (!ec){ socket1.async_read_some(...);}else{ handler(ec);}
if (!ec){ async_write(socket2, ...);}else{ handler(ec);}
![Page 105: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/105.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void do_read( tcp::socket& socket1, tcp::socket& socket2, asio::mutable_buffers_1 working_buffer, tuple<Handler> handler, const error_code& ec){ if (!ec) { socket1.async_read_some( working_buffer, bind(&do_write<Handler>, ref(socket1), ref(socket2), working_buffer, handler, _1, _2)); } else { get<0>(handler)(ec); }}
![Page 106: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/106.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void do_write( tcp::socket& socket1, tcp::socket& socket2, asio::mutable_buffers_1 working_buffer, tuple<Handler> handler, const error_code& ec, size_t length){ if (!ec) { asio::async_write(socket2, asio::buffer(working_buffer, length), bind(&do_read<Handler>, ref(socket1), ref(socket2), working_buffer, handler, _1)); } else { get<0>(handler)(ec); }}
![Page 107: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/107.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void async_transfer( tcp::socket& socket1, tcp::socket& socket2, asio::mutable_buffers_1 working_buffer, Handler handler){ do_read( socket1, socket2, working_buffer, make_tuple(handler), error_code());}
![Page 108: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/108.jpg)
Managing ComplexityManaging Complexity
Initiating function
if (!ec){ if (do_read) { do_read = false; socket1.async_read_some(...); } else { do_read = true; async_write(socket2, ...); }}else{ handler(ec);}
![Page 109: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/109.jpg)
Managing ComplexityManaging Complexity
template <class Handler>struct transfer_op{ bool do_read; tcp::socket& socket1; tcp::socket& socket2; asio::mutable_buffer working_buffer; Handler handler; void operator()(const error_code& ec, size_t length);};
![Page 110: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/110.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void transfer_op::operator()(const error_code& ec, size_t length){ if (!ec) { if (do_read) { do_read = false; socket1.async_read_some(working_buffer, *this); } else { do_read = true; asio::async_write(socket2, asio::buffer(working_buffer, length), *this); } } else { handler(ec); }};
![Page 111: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/111.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void async_transfer( tcp::socket& socket1, tcp::socket& socket2, asio::mutable_buffers_1 working_buffer, Handler handler){ transfer_op<Handler> op = { true, socket1, socket2, working_buffer, handler }; op(error_code(), 0);}
![Page 112: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/112.jpg)
Managing ComplexityManaging Complexity
if (!ec){ async_transfer(socket1, socket2, buffer1, ...); async_transfer(socket2, socket1, buffer2, ...);}
if (!ec){ socket2.async_connect(...);}
acceptor.async_accept(socket1, ...);
... ...
![Page 113: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/113.jpg)
Managing ComplexityManaging Complexity
template <class Function, class Handler>void asio_handler_invoke(const Function& f, transfer_op<Handler>* op){ using boost::asio::asio_handler_invoke; asio_handler_invoke(f, addressof(op->handler));}
Invocationhook
![Page 114: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/114.jpg)
Managing ComplexityManaging Complexity
template <class Handler>void* asio_handler_allocate(size_t n, transfer_op<Handler>* op){ using boost::asio::asio_handler_allocate; return asio_handler_allocate(n, addressof(op->handler));}
template <class Handler>void asio_handler_deallocate(void* p, size_t n, transfer_op<Handler>* op){ using boost::asio::asio_handler_deallocate; asio_handler_deallocate(p, n, addressof(op->handler));}
Allocationhooks
![Page 115: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/115.jpg)
Managing ComplexityManaging Complexity
template <class Stream1, class Stream2, class Handler>void async_transfer( Stream1& stream1, Stream2& stream2, asio::mutable_buffers_1 working_buffer, Handler handler);
![Page 116: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/116.jpg)
Managing ComplexityManaging Complexity
if (!ec){ async_transfer(socket1, socket2, buffer1, ...); async_transfer(socket2, socket1, buffer2, ...);}
if (!ec){ socket2.async_connect(...);}
acceptor.async_accept(socket1, ...);
... ...
![Page 117: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/117.jpg)
Managing ComplexityManaging Complexity
template <class Stream1, class Stream2>class proxy{ Stream1 up_; Stream2 down_; vector<unsigned char> buffer1_, buffer2_;
public: proxy(...); Stream1& up() { return up_; } Stream2& down() { return down_; }
template <class Handler> void async_run_upstream(Handler handler);
template <class Handler> void async_run_downstream(Handler handler);};
A “pass the buck” class:
![Page 118: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/118.jpg)
Managing ComplexityManaging Complexity
if (!ec){ proxy.async_run_downstream(...); proxy.async_run_upstream(...);}
if (!ec){ proxy.up().async_connect(...);}
acceptor.async_accept(proxy.down(), ...);
... ...
![Page 119: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/119.jpg)
Managing ComplexityManaging Complexity
if (!ec){ proxy.async_run_downstream(...); proxy.async_run_upstream(...);}
if (!ec){ proxy.up().async_connect(...);}
acceptor.async_accept(proxy.down(), ...);
... ... Caller must guaranteeobject lifetime until alloperations complete
![Page 120: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/120.jpg)
Managing ComplexityManaging Complexity
template <class Stream1, class Stream2>class proxy{ Stream1 up_; Stream2 down_; vector<unsigned char> buffer1_, buffer2_;
public: proxy(...); Stream1& up() { return up_; } Stream2& down() { return down_; }
template <class Handler> void async_run(Handler handler);};
Alternative “pass the buck” class:
![Page 121: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/121.jpg)
Managing ComplexityManaging Complexity
if (!ec){ proxy.async_run(...);}
if (!ec){ proxy.up().async_connect(...);}
...
acceptor.async_accept(proxy.down(), ...);
![Page 122: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/122.jpg)
Managing ComplexityManaging Complexity
![Page 123: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/123.jpg)
Managing ComplexityManaging Complexity
![Page 124: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/124.jpg)
Managing ComplexityManaging Complexity
template <class Stream1, class Stream2>class proxy : enable_shared_from_this<proxy<Stream1, Stream2> >{ asio::io_service strand_; Stream1 up_; Stream2 down_; vector<unsigned char> buffer1_, buffer2_;
void do_start(); void handle_transfer(const error_code& ec); public: proxy(...); Stream1& up() { return up_; } Stream2& down() { return down_; }
void start();};
The buck stops here:
![Page 125: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/125.jpg)
Managing ComplexityManaging Complexity
template <class Stream1, class Stream2>void proxy::start(){ strand_.dispatch( bind(&proxy::do_start, this->shared_from_this()));}
template <class Stream1, class Stream2>void proxy::do_start(){ async_transfer(stream1_, stream2_, buffer1_, strand_.wrap( bind(&proxy::handle_transfer, this->shared_from_this(), _1))); async_transfer(stream2_, stream1_, buffer2_, strand_.wrap( bind(&proxy::handle_transfer, this->shared_from_this(), _1)));}
![Page 126: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/126.jpg)
Managing ComplexityManaging Complexity
class connection : enable_shared_from_this<connection>{ // ... void start(); void stop(); bool is_stopped() const; // ...};
Remind you of anything?
![Page 127: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/127.jpg)
Managing ComplexityManaging Complexity
Operations on
I/O Objects
The buck stops here
Passing the buck
![Page 128: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/128.jpg)
Managing ComplexityManaging Complexity
int main{ asio::io_service io_service;
connection conn(io_service);
io_service.run();}
+
=No reference countingAll memory committed up frontPossibility of zero allocations in steady state
![Page 129: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/129.jpg)
Summary
![Page 130: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/130.jpg)
SummarySummary
Challenges:● Object lifetimes● Thinking asynchronously● Threads● Managing complexity
![Page 131: Thinking Asynchronously: Designing Applications with Boost...The Basics asio::io_service io_service; // ... tcp::socket socket(io_service); // ... socket.async_connect(server_endpoint,](https://reader036.vdocuments.mx/reader036/viewer/2022063014/5fcec6e8566e8c39ac414c76/html5/thumbnails/131.jpg)
SummarySummary
Guidelines:● Know your object lifetime rules● Assume asynchronous change, but know
what's under your control● Prefer to keep your logic single-threaded● Pass the buck as often as you can