From mkolar at freenetproject.org Tue Aug 7 09:32:38 2007 From: mkolar at freenetproject.org (mkolar at freenetproject.org) Date: Tue, 7 Aug 2007 09:32:38 +0000 (UTC) Subject: [Cppfcplib] r14501 - trunk/apps/CppFCPLib Message-ID: <20070807093238.1D87A47AADA@freenetproject.org> Author: mkolar Date: 2007-08-07 09:32:37 +0000 (Tue, 07 Aug 2007) New Revision: 14501 Modified: trunk/apps/CppFCPLib/Node.h trunk/apps/CppFCPLib/NodeThread.cpp trunk/apps/CppFCPLib/NodeThread.h Log: * method for retrieving reason of node failure Modified: trunk/apps/CppFCPLib/Node.h =================================================================== --- trunk/apps/CppFCPLib/Node.h 2007-08-07 06:46:17 UTC (rev 14500) +++ trunk/apps/CppFCPLib/Node.h 2007-08-07 09:32:37 UTC (rev 14501) @@ -12,6 +12,7 @@ #include "TQueue.h" #include "NodeThread.h" #include "AdditionalFields.h" +#include "Exceptions.h" #include "sha256.h" @@ -44,11 +45,17 @@ void shutdown(); bool isAlive() const { - return nodeThread->isAlive(); + return nodeThread->isAlive_; } - + bool hasFailure() const { + return nodeThread->hasException_; + } std::exception getFailure() const { - return *nodeThread->getFailure(); + if ( nodeThread->isAlive_ ) + throw std::logic_error("There is no failure"); + if (! nodeThread->hasException_ ) + throw std::logic_error("Cannot retrieve the reason of a failure"); + return *(nodeThread->getFailure()); } const Message::Ptr getNodeHelloMessage() const; Modified: trunk/apps/CppFCPLib/NodeThread.cpp =================================================================== --- trunk/apps/CppFCPLib/NodeThread.cpp 2007-08-07 06:46:17 UTC (rev 14500) +++ trunk/apps/CppFCPLib/NodeThread.cpp 2007-08-07 09:32:37 UTC (rev 14501) @@ -17,7 +17,8 @@ host_(host), port_(port), s(new Server( host_, port_ )), - isAlive_(true) + isAlive_(true), + hasException_(false) { } @@ -57,18 +58,18 @@ // some error has occured, keep the thread so you can access the isAlive and getFailure log().log(ERROR, "_mgrThreag: Caught std::runtime_error"); log().log(ERROR, e.what()); - isAlive_ = false; + isAlive_ = false; hasException_ = true; exception = ZThread::CountedPtr ( new std::runtime_error(e) ); } catch (std::exception& e) { // some error has occured, keep the thread so you can access the isAlive and getFailure log().log(ERROR, "_mgrThreag: Caught std::exception"); log().log(ERROR, e.what()); - isAlive_ = false; + isAlive_ = false; hasException_ = true; exception = ZThread::CountedPtr ( new std::exception(e) ); } catch (...) { // thread is stopped and log().log(ERROR, "_mgrThreag: Caught something else"); - isAlive_ = false; + isAlive_ = false; hasException_ = false; return; } try { Modified: trunk/apps/CppFCPLib/NodeThread.h =================================================================== --- trunk/apps/CppFCPLib/NodeThread.h 2007-08-07 06:46:17 UTC (rev 14500) +++ trunk/apps/CppFCPLib/NodeThread.h 2007-08-07 09:32:37 UTC (rev 14501) @@ -28,6 +28,7 @@ boost::shared_ptr s; bool isAlive_; + bool hasException_; ZThread::CountedPtr exception; std::map jobs[2]; // 0 -- local jobs, 1 -- global jobs @@ -39,9 +40,6 @@ void doMessage(ServerMessage::Ptr message); public: void run(); - bool isAlive() const { - return isAlive_; - } ZThread::CountedPtr getFailure() const { return exception; } From mkolar at freenetproject.org Tue Aug 7 11:39:53 2007 From: mkolar at freenetproject.org (mkolar at freenetproject.org) Date: Tue, 7 Aug 2007 11:39:53 +0000 (UTC) Subject: [Cppfcplib] r14502 - trunk/apps/CppFCPLib Message-ID: <20070807113953.95E474791C0@freenetproject.org> Author: mkolar Date: 2007-08-07 11:39:53 +0000 (Tue, 07 Aug 2007) New Revision: 14502 Modified: trunk/apps/CppFCPLib/FCPResult.h trunk/apps/CppFCPLib/JobTicket.cpp trunk/apps/CppFCPLib/JobTicket.h trunk/apps/CppFCPLib/Log.cpp trunk/apps/CppFCPLib/Log.h trunk/apps/CppFCPLib/Message.h trunk/apps/CppFCPLib/Node.cpp trunk/apps/CppFCPLib/Node.h trunk/apps/CppFCPLib/NodeThread.cpp trunk/apps/CppFCPLib/NodeThread.h trunk/apps/CppFCPLib/Server.cpp trunk/apps/CppFCPLib/ServerMessage.cpp trunk/apps/CppFCPLib/ServerMessage.h Log: * logging -- constructor is private * node failure recognition Modified: trunk/apps/CppFCPLib/FCPResult.h =================================================================== --- trunk/apps/CppFCPLib/FCPResult.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/FCPResult.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -12,6 +12,8 @@ namespace FCPLib { class TestDDAReplyResponse { + friend struct TestDDAReplyConverter; + Message::Ptr message; TestDDAReplyResponse(Message::Ptr message_) : message(message_) {} @@ -37,8 +39,6 @@ const std::string getContent () const throw(std::logic_error){ return getField("ContentToWrite"); } - - friend struct TestDDAReplyConverter; }; class TestDDAResponse { Modified: trunk/apps/CppFCPLib/JobTicket.cpp =================================================================== --- trunk/apps/CppFCPLib/JobTicket.cpp 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/JobTicket.cpp 2007-08-07 11:39:53 UTC (rev 14502) @@ -9,18 +9,19 @@ using namespace FCPLib; JobTicket::Ptr -JobTicket::factory(std::string id, Message::Ptr cmd) +JobTicket::factory(Node* n, std::string id, Message::Ptr cmd) { log().log(NOISY, "Creating " + cmd->getHeader()); Ptr ret( new JobTicket() ); - ret->init(id, cmd); + ret->init(n, id, cmd); return ret; } void -JobTicket::init(std::string &id, Message::Ptr cmd) +JobTicket::init(Node* n, std::string &id, Message::Ptr cmd) { + this->node = n; this->id = id; this->cmd = cmd; @@ -77,6 +78,7 @@ unsigned int then = (unsigned int) time(0); unsigned int elapsed; while (!reqSentLock.tryAcquire(100)){ + elapsed = (unsigned int) time(0) - then; if (elapsed < timeout){ ZThread::Thread::sleep(1000); @@ -139,7 +141,7 @@ " keepJob=" + Converter::toString( keep ) + " global=" + Converter::toString( global ) + " persistent=" + Converter::toString( persistent ) + - " returnType=" + boost::lexical_cast( retType )+ "\n"; + " returnType=" + boost::lexical_cast( retType )+ "\n"; repr += "Message=" + cmd->getHeader(); Modified: trunk/apps/CppFCPLib/JobTicket.h =================================================================== --- trunk/apps/CppFCPLib/JobTicket.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/JobTicket.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -22,13 +22,18 @@ class Node; class JobTicket { + friend class Node; + friend class NodeThread; + public: typedef boost::shared_ptr Ptr; private: - static Ptr factory(std::string id, Message::Ptr cmd); + static Ptr factory(Node* n, std::string id, Message::Ptr cmd); protected: + Node* node; + std::string id; Message::Ptr cmd; @@ -108,12 +113,12 @@ ZThread::Guard g(access); return _isFinished; } +}; +class GetJob : public JobTicket { friend class Node; friend class NodeThread; -}; -class GetJob : public JobTicket { public: typedef boost::shared_ptr Ptr; enum ReturnType { Direct, Disk, None }; @@ -121,6 +126,7 @@ private: ReturnType retType; std::ostream *stream; + GetJob() : JobTicket(), retType(Direct), @@ -130,15 +136,13 @@ static Ptr factory(std::string id, Message::Ptr cmd); GetJob& setStream( std::ostream *s ) { stream = s; return *this; } GetJob& setReturnType( ReturnType r ) { retType = r; return *this; } + public: ~GetJob() { if (stream != NULL) delete stream; } std::ostream& getStream() { return *stream; } ReturnType getReturnType() const { return retType; } const std::string& toString(); - - friend class Node; - friend class NodeThread; }; typedef std::vector JobCollection; Modified: trunk/apps/CppFCPLib/Log.cpp =================================================================== --- trunk/apps/CppFCPLib/Log.cpp 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/Log.cpp 2007-08-07 11:39:53 UTC (rev 14502) @@ -5,13 +5,14 @@ using namespace FCPLib; -Logger::Logger(ostream &out_, verbosityLevel logLevel_) +Logger::Logger(std::ostream &out_, verbosityLevel logLevel_) : out(out_), logLevel(logLevel_) { } -void Logger::log(verbosityLevel logLevel_, const char *message) +void +Logger::log(verbosityLevel logLevel_, const char *message) { ZThread::Guard g(lock); @@ -23,13 +24,14 @@ out.flush(); } -void Logger::log(verbosityLevel logLevel_, std::string message) +void +Logger::log(verbosityLevel logLevel_, std::string message) { log(logLevel_, message.c_str()); } Logger& -log(ostream &out_, verbosityLevel logLevel_) +FCPLib::log(std::ostream &out_, verbosityLevel logLevel_) { static bool firstTime = true; static Logger* l; Modified: trunk/apps/CppFCPLib/Log.h =================================================================== --- trunk/apps/CppFCPLib/Log.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/Log.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -8,8 +8,6 @@ #include #include -using namespace std; - namespace FCPLib { typedef enum { @@ -23,18 +21,26 @@ NOISY, } verbosityLevel; +class Logger; + +Logger& +log(std::ostream &out_=std::cerr, verbosityLevel logLevel_=DEBUG); + class Logger{ + friend Logger& log(std::ostream&, verbosityLevel); + ZThread::Mutex lock; - ostream &out; + std::ostream &out; verbosityLevel logLevel; + + Logger(std::ostream &out_, verbosityLevel logLevel_=ERROR); public: - Logger(ostream &out_, verbosityLevel logLevel_=ERROR); - void log(verbosityLevel logLevel, const char *message); - void log(verbosityLevel logLevel, string message); + void log(verbosityLevel logLevel, const char *message); + void log(verbosityLevel logLevel, std::string message); }; } -FCPLib::Logger& log(ostream &out_=cerr, FCPLib::verbosityLevel logLevel_=FCPLib::DEBUG); + #endif Modified: trunk/apps/CppFCPLib/Message.h =================================================================== --- trunk/apps/CppFCPLib/Message.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/Message.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -45,13 +45,17 @@ }; class DataMessage : public Message { + friend class Message; + std::istream *stream_; int dataLength_; + protected: DataMessage() : stream_(NULL), dataLength_(0) { isDataType = true; } + public: typedef boost::shared_ptr Ptr; @@ -60,7 +64,6 @@ void toSocket(boost::asio::ip::tcp::socket& socket); ~DataMessage() { if (stream_ != NULL) delete stream_; } - friend class Message; }; typedef std::vector MessagePtrContainer; Modified: trunk/apps/CppFCPLib/Node.cpp =================================================================== --- trunk/apps/CppFCPLib/Node.cpp 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/Node.cpp 2007-08-07 11:39:53 UTC (rev 14502) @@ -39,7 +39,9 @@ Node::Node(std::string name_, std::string host, int port) : name(name_), clientReqQueue( new TQueue() ), - globalCommandsTimeout(20) // 20 sec + globalCommandsTimeout(20), // 20 sec + isAlive_(true), + hasException_(false) { if (!name.size()) name = Node::_getUniqueId(); @@ -47,7 +49,7 @@ try { - nodeThread = new NodeThread(host, port, clientReqQueue); + nodeThread = new NodeThread(this, host, port, clientReqQueue); } catch (boost::system::system_error &e) { @@ -59,7 +61,7 @@ m->setField("Name", name); m->setField("ExpectedVersion", "2.0"); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "Node constructor: waiting for response to ClientHello"); @@ -84,7 +86,7 @@ m->setField("NodeIdentifier", identifier); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for Peer message"); @@ -104,7 +106,7 @@ if (fields.hasField("WithMetadata")) m->setField("WithMetadata", fields.getField("WithMetadata")); if (fields.hasField("WithVolatile")) m->setField("WithVolatile", fields.getField("WithVolatile")); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for EndListPeers message"); @@ -123,7 +125,7 @@ Message::Ptr m = Message::factory( std::string("ListPeerNotes") ); m->setField("NodeIdentifier", identifier); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for EndListPeerNotes message"); @@ -144,7 +146,7 @@ else m->setField("URL", value); - JobTicket::Ptr job = JobTicket::factory( "", m); + JobTicket::Ptr job = JobTicket::factory( this, "", m); clientReqQueue->put(job); log().log(DEBUG, "waiting for Peer message"); @@ -164,7 +166,7 @@ m->setFields(message); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for Peer message"); @@ -188,7 +190,7 @@ if (fields.hasField("IsDisabled")) m->setField("IsDisabled", fields.getField("IsDisabled")); if (fields.hasField("IsListenOnly")) m->setField("IsListenOnly", fields.getField("IsListenOnly")); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for Peer message"); @@ -209,9 +211,9 @@ m->setField("NodeIdentifier", nodeIdentifier); m->setField("NoteText", Base64::base64Encode((const unsigned char*)noteText.c_str(), noteText.size())); - m->setField("PeerNoteType", boost::lexical_cast( peerNoteType )); + m->setField("PeerNoteType", boost::lexical_cast( peerNoteType )); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for PeerNote message"); @@ -231,7 +233,7 @@ m->setField("NodeIdentifier", identifier); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for PeerRemoved message"); @@ -253,7 +255,7 @@ if (fields.hasField("WithPrivate")) m->setField("WithPrivate", fields.getField("WithPrivate")); if (fields.hasField("WithVolatile")) m->setField("WithVolatile", fields.getField("WithVolatile")); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for NodeData message"); @@ -279,7 +281,7 @@ if (fields.hasField("WithShortDescription")) m->setField("WithShortDescription", fields.getField("WithShortDescription")); if (fields.hasField("WithLongDescription")) m->setField("WithLongDescription", fields.getField("WithLongDescription")); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for ConfigData message"); @@ -298,7 +300,7 @@ if (m->getHeader() != "ModifyConfig") throw std::logic_error("ModifyConfig message expected, " + m->getHeader() + " received"); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for ConfigData message"); @@ -322,7 +324,7 @@ if (write) m->setField("WantWriteDirectory", "true"); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for TestDDAReply"); @@ -344,7 +346,7 @@ if (readContent != "") m->setField("ReadContent", readContent); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for TestDDAComplete"); @@ -426,7 +428,7 @@ Message::Ptr m = Message::factory( std::string("GenerateSSK") ); m->setField("Identifier", identifier); - JobTicket::Ptr job = JobTicket::factory( identifier, m ); + JobTicket::Ptr job = JobTicket::factory( this, identifier, m ); clientReqQueue->put(job); log().log(DEBUG, "waiting for SSKKeypair message"); @@ -471,7 +473,7 @@ if (global && !persistent) throw std::invalid_argument("Global requests must be persistent"); - JobTicket::Ptr job = JobTicket::factory( m->getField("Identifier"), m ); + JobTicket::Ptr job = JobTicket::factory( this, m->getField("Identifier"), m ); job->setGlobal( global ).setPersistent( persistent ); clientReqQueue->put(job); @@ -513,7 +515,7 @@ if (global && !persistent) throw std::invalid_argument("Global requests must be persistent"); - JobTicket::Ptr job = JobTicket::factory( m->getField("Identifier"), m ); + JobTicket::Ptr job = JobTicket::factory( this, m->getField("Identifier"), m ); job->setGlobal( global ).setPersistent( persistent ); clientReqQueue->put(job); @@ -600,7 +602,7 @@ if (global && !persistent) throw std::invalid_argument("Global requests must be persistent"); - JobTicket::Ptr job = JobTicket::factory( m->getField("Identifier"), m ); + JobTicket::Ptr job = JobTicket::factory( this, m->getField("Identifier"), m ); job->setGlobal( global ).setPersistent( persistent ); clientReqQueue->put(job); @@ -777,7 +779,7 @@ m->setField("Identifier", id); m->setField("DontPoll", Converter::toString( dontPoll )); - JobTicket::Ptr job = JobTicket::factory( id, m ); + JobTicket::Ptr job = JobTicket::factory( this, id, m ); clientReqQueue->put(job); return job; @@ -790,7 +792,7 @@ m->setField( "Enabled", Converter::toString( enabled ) ); m->setField( "VerbosityMask", boost::lexical_cast(verbosity) ); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); } @@ -798,7 +800,7 @@ Node::refreshPersistentRequest() { Message::Ptr m = Message::factory( std::string("ListPersistentRequest") ); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); // persistent jobs will be updated @@ -842,7 +844,7 @@ m->setField( "Global", Converter::toString( job->isGlobal() ) ); m->setField( "Identifier", job->getId() ); - JobTicket::Ptr job_ = JobTicket::factory( "", m ); + JobTicket::Ptr job_ = JobTicket::factory( this, "", m ); clientReqQueue->put(job_); // wait on job that is to be cancelled @@ -871,7 +873,7 @@ if (!changed) throw std::invalid_argument("Either ClientToken or PriorityClass needs to be defined."); - JobTicket::Ptr job_ = JobTicket::factory( "", m ); + JobTicket::Ptr job_ = JobTicket::factory( this, "", m ); clientReqQueue->put(job_); } @@ -880,7 +882,7 @@ { log().log(DEBUG, "about to shutdown the node"); Message::Ptr m = Message::factory( std::string("Shutdown") ); - JobTicket::Ptr job = JobTicket::factory( "", m ); + JobTicket::Ptr job = JobTicket::factory( this, "", m ); clientReqQueue->put(job); try { Modified: trunk/apps/CppFCPLib/Node.h =================================================================== --- trunk/apps/CppFCPLib/Node.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/Node.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -30,6 +30,22 @@ void checkProtocolError(Response &resp); Message::Ptr nodeHelloMessage; + ZThread::Mutex access; + + bool isAlive_, hasException_; + std::auto_ptr failure; + + void setIsAlive(bool x) { + ZThread::Guard g(access); + isAlive_ = x; + } + + void setFailure(std::auto_ptr e) { + ZThread::Guard g(access); + failure = e; + hasException_ = true; + } + public: Node(std::string name, std::string host, int port); ~Node(); @@ -45,17 +61,20 @@ void shutdown(); bool isAlive() const { - return nodeThread->isAlive_; + ZThread::Guard g(access); + return isAlive_; } bool hasFailure() const { - return nodeThread->hasException_; + ZThread::Guard g(access); + return hasException_; } - std::exception getFailure() const { - if ( nodeThread->isAlive_ ) + std::auto_ptr getFailure() const { + ZThread::Guard g(access); + if ( isAlive_ ) throw std::logic_error("There is no failure"); - if (! nodeThread->hasException_ ) + if (! hasException_ ) throw std::logic_error("Cannot retrieve the reason of a failure"); - return *(nodeThread->getFailure()); + return failure; } const Message::Ptr getNodeHelloMessage() const; Modified: trunk/apps/CppFCPLib/NodeThread.cpp =================================================================== --- trunk/apps/CppFCPLib/NodeThread.cpp 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/NodeThread.cpp 2007-08-07 11:39:53 UTC (rev 14502) @@ -10,15 +10,15 @@ using namespace FCPLib; using namespace ZThread; -NodeThread::NodeThread(std::string &host, +NodeThread::NodeThread(Node* n, + std::string &host, int port, JobTicketQueuePtr clientReqQueue_) throw() - : clientReqQueue(clientReqQueue_), + : node(n), + clientReqQueue(clientReqQueue_), host_(host), port_(port), - s(new Server( host_, port_ )), - isAlive_(true), - hasException_(false) + s(new Server( host_, port_ )) { } @@ -53,23 +53,24 @@ // this object will be destroyed log().log(ERROR, "_mgrThread: Caught Synchronization_Exception"); log().log(ERROR, e.what()); + node->setIsAlive(false); return; } catch (std::runtime_error& e) { // some error has occured, keep the thread so you can access the isAlive and getFailure log().log(ERROR, "_mgrThreag: Caught std::runtime_error"); log().log(ERROR, e.what()); - isAlive_ = false; hasException_ = true; - exception = ZThread::CountedPtr ( new std::runtime_error(e) ); + node->setIsAlive(false); + node->setFailure( std::auto_ptr( new std::runtime_error(e) ) ); } catch (std::exception& e) { // some error has occured, keep the thread so you can access the isAlive and getFailure log().log(ERROR, "_mgrThreag: Caught std::exception"); log().log(ERROR, e.what()); - isAlive_ = false; hasException_ = true; - exception = ZThread::CountedPtr ( new std::exception(e) ); + node->setIsAlive(false); + node->setFailure( std::auto_ptr( new std::exception(e) ) ); } catch (...) { // thread is stopped and log().log(ERROR, "_mgrThreag: Caught something else"); - isAlive_ = false; hasException_ = false; + node->setIsAlive(false); return; } try { @@ -126,7 +127,7 @@ log().log(ERROR, "doMessage : global message does not contain identifier !???"); return; } - JobTicket::Ptr job = JobTicket::factory( m->getField("Identifier"), m ); + JobTicket::Ptr job = JobTicket::factory( this->node, m->getField("Identifier"), m ); job->setGlobal(isGlobal).setPersistent(true); jobs[isGlobal][m->getField("Identifier")] = job; return; Modified: trunk/apps/CppFCPLib/NodeThread.h =================================================================== --- trunk/apps/CppFCPLib/NodeThread.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/NodeThread.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -22,27 +22,23 @@ typedef ZThread::CountedPtr< JobTicketQueue > JobTicketQueuePtr; class NodeThread : public ZThread::Runnable { + friend class Node; + + Node* node; + JobTicketQueuePtr clientReqQueue; std::string host_; int port_; boost::shared_ptr s; - bool isAlive_; - bool hasException_; - ZThread::CountedPtr exception; - std::map jobs[2]; // 0 -- local jobs, 1 -- global jobs - friend class Node; - NodeThread(std::string &host, int port, JobTicketQueuePtr clientReqQueue_) throw(); + NodeThread(Node* n, std::string &host, int port, JobTicketQueuePtr clientReqQueue_) throw(); void sendClientReq(JobTicket::Ptr job); void doMessage(ServerMessage::Ptr message); public: void run(); - ZThread::CountedPtr getFailure() const { - return exception; - } }; } Modified: trunk/apps/CppFCPLib/Server.cpp =================================================================== --- trunk/apps/CppFCPLib/Server.cpp 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/Server.cpp 2007-08-07 11:39:53 UTC (rev 14502) @@ -19,12 +19,12 @@ if ( port == -1 ) port = 9481; tcp::resolver resolver(io_service); - tcp::resolver::query query(host, boost::lexical_cast(port)); + tcp::resolver::query query(host, boost::lexical_cast(port)); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); tcp::resolver::iterator end; // Try each endpoint until we successfully establish a connection. - socket_ = auto_ptr( new boost::asio::ip::tcp::socket(io_service) ); + socket_ = std::auto_ptr( new boost::asio::ip::tcp::socket(io_service) ); boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { Modified: trunk/apps/CppFCPLib/ServerMessage.cpp =================================================================== --- trunk/apps/CppFCPLib/ServerMessage.cpp 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/ServerMessage.cpp 2007-08-07 11:39:53 UTC (rev 14502) @@ -241,7 +241,7 @@ server->read(boost::asio::buffer(buf, m)); stream.write(buf, m); tmp -= m; - log().log(DEBUG, "NODE: read "+ boost::lexical_cast( m ) + " bytes of data, " + boost::lexical_cast( tmp ) + " still left"); + log().log(DEBUG, "NODE: read "+ boost::lexical_cast( m ) + " bytes of data, " + boost::lexical_cast( tmp ) + " still left"); } stream.flush(); Modified: trunk/apps/CppFCPLib/ServerMessage.h =================================================================== --- trunk/apps/CppFCPLib/ServerMessage.h 2007-08-07 09:32:37 UTC (rev 14501) +++ trunk/apps/CppFCPLib/ServerMessage.h 2007-08-07 11:39:53 UTC (rev 14502) @@ -81,29 +81,32 @@ template class ServerMessageT : public ServerMessage { + friend class ServerMessage; + ServerMessageT() {} + public: - bool isLast(const JobTicketPtr job) const { return isLastT( message )( job ); } bool isError() const { return isErrorT; } - friend class ServerMessage; }; class AllDataMessage : public ServerMessage { + friend class ServerMessage; + boost::shared_ptr server; int bytesToRead; void read(boost::shared_ptr s); AllDataMessage() {} + public: bool isLast(const JobTicketPtr job) const; bool isError() const { return false; } - friend class ServerMessage; }; typedef class ServerMessageT NodeHelloMessage; From mkolar at freenetproject.org Tue Aug 7 13:04:30 2007 From: mkolar at freenetproject.org (mkolar at freenetproject.org) Date: Tue, 7 Aug 2007 13:04:30 +0000 (UTC) Subject: [Cppfcplib] r14503 - trunk/apps/CppFCPLib Message-ID: <20070807130430.A7D9447AAFF@freenetproject.org> Author: mkolar Date: 2007-08-07 13:04:30 +0000 (Tue, 07 Aug 2007) New Revision: 14503 Modified: trunk/apps/CppFCPLib/Exceptions.h trunk/apps/CppFCPLib/JobTicket.cpp trunk/apps/CppFCPLib/JobTicket.h trunk/apps/CppFCPLib/Message.cpp trunk/apps/CppFCPLib/Node.cpp trunk/apps/CppFCPLib/Node.h trunk/apps/CppFCPLib/NodeThread.cpp trunk/apps/CppFCPLib/Server.cpp Log: * jobs will be cancelled if the connection is lost ( currently, they wait until time out ) Modified: trunk/apps/CppFCPLib/Exceptions.h =================================================================== --- trunk/apps/CppFCPLib/Exceptions.h 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/Exceptions.h 2007-08-07 13:04:30 UTC (rev 14503) @@ -18,6 +18,11 @@ ~FCPException() throw(); }; +class FCPNodeFailure : public std::runtime_error { +public: + FCPNodeFailure(std::string msg) : std::runtime_error(msg) {} +}; + class FileError : public std::runtime_error { std::string path_; public: Modified: trunk/apps/CppFCPLib/JobTicket.cpp =================================================================== --- trunk/apps/CppFCPLib/JobTicket.cpp 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/JobTicket.cpp 2007-08-07 13:04:30 UTC (rev 14503) @@ -4,6 +4,7 @@ #include #include "Utils.h" +#include "Node.h" using namespace FCPLib; @@ -35,8 +36,13 @@ JobTicket::wait(unsigned int timeout) { if (!timeout){ - while (!lock.tryAcquire(100)) + while (!lock.tryAcquire(100)) { + if (! node->isAlive() ) { + if ( node->hasFailure() ) throw node->getFailure(); + else throw FCPNodeFailure( "node thread is not alive" ); + } ZThread::Thread::sleep(100); + } lock.release(); return; } @@ -44,6 +50,10 @@ unsigned int then = (unsigned int) time(0); unsigned int elapsed; while (!reqSentLock.tryAcquire(100)){ + if (! node->isAlive() ) { + if ( node->hasFailure() ) throw node->getFailure(); + else throw FCPNodeFailure( "node thread is not alive" ); + } elapsed = (unsigned int) time(0) - then; if (elapsed < timeout){ ZThread::Thread::sleep(1000); @@ -57,6 +67,10 @@ } log().log(DEBUG, "wait:"+this->getCommandName()+":"+this->getId()+": job now dispatched"); while (!lock.tryAcquire(100)){ + if (! node->isAlive() ) { + if ( node->hasFailure() ) throw node->getFailure(); + else throw FCPNodeFailure( "node thread is not alive" ); + } elapsed = (unsigned int) time(0) - then; if (elapsed < timeout) { ZThread::Thread::sleep(2000); @@ -78,7 +92,10 @@ unsigned int then = (unsigned int) time(0); unsigned int elapsed; while (!reqSentLock.tryAcquire(100)){ - + if (! node->isAlive() ) { + if ( node->hasFailure() ) throw node->getFailure(); + else throw FCPNodeFailure( "node thread is not alive" ); + } elapsed = (unsigned int) time(0) - then; if (elapsed < timeout){ ZThread::Thread::sleep(1000); @@ -119,11 +136,11 @@ } GetJob::Ptr -GetJob::factory(std::string id, Message::Ptr cmd) +GetJob::factory(Node *n, std::string id, Message::Ptr cmd) { log().log(NOISY, "Creating " + cmd->getHeader()); Ptr ret( new GetJob() ); - ret->init(id, cmd); + ret->init(n, id, cmd); return ret; } Modified: trunk/apps/CppFCPLib/JobTicket.h =================================================================== --- trunk/apps/CppFCPLib/JobTicket.h 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/JobTicket.h 2007-08-07 13:04:30 UTC (rev 14503) @@ -64,7 +64,7 @@ _isFinished(false) {} - void init(std::string &id, Message::Ptr cmd); + void init(Node *n, std::string &id, Message::Ptr cmd); JobTicket& setKeep( bool x ) { keep = x; return *this; }; JobTicket& setGlobal( bool x ) { global = x; return *this; }; @@ -133,7 +133,7 @@ stream(NULL) {} - static Ptr factory(std::string id, Message::Ptr cmd); + static Ptr factory(Node*n, std::string id, Message::Ptr cmd); GetJob& setStream( std::ostream *s ) { stream = s; return *this; } GetJob& setReturnType( ReturnType r ) { retType = r; return *this; } Modified: trunk/apps/CppFCPLib/Message.cpp =================================================================== --- trunk/apps/CppFCPLib/Message.cpp 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/Message.cpp 2007-08-07 13:04:30 UTC (rev 14503) @@ -74,7 +74,12 @@ void Message::toSocket(boost::asio::ip::tcp::socket& socket) { - boost::asio::write(socket, boost::asio::buffer(toString())); + boost::system::error_code error; + if (!socket.is_open()) + throw std::runtime_error("Message::toSocket :: socket is closed"); + boost::asio::write(socket, boost::asio::buffer(toString()), boost::asio::transfer_all(), error); + if (error) + throw boost::system::system_error(error); } void @@ -99,15 +104,26 @@ void DataMessage::toSocket(boost::asio::ip::tcp::socket& socket) { + boost::system::error_code error; char buf[1024]; int tmp = dataLength_; - boost::asio::write( socket, boost::asio::buffer(toString()) ); + + if (!socket.is_open()) + throw std::runtime_error("DataMessage::toSocket :: socket is closed"); + boost::asio::write( socket, boost::asio::buffer(toString()), boost::asio::transfer_all(), error ); + if (error) + throw boost::system::system_error(error); + while (tmp > 0) { int m = std::min(tmp, 1024); stream_->read(buf, m); if (stream_->fail()) throw std::runtime_error("Error while reading data stream."); - boost::asio::write( socket, boost::asio::buffer(buf, m) ); + if (!socket.is_open()) + throw std::runtime_error("DataMessage::toSocket :: socket is closed"); + boost::asio::write( socket, boost::asio::buffer(buf, m), boost::asio::transfer_all(), error ); + if (error) + throw boost::system::system_error(error); tmp -= m; } } Modified: trunk/apps/CppFCPLib/Node.cpp =================================================================== --- trunk/apps/CppFCPLib/Node.cpp 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/Node.cpp 2007-08-07 13:04:30 UTC (rev 14503) @@ -671,7 +671,7 @@ m->setField("Filename", filename); if (fields.hasField("TempFilename")) m->setField("TempFilename", fields.getField("TempFilename")); - GetJob::Ptr job = GetJob::factory( m->getField("Identifier"), m ); + GetJob::Ptr job = GetJob::factory( this, m->getField("Identifier"), m ); job->setGlobal( global ).setPersistent( persistent ); job->setReturnType( GetJob::Disk ); @@ -719,7 +719,7 @@ if (fields.hasField("BinaryBlob")) m->setField("BinaryBlob", fields.getField("BinaryBlob")); if (fields.hasField("AllowedMIMETypes")) m->setField("AllowedMIMETypes", fields.getField("AllowedMIMETypes")); - GetJob::Ptr job = GetJob::factory( m->getField("Identifier"), m ); + GetJob::Ptr job = GetJob::factory( this, m->getField("Identifier"), m ); job->setGlobal( global ).setPersistent( persistent ); job->setReturnType( GetJob::None ); @@ -761,7 +761,7 @@ if (fields.hasField("BinaryBlob")) m->setField("BinaryBlob", fields.getField("BinaryBlob")); if (fields.hasField("AllowedMIMETypes")) m->setField("AllowedMIMETypes", fields.getField("AllowedMIMETypes")); - GetJob::Ptr job = GetJob::factory( m->getField("Identifier"), m ); + GetJob::Ptr job = GetJob::factory( this, m->getField("Identifier"), m ); job->setGlobal( global ).setPersistent( persistent ); job->setReturnType( GetJob::Direct ).setStream( stream ); Modified: trunk/apps/CppFCPLib/Node.h =================================================================== --- trunk/apps/CppFCPLib/Node.h 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/Node.h 2007-08-07 13:04:30 UTC (rev 14503) @@ -18,6 +18,8 @@ namespace FCPLib { class Node { + friend class NodeThread; + std::string name; ZThread::CountedPtr< JobTicketQueue > clientReqQueue; NodeThread* nodeThread; @@ -33,16 +35,16 @@ ZThread::Mutex access; bool isAlive_, hasException_; - std::auto_ptr failure; + std::auto_ptr failure; void setIsAlive(bool x) { ZThread::Guard g(access); isAlive_ = x; } - void setFailure(std::auto_ptr e) { + void setFailure(std::string e) { ZThread::Guard g(access); - failure = e; + failure = std::auto_ptr( new FCPNodeFailure( e ) ); hasException_ = true; } @@ -60,21 +62,21 @@ void shutdown(); - bool isAlive() const { + bool isAlive() { ZThread::Guard g(access); return isAlive_; } - bool hasFailure() const { + bool hasFailure() { ZThread::Guard g(access); return hasException_; } - std::auto_ptr getFailure() const { + FCPNodeFailure getFailure() { ZThread::Guard g(access); if ( isAlive_ ) throw std::logic_error("There is no failure"); if (! hasException_ ) throw std::logic_error("Cannot retrieve the reason of a failure"); - return failure; + return *failure; } const Message::Ptr getNodeHelloMessage() const; Modified: trunk/apps/CppFCPLib/NodeThread.cpp =================================================================== --- trunk/apps/CppFCPLib/NodeThread.cpp 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/NodeThread.cpp 2007-08-07 13:04:30 UTC (rev 14503) @@ -5,8 +5,8 @@ #include "NodeThread.h" #include "Log.h" +#include "Node.h" - using namespace FCPLib; using namespace ZThread; @@ -54,37 +54,24 @@ log().log(ERROR, "_mgrThread: Caught Synchronization_Exception"); log().log(ERROR, e.what()); node->setIsAlive(false); - return; } catch (std::runtime_error& e) { // some error has occured, keep the thread so you can access the isAlive and getFailure log().log(ERROR, "_mgrThreag: Caught std::runtime_error"); log().log(ERROR, e.what()); - node->setIsAlive(false); - node->setFailure( std::auto_ptr( new std::runtime_error(e) ) ); + node->setIsAlive( false ); + node->setFailure( e.what() ); } catch (std::exception& e) { // some error has occured, keep the thread so you can access the isAlive and getFailure log().log(ERROR, "_mgrThreag: Caught std::exception"); log().log(ERROR, e.what()); - node->setIsAlive(false); - node->setFailure( std::auto_ptr( new std::exception(e) ) ); + node->setIsAlive( false ); + node->setFailure( e.what() ); } catch (...) { - // thread is stopped and + // thread is stopped and we don't know what has happend log().log(ERROR, "_mgrThreag: Caught something else"); node->setIsAlive(false); - return; + node->setFailure( "unknown error" ); } - try { - while (!Thread::interrupted()) { - // dummy loop, wait untill interrupt - Thread::sleep(1000); - Thread::yield(); - } - } catch (ZThread::Synchronization_Exception& e) { - // thread was interupted, normal way to shutdown the thread - // this object will be destroyed - log().log(ERROR, "_mgrThread: Caught Synchronization_Exception"); - return; - } } void Modified: trunk/apps/CppFCPLib/Server.cpp =================================================================== --- trunk/apps/CppFCPLib/Server.cpp 2007-08-07 11:39:53 UTC (rev 14502) +++ trunk/apps/CppFCPLib/Server.cpp 2007-08-07 13:04:30 UTC (rev 14503) @@ -48,9 +48,14 @@ } void Server::send(const std::string &s){ + boost::system::error_code error; + log().log(DEBUG, "Sending:\n"+s+"-----------------\n"); - - boost::asio::write(*socket_, boost::asio::buffer(s)); + if (!socket_->is_open()) + throw std::runtime_error("Server::send :: socket is closed"); + boost::asio::write(*socket_, boost::asio::buffer(s), boost::asio::transfer_all(), error ); + if (error) + throw boost::system::system_error(error); } void Server::send(const Message::Ptr m) @@ -61,7 +66,16 @@ } bool Server::dataAvailable(){ - return socket_->available() != 0 || response.size() != 0; + boost::system::error_code error; + bool ret; + + if (!socket_->is_open()) + throw std::runtime_error("Server::dataAvailable :: socket is closed"); + ret = socket_->available(error) != 0 || response.size() != 0; + if (error) + throw boost::system::system_error(error); + + return ret; } void From mkolar at freenetproject.org Wed Aug 8 13:16:59 2007 From: mkolar at freenetproject.org (mkolar at freenetproject.org) Date: Wed, 8 Aug 2007 13:16:59 +0000 (UTC) Subject: [Cppfcplib] r14523 - trunk/apps/CppFCPLib Message-ID: <20070808131659.99347479EAD@freenetproject.org> Author: mkolar Date: 2007-08-08 13:16:59 +0000 (Wed, 08 Aug 2007) New Revision: 14523 Modified: trunk/apps/CppFCPLib/JobTicket.h trunk/apps/CppFCPLib/NodeThread.h trunk/apps/CppFCPLib/Server.cpp trunk/apps/CppFCPLib/Server.h trunk/apps/CppFCPLib/ServerMessage.cpp trunk/apps/CppFCPLib/ServerMessage.h Log: * direct get works Modified: trunk/apps/CppFCPLib/JobTicket.h =================================================================== --- trunk/apps/CppFCPLib/JobTicket.h 2007-08-07 22:24:26 UTC (rev 14522) +++ trunk/apps/CppFCPLib/JobTicket.h 2007-08-08 13:16:59 UTC (rev 14523) @@ -138,7 +138,7 @@ GetJob& setReturnType( ReturnType r ) { retType = r; return *this; } public: - ~GetJob() { if (stream != NULL) delete stream; } + ~GetJob() {} std::ostream& getStream() { return *stream; } ReturnType getReturnType() const { return retType; } Modified: trunk/apps/CppFCPLib/NodeThread.h =================================================================== --- trunk/apps/CppFCPLib/NodeThread.h 2007-08-07 22:24:26 UTC (rev 14522) +++ trunk/apps/CppFCPLib/NodeThread.h 2007-08-08 13:16:59 UTC (rev 14523) @@ -39,6 +39,10 @@ void doMessage(ServerMessage::Ptr message); public: void run(); + ~NodeThread() { + jobs[0].clear(); + jobs[1].clear(); + } }; } Modified: trunk/apps/CppFCPLib/Server.cpp =================================================================== --- trunk/apps/CppFCPLib/Server.cpp 2007-08-07 22:24:26 UTC (rev 14522) +++ trunk/apps/CppFCPLib/Server.cpp 2007-08-08 13:16:59 UTC (rev 14523) @@ -79,7 +79,16 @@ } void -Server::read(boost::asio::mutable_buffers_1 buf) +Server::read(char *buf, std::size_t len) { - boost::asio::read(*socket_, buf); + log().log(NOISY, "Server::read: top"); + boost::system::error_code error; + + while (response.size() < len) { + log().log(NOISY, "bytes read: " + boost::lexical_cast(response.size())); + response.commit(socket_->read_some(response.prepare(len), error)); + if (error) + throw boost::system::system_error(error); + } + response_stream.read(buf, len); } Modified: trunk/apps/CppFCPLib/Server.h =================================================================== --- trunk/apps/CppFCPLib/Server.h 2007-08-07 22:24:26 UTC (rev 14522) +++ trunk/apps/CppFCPLib/Server.h 2007-08-08 13:16:59 UTC (rev 14523) @@ -21,7 +21,7 @@ public: ~Server(); std::string readln(); - void read(boost::asio::mutable_buffers_1); + void read(char*, std::size_t); void send(const std::string &s); void send(Message::Ptr m); bool dataAvailable(); Modified: trunk/apps/CppFCPLib/ServerMessage.cpp =================================================================== --- trunk/apps/CppFCPLib/ServerMessage.cpp 2007-08-07 22:24:26 UTC (rev 14522) +++ trunk/apps/CppFCPLib/ServerMessage.cpp 2007-08-08 13:16:59 UTC (rev 14523) @@ -230,18 +230,20 @@ bool AllDataMessage::isLast(const JobTicketPtr job) const { + log().log(NOISY, "AllDataMessage::isLast: top"); GetJob::Ptr job_ = boost::dynamic_pointer_cast( job ); std::ostream& stream = job_->getStream(); char buf[1024]; - int tmp = bytesToRead; - while (tmp > 0) { - int m = std::min(tmp, 1024); - server->read(boost::asio::buffer(buf, m)); + std::size_t bytes_available = bytesToRead; + log().log(NOISY, "bytesToRead = " + boost::lexical_cast( bytes_available )); + while (bytes_available > 0) { + std::size_t m = std::min(bytes_available, 1024); + server->read(buf, m); stream.write(buf, m); - tmp -= m; - log().log(DEBUG, "NODE: read "+ boost::lexical_cast( m ) + " bytes of data, " + boost::lexical_cast( tmp ) + " still left"); + bytes_available -= m; + log().log(DEBUG, "NODE: read "+ boost::lexical_cast( m ) + " bytes of data, " + boost::lexical_cast( bytes_available ) + " still left"); } stream.flush(); Modified: trunk/apps/CppFCPLib/ServerMessage.h =================================================================== --- trunk/apps/CppFCPLib/ServerMessage.h 2007-08-07 22:24:26 UTC (rev 14522) +++ trunk/apps/CppFCPLib/ServerMessage.h 2007-08-08 13:16:59 UTC (rev 14523) @@ -98,7 +98,7 @@ friend class ServerMessage; boost::shared_ptr server; - int bytesToRead; + std::size_t bytesToRead; void read(boost::shared_ptr s);