Factory.cc revision 903f321e
15a94f34bSShuo Chen#include <map> 25a94f34bSShuo Chen 35a94f34bSShuo Chen#include <boost/bind.hpp> 45a94f34bSShuo Chen#include <boost/enable_shared_from_this.hpp> 55a94f34bSShuo Chen#include <boost/shared_ptr.hpp> 65a94f34bSShuo Chen#include <boost/weak_ptr.hpp> 75a94f34bSShuo Chen 85a94f34bSShuo Chen#include "../Mutex.h" 95a94f34bSShuo Chen 105a94f34bSShuo Chen#include <assert.h> 115a94f34bSShuo Chen#include <stdio.h> 125a94f34bSShuo Chen 135a94f34bSShuo Chenusing std::string; 145a94f34bSShuo Chen 155a94f34bSShuo Chenclass Stock : boost::noncopyable 165a94f34bSShuo Chen{ 175a94f34bSShuo Chen public: 185a94f34bSShuo Chen Stock(const string& name) 195a94f34bSShuo Chen : name_(name) 205a94f34bSShuo Chen { 215a94f34bSShuo Chen printf(" Stock[%p] %s\n", this, name_.c_str()); 225a94f34bSShuo Chen } 235a94f34bSShuo Chen 245a94f34bSShuo Chen ~Stock() 255a94f34bSShuo Chen { 265a94f34bSShuo Chen printf("~Stock[%p] %s\n", this, name_.c_str()); 275a94f34bSShuo Chen } 285a94f34bSShuo Chen 295a94f34bSShuo Chen const string& key() const { return name_; } 305a94f34bSShuo Chen 315a94f34bSShuo Chen private: 325a94f34bSShuo Chen string name_; 335a94f34bSShuo Chen}; 345a94f34bSShuo Chen 355a94f34bSShuo Chennamespace version1 365a94f34bSShuo Chen{ 375a94f34bSShuo Chen 385a94f34bSShuo Chen// questionable code 395a94f34bSShuo Chenclass StockFactory : boost::noncopyable 405a94f34bSShuo Chen{ 415a94f34bSShuo Chen public: 425a94f34bSShuo Chen 435a94f34bSShuo Chen boost::shared_ptr<Stock> get(const string& key) 445a94f34bSShuo Chen { 455a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 465a94f34bSShuo Chen boost::shared_ptr<Stock>& pStock = stocks_[key]; 475a94f34bSShuo Chen if (!pStock) 485a94f34bSShuo Chen { 495a94f34bSShuo Chen pStock.reset(new Stock(key)); 505a94f34bSShuo Chen } 515a94f34bSShuo Chen return pStock; 525a94f34bSShuo Chen } 535a94f34bSShuo Chen 545a94f34bSShuo Chen 555a94f34bSShuo Chen private: 565a94f34bSShuo Chen mutable muduo::MutexLock mutex_; 575a94f34bSShuo Chen std::map<string, boost::shared_ptr<Stock> > stocks_; 585a94f34bSShuo Chen}; 595a94f34bSShuo Chen 605a94f34bSShuo Chen} 615a94f34bSShuo Chen 625a94f34bSShuo Chennamespace version2 635a94f34bSShuo Chen{ 645a94f34bSShuo Chen 655a94f34bSShuo Chenclass StockFactory : boost::noncopyable 665a94f34bSShuo Chen{ 675a94f34bSShuo Chen public: 685a94f34bSShuo Chen boost::shared_ptr<Stock> get(const string& key) 695a94f34bSShuo Chen { 705a94f34bSShuo Chen boost::shared_ptr<Stock> pStock; 715a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 725a94f34bSShuo Chen boost::weak_ptr<Stock>& wkStock = stocks_[key]; 735a94f34bSShuo Chen pStock = wkStock.lock(); 745a94f34bSShuo Chen if (!pStock) 755a94f34bSShuo Chen { 765a94f34bSShuo Chen pStock.reset(new Stock(key)); 775a94f34bSShuo Chen wkStock = pStock; 785a94f34bSShuo Chen } 795a94f34bSShuo Chen return pStock; 805a94f34bSShuo Chen } 815a94f34bSShuo Chen 825a94f34bSShuo Chen private: 835a94f34bSShuo Chen mutable muduo::MutexLock mutex_; 845a94f34bSShuo Chen std::map<string, boost::weak_ptr<Stock> > stocks_; 855a94f34bSShuo Chen}; 865a94f34bSShuo Chen 875a94f34bSShuo Chen} 885a94f34bSShuo Chen 895a94f34bSShuo Chennamespace version3 905a94f34bSShuo Chen{ 915a94f34bSShuo Chen 925a94f34bSShuo Chenclass StockFactory : boost::noncopyable 935a94f34bSShuo Chen{ 945a94f34bSShuo Chen public: 955a94f34bSShuo Chen 965a94f34bSShuo Chen boost::shared_ptr<Stock> get(const string& key) 975a94f34bSShuo Chen { 985a94f34bSShuo Chen boost::shared_ptr<Stock> pStock; 995a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 1005a94f34bSShuo Chen boost::weak_ptr<Stock>& wkStock = stocks_[key]; 1015a94f34bSShuo Chen pStock = wkStock.lock(); 1025a94f34bSShuo Chen if (!pStock) 1035a94f34bSShuo Chen { 1045a94f34bSShuo Chen pStock.reset(new Stock(key), 1055a94f34bSShuo Chen boost::bind(&StockFactory::deleteStock, this, _1)); 1065a94f34bSShuo Chen wkStock = pStock; 1075a94f34bSShuo Chen } 1085a94f34bSShuo Chen return pStock; 1095a94f34bSShuo Chen } 1105a94f34bSShuo Chen 1115a94f34bSShuo Chen private: 1125a94f34bSShuo Chen 1135a94f34bSShuo Chen void deleteStock(Stock* stock) 1145a94f34bSShuo Chen { 1155a94f34bSShuo Chen printf("deleteStock[%p]\n", stock); 1165a94f34bSShuo Chen if (stock) 1175a94f34bSShuo Chen { 1185a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 1195a94f34bSShuo Chen stocks_.erase(stock->key()); 1205a94f34bSShuo Chen } 1215a94f34bSShuo Chen delete stock; // sorry, I lied 1225a94f34bSShuo Chen } 1235a94f34bSShuo Chen mutable muduo::MutexLock mutex_; 1245a94f34bSShuo Chen std::map<string, boost::weak_ptr<Stock> > stocks_; 1255a94f34bSShuo Chen}; 1265a94f34bSShuo Chen 1275a94f34bSShuo Chen} 1285a94f34bSShuo Chen 1295a94f34bSShuo Chennamespace version4 1305a94f34bSShuo Chen{ 1315a94f34bSShuo Chen 1325a94f34bSShuo Chenclass StockFactory : public boost::enable_shared_from_this<StockFactory>, 1335a94f34bSShuo Chen boost::noncopyable 1345a94f34bSShuo Chen{ 1355a94f34bSShuo Chen public: 1365a94f34bSShuo Chen 1375a94f34bSShuo Chen boost::shared_ptr<Stock> get(const string& key) 1385a94f34bSShuo Chen { 1395a94f34bSShuo Chen boost::shared_ptr<Stock> pStock; 1405a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 1415a94f34bSShuo Chen boost::weak_ptr<Stock>& wkStock = stocks_[key]; 1425a94f34bSShuo Chen pStock = wkStock.lock(); 1435a94f34bSShuo Chen if (!pStock) 1445a94f34bSShuo Chen { 1455a94f34bSShuo Chen pStock.reset(new Stock(key), 1465a94f34bSShuo Chen boost::bind(&StockFactory::deleteStock, 1475a94f34bSShuo Chen shared_from_this(), 1485a94f34bSShuo Chen _1)); 1495a94f34bSShuo Chen wkStock = pStock; 1505a94f34bSShuo Chen } 1515a94f34bSShuo Chen return pStock; 1525a94f34bSShuo Chen } 1535a94f34bSShuo Chen 1545a94f34bSShuo Chen private: 1555a94f34bSShuo Chen 1565a94f34bSShuo Chen void deleteStock(Stock* stock) 1575a94f34bSShuo Chen { 1585a94f34bSShuo Chen printf("deleteStock[%p]\n", stock); 1595a94f34bSShuo Chen if (stock) 1605a94f34bSShuo Chen { 1615a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 1625a94f34bSShuo Chen stocks_.erase(stock->key()); 1635a94f34bSShuo Chen } 1645a94f34bSShuo Chen delete stock; // sorry, I lied 1655a94f34bSShuo Chen } 1665a94f34bSShuo Chen mutable muduo::MutexLock mutex_; 1675a94f34bSShuo Chen std::map<string, boost::weak_ptr<Stock> > stocks_; 1685a94f34bSShuo Chen}; 1695a94f34bSShuo Chen 1705a94f34bSShuo Chen} 1715a94f34bSShuo Chen 1725a94f34bSShuo Chenclass StockFactory : public boost::enable_shared_from_this<StockFactory>, 1735a94f34bSShuo Chen boost::noncopyable 1745a94f34bSShuo Chen{ 1755a94f34bSShuo Chen public: 1765a94f34bSShuo Chen boost::shared_ptr<Stock> get(const string& key) 1775a94f34bSShuo Chen { 1785a94f34bSShuo Chen boost::shared_ptr<Stock> pStock; 1795a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 1805a94f34bSShuo Chen boost::weak_ptr<Stock>& wkStock = stocks_[key]; 1815a94f34bSShuo Chen pStock = wkStock.lock(); 1825a94f34bSShuo Chen if (!pStock) 1835a94f34bSShuo Chen { 1845a94f34bSShuo Chen pStock.reset(new Stock(key), 1855a94f34bSShuo Chen boost::bind(&StockFactory::weakDeleteCallback, 1865a94f34bSShuo Chen boost::weak_ptr<StockFactory>(shared_from_this()), 1875a94f34bSShuo Chen _1)); 1885a94f34bSShuo Chen wkStock = pStock; 1895a94f34bSShuo Chen } 1905a94f34bSShuo Chen return pStock; 1915a94f34bSShuo Chen } 1925a94f34bSShuo Chen 1935a94f34bSShuo Chen private: 194903f321eSShuo Chen static void weakDeleteCallback(const boost::weak_ptr<StockFactory>& wkFactory, 1955a94f34bSShuo Chen Stock* stock) 1965a94f34bSShuo Chen { 1975a94f34bSShuo Chen printf("weakDeleteStock[%p]\n", stock); 1985a94f34bSShuo Chen boost::shared_ptr<StockFactory> factory(wkFactory.lock()); 1995a94f34bSShuo Chen if (factory) 2005a94f34bSShuo Chen { 2015a94f34bSShuo Chen factory->removeStock(stock); 2025a94f34bSShuo Chen } 2035a94f34bSShuo Chen else 2045a94f34bSShuo Chen { 2055a94f34bSShuo Chen printf("factory died.\n"); 2065a94f34bSShuo Chen } 2075a94f34bSShuo Chen delete stock; // sorry, I lied 2085a94f34bSShuo Chen } 2095a94f34bSShuo Chen 2105a94f34bSShuo Chen void removeStock(Stock* stock) 2115a94f34bSShuo Chen { 2125a94f34bSShuo Chen if (stock) 2135a94f34bSShuo Chen { 2145a94f34bSShuo Chen muduo::MutexLockGuard lock(mutex_); 2155a94f34bSShuo Chen stocks_.erase(stock->key()); 2165a94f34bSShuo Chen } 2175a94f34bSShuo Chen } 2185a94f34bSShuo Chen 2195a94f34bSShuo Chen private: 2205a94f34bSShuo Chen mutable muduo::MutexLock mutex_; 2215a94f34bSShuo Chen std::map<string, boost::weak_ptr<Stock> > stocks_; 2225a94f34bSShuo Chen}; 2235a94f34bSShuo Chen 2245a94f34bSShuo Chenvoid testLongLifeFactory() 2255a94f34bSShuo Chen{ 2265a94f34bSShuo Chen boost::shared_ptr<StockFactory> factory(new StockFactory); 2275a94f34bSShuo Chen { 2285a94f34bSShuo Chen boost::shared_ptr<Stock> stock = factory->get("NYSE:IBM"); 2295a94f34bSShuo Chen boost::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM"); 2305a94f34bSShuo Chen assert(stock == stock2); 2315a94f34bSShuo Chen // stock destructs here 2325a94f34bSShuo Chen } 2335a94f34bSShuo Chen // factory destructs here 2345a94f34bSShuo Chen} 2355a94f34bSShuo Chen 2365a94f34bSShuo Chenvoid testShortLifeFactory() 2375a94f34bSShuo Chen{ 2385a94f34bSShuo Chen boost::shared_ptr<Stock> stock; 2395a94f34bSShuo Chen { 2405a94f34bSShuo Chen boost::shared_ptr<StockFactory> factory(new StockFactory); 2415a94f34bSShuo Chen stock = factory->get("NYSE:IBM"); 2425a94f34bSShuo Chen boost::shared_ptr<Stock> stock2 = factory->get("NYSE:IBM"); 2435a94f34bSShuo Chen assert(stock == stock2); 2445a94f34bSShuo Chen // factory destructs here 2455a94f34bSShuo Chen } 2465a94f34bSShuo Chen // stock destructs here 2475a94f34bSShuo Chen} 2485a94f34bSShuo Chen 2495a94f34bSShuo Chenint main() 2505a94f34bSShuo Chen{ 2515a94f34bSShuo Chen version1::StockFactory sf1; 2525a94f34bSShuo Chen version2::StockFactory sf2; 2535a94f34bSShuo Chen version3::StockFactory sf3; 2545a94f34bSShuo Chen boost::shared_ptr<version3::StockFactory> sf4(new version3::StockFactory); 2555a94f34bSShuo Chen boost::shared_ptr<StockFactory> sf5(new StockFactory); 2565a94f34bSShuo Chen 2575a94f34bSShuo Chen { 2585a94f34bSShuo Chen boost::shared_ptr<Stock> s1 = sf1.get("stock1"); 2595a94f34bSShuo Chen } 2605a94f34bSShuo Chen 2615a94f34bSShuo Chen { 2625a94f34bSShuo Chen boost::shared_ptr<Stock> s2 = sf2.get("stock2"); 2635a94f34bSShuo Chen } 2645a94f34bSShuo Chen 2655a94f34bSShuo Chen { 2665a94f34bSShuo Chen boost::shared_ptr<Stock> s3 = sf3.get("stock3"); 2675a94f34bSShuo Chen } 2685a94f34bSShuo Chen 2695a94f34bSShuo Chen { 2705a94f34bSShuo Chen boost::shared_ptr<Stock> s4 = sf4->get("stock4"); 2715a94f34bSShuo Chen } 2725a94f34bSShuo Chen 2735a94f34bSShuo Chen { 2745a94f34bSShuo Chen boost::shared_ptr<Stock> s5 = sf5->get("stock5"); 2755a94f34bSShuo Chen } 2765a94f34bSShuo Chen 2775a94f34bSShuo Chen testLongLifeFactory(); 2785a94f34bSShuo Chen testShortLifeFactory(); 2795a94f34bSShuo Chen} 280