diff options
Diffstat (limited to 'src/Common/Request.h')
-rw-r--r-- | src/Common/Request.h | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/src/Common/Request.h b/src/Common/Request.h index 6f72667..d351c2a 100644 --- a/src/Common/Request.h +++ b/src/Common/Request.h @@ -26,6 +26,9 @@ #include <memory> #include <boost/bind.hpp> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/mutex.hpp> namespace Mad { namespace Common { @@ -34,35 +37,88 @@ class Request : public RequestHandler { private: friend class RequestManager; - Net::Signals::Signal1<void, const Request&> finished; + Net::Signals::Signal1<Request&> finished; std::auto_ptr<XmlPacket> res; Net::Exception exp; + boost::mutex mutex; + boost::condition_variable finishCond; + bool isFinished; + + static void doNothing(Request&) {} + public: - typedef Net::Signals::Signal1<void, const Request&>::slot_type slot_type; + typedef Net::Signals::Signal1<Request&>::slot_type slot_type; protected: + static slot_type empty_slot; + Request(Connection *connection, uint16_t requestId, slot_type slot) - : RequestHandler(connection, requestId), exp(Net::Exception::NOT_FINISHED) { + : RequestHandler(connection, requestId), exp(Net::Exception::NOT_FINISHED), isFinished(false) { finished.connect(slot); finished.connect(boost::bind(&Request::signalFinished, this)); } - void finish(std::auto_ptr<XmlPacket> result) {res = result; finished.emit(*this);} - void finish(const XmlPacket& result) {res.reset(new XmlPacket(result)); finished.emit(*this);} - void finishWithError(const Net::Exception &e) {exp = e; finished.emit(*this);} + virtual ~Request() { + wait(); + } + + void finish(std::auto_ptr<XmlPacket> result) { + { + boost::lock_guard<boost::mutex> lock(mutex); + + res = result; + isFinished = true; + } + + finishCond.notify_all(); + finished.emit(*this); + } + + void finish(const XmlPacket& result) { + { + boost::lock_guard<boost::mutex> lock(mutex); + + res.reset(new XmlPacket(result)); + isFinished = true; + } + + finishCond.notify_all(); + finished.emit(*this); + } + + void finishWithError(const Net::Exception &e) { + { + boost::lock_guard<boost::mutex> lock(mutex); + + exp = e; + isFinished = true; + } + + finishCond.notify_all(); + finished.emit(*this); + } virtual void sendRequest() = 0; virtual void handlePacket(const XmlPacket &packet); public: - const XmlPacket& getResult() const throw(Net::Exception) { + const XmlPacket& getResult() throw(Net::Exception) { + boost::lock_guard<boost::mutex> lock(mutex); + if(res.get()) return *res; throw exp; } + + void wait() { + boost::unique_lock<boost::mutex> lock(mutex); + + while(!isFinished) + finishCond.wait(lock); + } }; } |