1#include "../Mutex.h"
2#include "../Thread.h"
3#include <set>
4#include <boost/shared_ptr.hpp>
5#include <boost/enable_shared_from_this.hpp>
6#include <stdio.h>
7
8class Request;
9typedef boost::shared_ptr<Request> RequestPtr;
10
11class Inventory
12{
13 public:
14  Inventory()
15    : requests_(new RequestList)
16  {
17  }
18
19  void add(const RequestPtr& req)
20  {
21    muduo::MutexLockGuard lock(mutex_);
22    if (!requests_.unique())
23    {
24      requests_.reset(new RequestList(*requests_));
25      printf("Inventory::add() copy the whole list\n");
26    }
27    assert(requests_.unique());
28    requests_->insert(req);
29  }
30
31  void remove(const RequestPtr& req) // __attribute__ ((noinline))
32  {
33    muduo::MutexLockGuard lock(mutex_);
34    if (!requests_.unique())
35    {
36      requests_.reset(new RequestList(*requests_));
37      printf("Inventory::remove() copy the whole list\n");
38    }
39    assert(requests_.unique());
40    requests_->erase(req);
41  }
42
43  void printAll() const;
44
45 private:
46  typedef std::set<RequestPtr> RequestList;
47  typedef boost::shared_ptr<RequestList> RequestListPtr;
48
49  RequestListPtr getData() const
50  {
51    muduo::MutexLockGuard lock(mutex_);
52    return requests_;
53  }
54
55  mutable muduo::MutexLock mutex_;
56  RequestListPtr requests_;
57};
58
59Inventory g_inventory;
60
61class Request : public boost::enable_shared_from_this<Request>
62{
63 public:
64  Request()
65    : x_(0)
66  {
67  }
68
69  ~Request()
70  {
71    x_ = -1;
72  }
73
74  void cancel() __attribute__ ((noinline))
75  {
76    muduo::MutexLockGuard lock(mutex_);
77    x_ = 1;
78    sleep(1);
79    printf("cancel()\n");
80    g_inventory.remove(shared_from_this());
81  }
82
83  void process() // __attribute__ ((noinline))
84  {
85    muduo::MutexLockGuard lock(mutex_);
86    g_inventory.add(shared_from_this());
87    // ...
88  }
89
90  void print() const __attribute__ ((noinline))
91  {
92    muduo::MutexLockGuard lock(mutex_);
93    // ...
94    printf("print Request %p x=%d\n", this, x_);
95  }
96
97 private:
98  mutable muduo::MutexLock mutex_;
99  int x_;
100};
101
102void Inventory::printAll() const
103{
104  RequestListPtr requests = getData();
105  printf("printAll()\n");
106  sleep(1);
107  for (std::set<RequestPtr>::const_iterator it = requests->begin();
108      it != requests->end();
109      ++it)
110  {
111    (*it)->print();
112  }
113}
114
115void threadFunc()
116{
117  RequestPtr req(new Request);
118  req->process();
119  req->cancel();
120}
121
122int main()
123{
124  muduo::Thread thread(threadFunc);
125  thread.start();
126  usleep(500*1000);
127  g_inventory.printAll();
128  thread.join();
129}
130