RCFProto
 All Classes Functions Typedefs
ServerObjectService.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_SERVEROBJECTSERVICE_HPP
20 #define INCLUDE_RCF_SERVEROBJECTSERVICE_HPP
21 
22 #include <boost/any.hpp>
23 
24 #include <RCF/Export.hpp>
25 #include <RCF/PeriodicTimer.hpp>
26 #include <RCF/Service.hpp>
27 
28 
29 namespace RCF {
30 
31  class ServerObjectService;
32  typedef boost::shared_ptr<ServerObjectService> ServerObjectServicePtr;
33 
34  class ServerObjectHolder
35  {
36  public:
37 
38  ServerObjectHolder() :
39  mTimeoutMs(0),
40  mLastTouchMs(0),
41  mUseCount(0)
42  {
43  }
44 
45  ServerObjectHolder(const boost::any & serverObject, boost::uint32_t timeoutMs) :
46  mTimeoutMs(timeoutMs),
47  mLastTouchMs(0),
48  mUseCount(0),
49  mServerObject(serverObject)
50  {
51  }
52 
53  boost::uint32_t mTimeoutMs;
54  boost::uint32_t mLastTouchMs;
55  int mUseCount;
56  boost::any mServerObject;
57  };
58 
59  class RCF_EXPORT ServerObjectService : public I_Service, boost::noncopyable
60  {
61  public:
62  ServerObjectService();
63 
64  private:
65  void onServerStart(RcfServer & server);
66  void onServerStop(RcfServer & server);
67  void onTimer();
68  void customDeleter(const std::string & objectKey, void * pt);
69 
70  typedef std::map<std::string, ServerObjectHolder> ServerObjectMap;
71 
72  RcfServer * mpRcfServer;
73  PeriodicTimer mPeriodicTimer;
74 
75  boost::uint32_t mHarvestingIntervalS;
76  boost::uint32_t mLastHarvestMs;
77 
78  Mutex mMutex;
79  ServerObjectMap mServerObjectMap;
80 
81 
82 
83  template<typename T>
84  boost::shared_ptr<T> getServerObjectImpl(
85  const std::string & objectKey,
86  boost::uint32_t timeoutMs,
87  bool createIfDoesntExist)
88  {
89  typedef boost::shared_ptr<T> TPtr;
90 
91  Lock lock(mMutex);
92 
93  ServerObjectMap::iterator iter = mServerObjectMap.find(objectKey);
94  if (iter != mServerObjectMap.end())
95  {
96  ServerObjectHolder & holder = iter->second;
97  boost::any & a = holder.mServerObject;
98  TPtr * ptPtr = boost::any_cast<TPtr>(&a);
99  RCF_ASSERT(ptPtr);
100  TPtr tPtr = *ptPtr;
101  T * pt = tPtr.get();
102  RCF_ASSERT(pt);
103 
104  // Return shared_ptr with custom deleter.
105  holder.mLastTouchMs = getCurrentTimeMs();
106  RCF_ASSERT(holder.mUseCount >= 0);
107  ++holder.mUseCount;
108  TPtr ptr(pt, boost::bind(&ServerObjectService::customDeleter, this, objectKey, _1));
109  return ptr;
110  }
111  else if (createIfDoesntExist)
112  {
113  T * pt = new T();
114  TPtr tPtr(pt);
115  mServerObjectMap[objectKey] = ServerObjectHolder(boost::any(tPtr), timeoutMs);
116  ServerObjectHolder & holder = mServerObjectMap[objectKey];
117 
118  // Return shared_ptr with custom deleter.
119  holder.mLastTouchMs = getCurrentTimeMs();
120  RCF_ASSERT(holder.mUseCount >= 0);
121  ++holder.mUseCount;
122  TPtr ptr(pt, boost::bind(&ServerObjectService::customDeleter, this, objectKey, _1));
123  return ptr;
124  }
125  else
126  {
127  return TPtr();
128  }
129  }
130 
131  public:
132 
133  template<typename T>
134  boost::shared_ptr<T> queryServerObject(
135  const std::string & objectKey)
136  {
137  return getServerObjectImpl<T>(objectKey, 0, false);
138  }
139 
140  template<typename T>
141  boost::shared_ptr<T> getServerObject(
142  const std::string & objectKey,
143  boost::uint32_t timeoutMs)
144  {
145  return getServerObjectImpl<T>(objectKey, timeoutMs, true);
146  }
147 
148  void deleteServerObject(const std::string & objectKey);
149  };
150 
151 } // namespace RCF
152 
153 #endif // ! INCLUDE_RCF_SERVEROBJECTSERVICE_HPP