12d3b4de6SShuo Chen#include "../Mutex.h"
22d3b4de6SShuo Chen#include "../Thread.h"
32d3b4de6SShuo Chen#include <set>
42d3b4de6SShuo Chen#include <boost/shared_ptr.hpp>
52d3b4de6SShuo Chen#include <stdio.h>
62d3b4de6SShuo Chen
72d3b4de6SShuo Chenclass Request;
82d3b4de6SShuo Chen
92d3b4de6SShuo Chenclass Inventory
102d3b4de6SShuo Chen{
112d3b4de6SShuo Chen public:
122d3b4de6SShuo Chen  Inventory()
132d3b4de6SShuo Chen    : requests_(new RequestList)
142d3b4de6SShuo Chen  {
152d3b4de6SShuo Chen  }
162d3b4de6SShuo Chen
172d3b4de6SShuo Chen  void add(Request* req)
182d3b4de6SShuo Chen  {
192d3b4de6SShuo Chen    muduo::MutexLockGuard lock(mutex_);
202d3b4de6SShuo Chen    if (!requests_.unique())
212d3b4de6SShuo Chen    {
222d3b4de6SShuo Chen      requests_.reset(new RequestList(*requests_));
232d3b4de6SShuo Chen      printf("Inventory::add() copy the whole list\n");
242d3b4de6SShuo Chen    }
252d3b4de6SShuo Chen    assert(requests_.unique());
262d3b4de6SShuo Chen    requests_->insert(req);
272d3b4de6SShuo Chen  }
282d3b4de6SShuo Chen
292d3b4de6SShuo Chen  void remove(Request* req) // __attribute__ ((noinline))
302d3b4de6SShuo Chen  {
312d3b4de6SShuo Chen    muduo::MutexLockGuard lock(mutex_);
322d3b4de6SShuo Chen    if (!requests_.unique())
332d3b4de6SShuo Chen    {
342d3b4de6SShuo Chen      requests_.reset(new RequestList(*requests_));
352d3b4de6SShuo Chen      printf("Inventory::remove() copy the whole list\n");
362d3b4de6SShuo Chen    }
372d3b4de6SShuo Chen    assert(requests_.unique());
382d3b4de6SShuo Chen    requests_->erase(req);
392d3b4de6SShuo Chen  }
402d3b4de6SShuo Chen
412d3b4de6SShuo Chen  void printAll() const;
422d3b4de6SShuo Chen
432d3b4de6SShuo Chen private:
442d3b4de6SShuo Chen  typedef std::set<Request*> RequestList;
452d3b4de6SShuo Chen  typedef boost::shared_ptr<RequestList> RequestListPtr;
462d3b4de6SShuo Chen
472d3b4de6SShuo Chen  RequestListPtr getData() const
482d3b4de6SShuo Chen  {
492d3b4de6SShuo Chen    muduo::MutexLockGuard lock(mutex_);
502d3b4de6SShuo Chen    return requests_;
512d3b4de6SShuo Chen  }
522d3b4de6SShuo Chen
532d3b4de6SShuo Chen  mutable muduo::MutexLock mutex_;
542d3b4de6SShuo Chen  RequestListPtr requests_;
552d3b4de6SShuo Chen};
562d3b4de6SShuo Chen
572d3b4de6SShuo ChenInventory g_inventory;
582d3b4de6SShuo Chen
592d3b4de6SShuo Chenclass Request
602d3b4de6SShuo Chen{
612d3b4de6SShuo Chen public:
622d3b4de6SShuo Chen  Request()
632d3b4de6SShuo Chen    : x_(0)
642d3b4de6SShuo Chen  {
652d3b4de6SShuo Chen  }
662d3b4de6SShuo Chen
672d3b4de6SShuo Chen  ~Request() __attribute__ ((noinline))
682d3b4de6SShuo Chen  {
692d3b4de6SShuo Chen    muduo::MutexLockGuard lock(mutex_);
702d3b4de6SShuo Chen    x_ = -1;
712d3b4de6SShuo Chen    sleep(1);
722d3b4de6SShuo Chen    g_inventory.remove(this);
732d3b4de6SShuo Chen  }
742d3b4de6SShuo Chen
752d3b4de6SShuo Chen  void process() // __attribute__ ((noinline))
762d3b4de6SShuo Chen  {
772d3b4de6SShuo Chen    muduo::MutexLockGuard lock(mutex_);
782d3b4de6SShuo Chen    g_inventory.add(this);
792d3b4de6SShuo Chen    // ...
802d3b4de6SShuo Chen  }
812d3b4de6SShuo Chen
822d3b4de6SShuo Chen  void print() const __attribute__ ((noinline))
832d3b4de6SShuo Chen  {
842d3b4de6SShuo Chen    muduo::MutexLockGuard lock(mutex_);
852d3b4de6SShuo Chen    // ...
862d3b4de6SShuo Chen    printf("print Request %p x=%d\n", this, x_);
872d3b4de6SShuo Chen  }
882d3b4de6SShuo Chen
892d3b4de6SShuo Chen private:
902d3b4de6SShuo Chen  mutable muduo::MutexLock mutex_;
912d3b4de6SShuo Chen  int x_;
922d3b4de6SShuo Chen};
932d3b4de6SShuo Chen
942d3b4de6SShuo Chenvoid Inventory::printAll() const
952d3b4de6SShuo Chen{
962d3b4de6SShuo Chen  RequestListPtr requests = getData();
972d3b4de6SShuo Chen  sleep(1);
982d3b4de6SShuo Chen  for (std::set<Request*>::const_iterator it = requests->begin();
992d3b4de6SShuo Chen      it != requests->end();
1002d3b4de6SShuo Chen      ++it)
1012d3b4de6SShuo Chen  {
1022d3b4de6SShuo Chen    (*it)->print();
1032d3b4de6SShuo Chen  }
1042d3b4de6SShuo Chen}
1052d3b4de6SShuo Chen
1062d3b4de6SShuo Chenvoid threadFunc()
1072d3b4de6SShuo Chen{
1082d3b4de6SShuo Chen  Request* req = new Request;
1092d3b4de6SShuo Chen  req->process();
1102d3b4de6SShuo Chen  delete req;
1112d3b4de6SShuo Chen}
1122d3b4de6SShuo Chen
1132d3b4de6SShuo Chenint main()
1142d3b4de6SShuo Chen{
1152d3b4de6SShuo Chen  muduo::Thread thread(threadFunc);
1162d3b4de6SShuo Chen  thread.start();
1172d3b4de6SShuo Chen  usleep(500*1000);
1182d3b4de6SShuo Chen  g_inventory.printAll();
1192d3b4de6SShuo Chen  thread.join();
1202d3b4de6SShuo Chen}
121