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