Ticket #9203: main.cpp

File main.cpp, 2.2 KB (added by Greg Barron <gregbarron71@…>, 9 years ago)

Demonstrates strand allocation issue.

Line 
1/**
2 * This file demonstrates how handlers wrapped with one strand are
3 * executed on a different strand and how this can lead to deadlocks.
4 */
5#include <boost/asio.hpp>
6#include <boost/thread.hpp>
7#include <boost/enable_shared_from_this.hpp>
8#include <boost/shared_ptr.hpp>
9#include <iostream>
10
11namespace
12{
13 class Test
14 {
15 public:
16
17 Test(boost::asio::io_service& io_service)
18 : m_io_service(io_service)
19 , m_strand(io_service)
20 {
21 }
22
23 void block()
24 {
25 while (true)
26 {
27 std::cout << this << ": strand.impl_" << strand().impl_ << ": " << __FUNCTION__ << ": Hello world!" << "\n";
28 sleep(1);
29 }
30 }
31
32 void print()
33 {
34 std::cout << this << ": strand.impl_" << strand().impl_ << ": " << __FUNCTION__ << ": Hello world!" << "\n";
35 boost::shared_ptr<Test> pPrinter(new Test(m_io_service));
36 m_io_service.post(pPrinter->strand().wrap(boost::bind(&Test::print, pPrinter)));
37 }
38
39 boost::asio::strand& strand()
40 {
41 return (m_strand);
42 }
43
44 boost::asio::io_service& m_io_service;
45 boost::asio::strand m_strand;
46 };
47}
48
49int main()
50{
51 boost::asio::io_service io_service;
52
53 /**
54 * The handler will block which will stall the strand. Any further
55 * handlers wrap with this strand will never run.
56 */
57 Test blocker(io_service);
58 io_service.post(blocker.strand().wrap(boost::bind(&Test::block, blocker)));
59
60 /**
61 * The handler will print "Hello World" and then create a new instantiation
62 * of the class and and post a similarly wrapped handler. "Hello World"
63 * should be printed forever. However eventually the printer's strand will
64 * share the implemention of the strand belonging to "blocker" and will not
65 * be executed.
66 */
67 boost::shared_ptr<Test> pPrinter(new Test(io_service));
68 io_service.post(pPrinter->strand().wrap(boost::bind(&Test::print, pPrinter)));
69 pPrinter.reset();
70
71 boost::thread thread(boost::bind(&boost::asio::io_service::run, boost::ref(io_service)));
72 io_service.run();
73
74 thread.join();
75}