123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- //
- // ActiveResult.h
- //
- // Library: Foundation
- // Package: Threading
- // Module: ActiveObjects
- //
- // Definition of the ActiveResult class.
- //
- // Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
- // and Contributors.
- //
- // SPDX-License-Identifier: BSL-1.0
- //
- #ifndef Foundation_ActiveResult_INCLUDED
- #define Foundation_ActiveResult_INCLUDED
- #include "Poco/Foundation.h"
- #include "Poco/Mutex.h"
- #include "Poco/Event.h"
- #include "Poco/RefCountedObject.h"
- #include "Poco/Exception.h"
- #include <algorithm>
- namespace Poco {
- template <class ResultType>
- class ActiveResultHolder: public RefCountedObject
- /// This class holds the result of an asynchronous method
- /// invocation. It is used to pass the result from the
- /// execution thread back to the invocation thread.
- /// The class uses reference counting for memory management.
- /// Do not use this class directly, use ActiveResult instead.
- {
- public:
- ActiveResultHolder():
- _pData(0),
- _pExc(0),
- _event(false)
- /// Creates an ActiveResultHolder.
- {
- }
-
- ResultType& data()
- /// Returns a reference to the actual result.
- {
- poco_check_ptr(_pData);
- return *_pData;
- }
-
- void data(ResultType* pData)
- {
- delete _pData;
- _pData = pData;
- }
-
- void wait()
- /// Pauses the caller until the result becomes available.
- {
- _event.wait();
- }
-
- bool tryWait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Returns true if the result became
- /// available, false otherwise.
- {
- return _event.tryWait(milliseconds);
- }
-
- void wait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Throws a TimeoutException if the
- /// result did not became available.
- {
- _event.wait(milliseconds);
- }
-
- void notify()
- /// Notifies the invoking thread that the result became available.
- {
- _event.set();
- }
-
- bool failed() const
- /// Returns true if the active method failed (and threw an exception).
- /// Information about the exception can be obtained by calling error().
- {
- return _pExc != 0;
- }
-
- std::string error() const
- /// If the active method threw an exception, a textual representation
- /// of the exception is returned. An empty string is returned if the
- /// active method completed successfully.
- {
- if (_pExc)
- return _pExc->message();
- else
- return std::string();
- }
-
- Exception* exception() const
- /// If the active method threw an exception, a clone of the exception
- /// object is returned, otherwise null.
- {
- return _pExc;
- }
-
- void error(const Exception& exc)
- /// Sets the exception.
- {
- delete _pExc;
- _pExc = exc.clone();
- }
-
- void error(const std::string& msg)
- /// Sets the exception.
- {
- delete _pExc;
- _pExc = new UnhandledException(msg);
- }
- protected:
- ~ActiveResultHolder()
- {
- delete _pData;
- delete _pExc;
- }
- private:
- ResultType* _pData;
- Exception* _pExc;
- Event _event;
- };
- template <>
- class ActiveResultHolder<void>: public RefCountedObject
- {
- public:
- ActiveResultHolder():
- _pExc(0),
- _event(false)
- /// Creates an ActiveResultHolder.
- {
- }
-
- void wait()
- /// Pauses the caller until the result becomes available.
- {
- _event.wait();
- }
-
- bool tryWait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Returns true if the result became
- /// available, false otherwise.
- {
- return _event.tryWait(milliseconds);
- }
-
- void wait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Throws a TimeoutException if the
- /// result did not became available.
- {
- _event.wait(milliseconds);
- }
-
- void notify()
- /// Notifies the invoking thread that the result became available.
- {
- _event.set();
- }
-
- bool failed() const
- /// Returns true if the active method failed (and threw an exception).
- /// Information about the exception can be obtained by calling error().
- {
- return _pExc != 0;
- }
-
- std::string error() const
- /// If the active method threw an exception, a textual representation
- /// of the exception is returned. An empty string is returned if the
- /// active method completed successfully.
- {
- if (_pExc)
- return _pExc->message();
- else
- return std::string();
- }
-
- Exception* exception() const
- /// If the active method threw an exception, a clone of the exception
- /// object is returned, otherwise null.
- {
- return _pExc;
- }
-
- void error(const Exception& exc)
- /// Sets the exception.
- {
- delete _pExc;
- _pExc = exc.clone();
- }
-
- void error(const std::string& msg)
- /// Sets the exception.
- {
- delete _pExc;
- _pExc = new UnhandledException(msg);
- }
- protected:
- ~ActiveResultHolder()
- {
- delete _pExc;
- }
- private:
- Exception* _pExc;
- Event _event;
- };
- template <class RT>
- class ActiveResult
- /// This class holds the result of an asynchronous method
- /// invocation (see class ActiveMethod). It is used to pass the
- /// result from the execution thread back to the invocation thread.
- {
- public:
- typedef RT ResultType;
- typedef ActiveResultHolder<ResultType> ActiveResultHolderType;
- ActiveResult(ActiveResultHolderType* pHolder):
- _pHolder(pHolder)
- /// Creates the active result. For internal use only.
- {
- poco_check_ptr (pHolder);
- }
-
- ActiveResult(const ActiveResult& result)
- /// Copy constructor.
- {
- _pHolder = result._pHolder;
- _pHolder->duplicate();
- }
-
- ~ActiveResult()
- /// Destroys the result.
- {
- _pHolder->release();
- }
-
- ActiveResult& operator = (const ActiveResult& result)
- /// Assignment operator.
- {
- ActiveResult tmp(result);
- swap(tmp);
- return *this;
- }
-
- void swap(ActiveResult& result)
- {
- using std::swap;
- swap(_pHolder, result._pHolder);
- }
-
- ResultType& data() const
- /// Returns a reference to the result data.
- {
- return _pHolder->data();
- }
-
- void data(ResultType* pValue)
- {
- _pHolder->data(pValue);
- }
-
- void wait()
- /// Pauses the caller until the result becomes available.
- {
- _pHolder->wait();
- }
-
- bool tryWait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Returns true if the result became
- /// available, false otherwise.
- {
- return _pHolder->tryWait(milliseconds);
- }
-
- void wait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Throws a TimeoutException if the
- /// result did not became available.
- {
- _pHolder->wait(milliseconds);
- }
-
- bool available() const
- /// Returns true if a result is available.
- {
- return _pHolder->tryWait(0);
- }
-
- bool failed() const
- /// Returns true if the active method failed (and threw an exception).
- /// Information about the exception can be obtained by calling error().
- {
- return _pHolder->failed();
- }
-
- std::string error() const
- /// If the active method threw an exception, a textual representation
- /// of the exception is returned. An empty string is returned if the
- /// active method completed successfully.
- {
- return _pHolder->error();
- }
- Exception* exception() const
- /// If the active method threw an exception, a clone of the exception
- /// object is returned, otherwise null.
- {
- return _pHolder->exception();
- }
- void notify()
- /// Notifies the invoking thread that the result became available.
- /// For internal use only.
- {
- _pHolder->notify();
- }
-
- ResultType& data()
- /// Returns a non-const reference to the result data. For internal
- /// use only.
- {
- return _pHolder->data();
- }
-
- void error(const std::string& msg)
- /// Sets the failed flag and the exception message.
- {
- _pHolder->error(msg);
- }
- void error(const Exception& exc)
- /// Sets the failed flag and the exception message.
- {
- _pHolder->error(exc);
- }
-
- private:
- ActiveResult();
- ActiveResultHolderType* _pHolder;
- };
- template <>
- class ActiveResult<void>
- /// This class holds the result of an asynchronous method
- /// invocation (see class ActiveMethod). It is used to pass the
- /// result from the execution thread back to the invocation thread.
- {
- public:
- typedef ActiveResultHolder<void> ActiveResultHolderType;
- ActiveResult(ActiveResultHolderType* pHolder):
- _pHolder(pHolder)
- /// Creates the active result. For internal use only.
- {
- poco_check_ptr (pHolder);
- }
-
- ActiveResult(const ActiveResult& result)
- /// Copy constructor.
- {
- _pHolder = result._pHolder;
- _pHolder->duplicate();
- }
-
- ~ActiveResult()
- /// Destroys the result.
- {
- _pHolder->release();
- }
-
- ActiveResult& operator = (const ActiveResult& result)
- /// Assignment operator.
- {
- ActiveResult tmp(result);
- swap(tmp);
- return *this;
- }
-
- void swap(ActiveResult& result)
- {
- using std::swap;
- swap(_pHolder, result._pHolder);
- }
-
- void wait()
- /// Pauses the caller until the result becomes available.
- {
- _pHolder->wait();
- }
-
- bool tryWait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Returns true if the result became
- /// available, false otherwise.
- {
- return _pHolder->tryWait(milliseconds);
- }
-
- void wait(long milliseconds)
- /// Waits up to the specified interval for the result to
- /// become available. Throws a TimeoutException if the
- /// result did not became available.
- {
- _pHolder->wait(milliseconds);
- }
-
- bool available() const
- /// Returns true if a result is available.
- {
- return _pHolder->tryWait(0);
- }
-
- bool failed() const
- /// Returns true if the active method failed (and threw an exception).
- /// Information about the exception can be obtained by calling error().
- {
- return _pHolder->failed();
- }
-
- std::string error() const
- /// If the active method threw an exception, a textual representation
- /// of the exception is returned. An empty string is returned if the
- /// active method completed successfully.
- {
- return _pHolder->error();
- }
- Exception* exception() const
- /// If the active method threw an exception, a clone of the exception
- /// object is returned, otherwise null.
- {
- return _pHolder->exception();
- }
- void notify()
- /// Notifies the invoking thread that the result became available.
- /// For internal use only.
- {
- _pHolder->notify();
- }
-
- void error(const std::string& msg)
- /// Sets the failed flag and the exception message.
- {
- _pHolder->error(msg);
- }
- void error(const Exception& exc)
- /// Sets the failed flag and the exception message.
- {
- _pHolder->error(exc);
- }
-
- private:
- ActiveResult();
- ActiveResultHolderType* _pHolder;
- };
- } // namespace Poco
- #endif // Foundation_ActiveResult_INCLUDED
|