19 #ifndef INCLUDE_RCF_FUTURE_HPP
20 #define INCLUDE_RCF_FUTURE_HPP
22 #include <RCF/ClientStub.hpp>
23 #include <RCF/Marshal.hpp>
30 virtual ~I_Future() {}
31 virtual void setClientStub(ClientStub *pClientStub) = 0;
41 Future() : mStatePtr(new State())
44 Future(T *pt) : mStatePtr( new State(pt))
47 Future(T *pt, ClientStub *pClientStub) : mStatePtr( new State(pt))
49 pClientStub->enrol(mStatePtr.get());
52 Future(
const T &t) : mStatePtr( new State(t))
57 return mStatePtr->operator T&();
62 return mStatePtr->operator T&();
65 Future &operator=(
const Future &rhs)
67 mStatePtr = rhs.mStatePtr;
71 Future &operator=(
const FutureImpl<T> &rhs)
77 Future(
const FutureImpl<T> &rhs) : mStatePtr( new State())
84 return mStatePtr->ready();
87 void wait(boost::uint32_t timeoutMs = 0)
89 mStatePtr->wait(timeoutMs);
102 ClientStub & getClientStub()
104 return mStatePtr->getClientStub();
107 std::auto_ptr<Exception> getAsyncException()
109 return mStatePtr->getClientStub().getAsyncException();
115 friend class FutureImpl;
117 class State :
public I_Future, boost::noncopyable
140 unregisterFromCandidates();
151 if (!mpClientStub->ready())
153 mpClientStub->waitForReady();
156 std::auto_ptr<Exception> ePtr =
157 mpClientStub->getAsyncException();
165 T *pt = mpt ? mpt : mtPtr.get();
167 Lock lock(gCandidatesMutex());
168 gCandidates().add(pt,
this);
174 void setClientStub(ClientStub *pClientStub)
176 mpClientStub = pClientStub;
179 void setClientStub(ClientStub *pClientStub, T * pt)
181 unregisterFromCandidates();
183 mpClientStub = pClientStub;
191 boost::scoped_ptr<T> mtPtr;
192 RCF::ClientStub * mpClientStub;
198 return mpClientStub->ready();
201 void wait(boost::uint32_t timeoutMs = 0)
203 mpClientStub->waitForReady(timeoutMs);
208 mpClientStub->cancel();
211 ClientStub & getClientStub()
213 return *mpClientStub;
216 void unregisterFromCandidates()
218 T *pt = mpt ? mpt : mtPtr.get();
219 Lock lock(gCandidatesMutex());
220 I_Future * pFuture = gCandidates().find(pt);
223 gCandidates().erase(pt);
229 boost::shared_ptr<State> mStatePtr;
235 LogEntryExit(ClientStub & clientStub) :
236 mClientStub(clientStub),
237 mMsg(clientStub.mCurrentCallDesc)
239 if (mClientStub.mCallInProgress)
241 RCF_THROW(_RcfError_ConcurrentCalls());
244 mClientStub.mCallInProgress =
true;
245 RCF_LOG_2() <<
"RcfClient - begin remote call. " << mMsg;
250 if (!mClientStub.getAsync())
252 RCF_LOG_2() <<
"RcfClient - end remote call. " << mMsg;
253 mClientStub.mCallInProgress =
false;
258 ClientStub & mClientStub;
259 const std::string & mMsg;
263 class RCF_EXPORT FutureImplBase
268 ClientStub &clientStub,
269 const std::string & interfaceName,
271 RemoteCallSemantics rcs,
273 const char * szArity);
275 FutureImplBase(
const FutureImplBase& rhs);
276 FutureImplBase &operator=(
const FutureImplBase &rhs);
279 void callSync()
const;
280 void callAsync()
const;
282 ClientStub * mpClientStub;
284 RemoteCallSemantics mRcs;
285 const char * mSzFunc;
286 const char * mSzArity;
291 class FutureImpl :
public FutureImplBase
296 ClientStub &clientStub,
297 const std::string & interfaceName,
299 RemoteCallSemantics rcs,
300 const char * szFunc =
"",
301 const char * szArity =
"") :
302 FutureImplBase(clientStub, interfaceName, fnId, rcs, szFunc, szArity),
307 FutureImpl(
const FutureImpl &rhs) :
313 FutureImpl &operator=(
const FutureImpl &rhs)
315 FutureImplBase::operator=(rhs);
331 mpClientStub->clearParameters();
336 void assignTo(Future<T> &future)
const
339 mpClientStub->setAsync(
true);
340 future.mStatePtr->setClientStub(mpClientStub, mpT);
345 ~FutureImpl() RCF_DTOR_THROWS
351 if (!mpClientStub->getAsync())
353 mpClientStub->clearParameters();
362 template<
typename T,
typename U>
363 bool operator==(
const FutureImpl<T> & fi,
const U & u)
365 return fi.operator T() == u;
368 template<
typename T,
typename U>
369 bool operator==(
const U & u,
const FutureImpl<T> & fi)
371 return u == fi.operator T();
375 RCF::MemOstream & operator<<(RCF::MemOstream & os, const FutureImpl<T> & fi)
377 return os << fi.operator T();
383 #endif // INCLUDE_RCF_FUTURE_HPP