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;
268 ClientStub &clientStub,
269 const std::string & interfaceName,
271 RemoteCallSemantics rcs,
272 const char * szFunc =
"",
273 const char * szArity =
"") :
275 mpClientStub(&clientStub),
283 clientStub.init(interfaceName, fnId, rcs);
286 FutureImpl(
const FutureImpl &rhs) :
288 mpClientStub(rhs.mpClientStub),
291 mSzFunc(rhs.mSzFunc),
292 mSzArity(rhs.mSzArity),
298 FutureImpl &operator=(
const FutureImpl &rhs)
301 mpClientStub = rhs.mpClientStub;
304 mSzFunc = rhs.mSzFunc;
305 mSzArity = rhs.mSzArity;
323 mpClientStub->clearParameters();
328 void assignTo(Future<T> &future)
const
331 mpClientStub->setAsync(
true);
332 future.mStatePtr->setClientStub(mpClientStub, mpT);
343 if (!mpClientStub->getAsync())
345 mpClientStub->clearParameters();
354 if (mpClientStub->getTransport().isInProcess())
356 mpClientStub->getTransport().doInProcessCall(*mpClientStub);
357 if (mpClientStub->mAsyncCallback)
359 mpClientStub->mAsyncCallback = boost::function0<void>();
364 #if RCF_FEATURE_FILETRANSFER==1
367 mpClientStub->processUploadStreams();
372 bool async = mpClientStub->getAsync();
374 mpClientStub->setTries(0);
376 setCurrentCallDesc(mpClientStub->mCurrentCallDesc, mpClientStub->mRequest, mSzFunc, mSzArity);
388 void callSync()
const
397 LogEntryExit logEntryExit(*mpClientStub);
399 RCF_LOG_3()(mpClientStub)(mpClientStub->mRequest)
400 <<
"RcfClient - sending synchronous request.";
404 mpClientStub->call(mRcs);
406 catch(
const RCF::RemoteException & e)
408 mpClientStub->mEncodedByteBuffers.resize(0);
409 if (shouldDisconnectOnRemoteError( e.getError() ))
411 mpClientStub->disconnect();
415 catch(
const RCF::Exception &)
417 mpClientStub->mEncodedByteBuffers.resize(0);
418 mpClientStub->disconnect();
423 mpClientStub->mEncodedByteBuffers.resize(0);
424 mpClientStub->disconnect();
429 void callAsync()
const
431 LogEntryExit logEntryExit(*mpClientStub);
433 RCF_LOG_3()(mpClientStub)(mpClientStub->mRequest)
434 <<
"RcfClient - sending asynchronous request.";
436 std::auto_ptr<RCF::Exception> ape;
440 mpClientStub->call(mRcs);
442 catch(
const RCF::Exception & e)
444 ape.reset( e.clone().release() );
448 ape.reset(
new Exception(_RcfError_NonStdException()) );
453 mpClientStub->onError(*ape);
456 getTlsAmiNotification().run();
460 ClientStub * mpClientStub;
462 RemoteCallSemantics mRcs;
463 const char * mSzFunc;
464 const char * mSzArity;
469 template<
typename T,
typename U>
470 bool operator==(
const FutureImpl<T> & fi,
const U & u)
472 return fi.operator T() == u;
475 template<
typename T,
typename U>
476 bool operator==(
const U & u,
const FutureImpl<T> & fi)
478 return u == fi.operator T();
482 std::ostream & operator<<(std::ostream & os, const FutureImpl<T> & fi)
484 return os << fi.operator T();
490 #endif // INCLUDE_RCF_FUTURE_HPP