131
Thinking Asynchronously: Designing Applications with Boost.Asio Chris Kohlhoff

Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Thinking Asynchronously:Designing Applications with Boost.Asio

Chris Kohlhoff

Page 2: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The Basics

Page 3: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

socket.async_connect( server_endpoint, your_completion_handler);

Page 9: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

socket.async_connect( server_endpoint, your_completion_handler);

I/O Object

Page 10: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

socket.async_connect( server_endpoint, your_completion_handler);

Initiatingfunction

Page 11: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

socket.async_connect( server_endpoint, your_completion_handler);

Arguments

Page 12: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

socket.async_connect( server_endpoint, your_completion_handler);

The BasicsThe Basics

Completionhandler

Page 13: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

socket.async_connect( server_endpoint, your_completion_handler);

The BasicsThe Basics

io_service

Operating System

Page 15: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

Operating System

work

handler

io_service.run()

Page 17: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

Operating System

work

handler

io_service.run()

notifies

Page 18: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

Operating System

work

handler

io_service.run()dequeues

Page 19: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

Operating System

work

handler

io_service.run()

result

handler

dequeues

Page 20: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

Operating System

io_service.run()

result

handler

your_completion_handler(ec);

Page 21: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

work

handler

work

handler

work

handler

work

handler

io_service.run()

Page 27: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

work

handler

work

handler

work

handler

work

handler

io_service.run()

dequeues

Page 28: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

work

handlerwork

handler

work

handler

io_service.run()

result

handler

Page 30: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

io_service

work

handler

work

handlerwork

handler

work

handler

io_service.run()

Page 34: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

socket.async_connect( server_endpoint, your_completion_handler);

Completionhandler

Asynchronousoperation

Page 35: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

The BasicsThe Basics

socket.async_connect(...);

if (!ec){ socket.async_read_some(...);}

if (!ec){ async_write(socket, ...);}

Page 36: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Challenges:● Object lifetimes● Thinking asynchronously● Threads● Managing complexity

Page 37: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object Lifetimes

Page 38: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object LifetimesObject Lifetimes

socket.async_connect(...);

if (!ec){ socket.async_read_some(...);}

if (!ec){ async_write(socket, ...);}

Page 45: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object LifetimesObject Lifetimes

int main{ asio::io_service io_service;

connection conn(io_service);

io_service.run();}

Page 46: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object LifetimesObject Lifetimes

Question:● When does object lifetime begin and end?

Page 47: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object LifetimesObject Lifetimes

socket.async_connect(...);

if (!ec){ socket.async_read_some(...);}

if (!ec){ async_write(socket, ...);}

Page 49: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object LifetimesObject Lifetimes

io_service

work

handlerwork

handler

work

handler

socket.async_read_some(...);

work

handler

creates

Page 50: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Object LifetimesObject Lifetimes

class connection : enable_shared_from_this<connection>{ tcp::socket socket_; vector<unsigned char> data_; // ...};

Page 52: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Thinking Asynchronously

Page 57: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Thinking AsynchronouslyThinking Asynchronously

class connection{ tcp::socket socket_; vector<unsigned char> data_; // ... ~connection() { socket_.close(); } // ...};

Page 58: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Thinking AsynchronouslyThinking Asynchronously

Operating System

gettimeofday() time()

Page 60: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Thinking AsynchronouslyThinking Asynchronously

if (socket.IsConnected()){ socket.Write(data);}

What's wrong with this code?

Page 61: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Thinking AsynchronouslyThinking Asynchronously

Operating System

IsConnected() Write()

TCP State Machine

Page 62: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Threads

Page 67: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

Single-threaded:● Preferred starting point● Keep handlers short and non-blocking

Page 69: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

io_service

work

handlerwork

handler

work

handler

io_service.run()

Page 71: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

work

handlerwork

handler

work

handler

launch task in threadwork

handler

Thread

creates

Page 72: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

io_service

work

handlerwork

handler

work

handler

io_service.run()

Thread

work

handler

Page 73: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

io_service

work

handlerwork

handler

work

handler

io_service.run()

result

handler

work

result

handler

dequeues

Page 75: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

io_service

work

handlerwork

handler

work

handler

io_service.run()

result

handler

Page 76: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

work

handler

asio::io_service::work

Page 77: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

class connection : enable_shared_from_this<connection>{ // ... void work_done(...result...) { // ... } // ...};

Page 80: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

Strands:● Non-concurrent invocation of handlers● May be implicit or explicit

Page 86: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

ThreadsThreads

socket.async_connect(...);

if (!ec){ socket.async_read_some(...);}

if (!ec){ async_write(socket, ...);}

Page 88: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Managing Complexity

Page 100: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Managing ComplexityManaging Complexity

Approaches:● Pass the buck● The buck stops here

Page 101: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Managing ComplexityManaging Complexity

Approaches:● Pass the buck

● Functions● Classes

● The buck stops here● Classes

Page 102: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Managing ComplexityManaging Complexity

Page 123: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Managing ComplexityManaging Complexity

Page 124: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Managing ComplexityManaging Complexity

Operations on

I/O Objects

The buck stops here

Passing the buck

Page 128: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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 Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

Summary

Page 130: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

SummarySummary

Challenges:● Object lifetimes● Thinking asynchronously● Threads● Managing complexity

Page 131: Thinking Asynchronously: Designing Applications with Boostcpp.mimuw.edu.pl/files/boost_vs_qt/asio/thinking_asynchronously.pdf · The Basics asio::io_service io_service; // ... tcp::socket

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