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