From 3d436aa8e866bcc02b884708545ced6c4eb93d1a Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Fri, 29 Mar 2013 19:41:06 +0000 Subject: [PATCH] arbitrary depth subclients --- Fltk/gmshLocalNetworkClient.h | 23 +++++++++++++++-- Fltk/onelabGroup.cpp | 48 ++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Fltk/gmshLocalNetworkClient.h b/Fltk/gmshLocalNetworkClient.h index 979b5c62d6..54913a91b2 100644 --- a/Fltk/gmshLocalNetworkClient.h +++ b/Fltk/gmshLocalNetworkClient.h @@ -16,13 +16,24 @@ class gmshLocalNetworkClient : public onelab::localNetworkClient{ // metamodel that calls several underlying models); _clients keeps track of // the master (this) and the subclients. std::vector<gmshLocalNetworkClient*> _clients; + // client that launched this one (with GMSH_CONNECT); _father is zero for the + // master client (the one created by Gmsh). + gmshLocalNetworkClient *_father; public: gmshLocalNetworkClient(const std::string &name, const std::string &executable, const std::string &remoteLogin="") - : onelab::localNetworkClient(name, executable, remoteLogin) + : onelab::localNetworkClient(name, executable, remoteLogin), _father(0) { addClient(this); } + void setFather(gmshLocalNetworkClient *father) + { + _father = father; + } + gmshLocalNetworkClient *getFather() + { + return _father; + } void addClient(gmshLocalNetworkClient *client) { _clients.push_back(client); @@ -39,7 +50,15 @@ class gmshLocalNetworkClient : public onelab::localNetworkClient{ if(i >= 0 && i < getNumClients()) return _clients[i]; return 0; } - bool receiveMessage(int &type); + int getNumConnectedClients() + { + int n = 0; + for(int i = 0; i < getNumClients(); i++){ + if(_clients[i]->getPid() != -1) n++; + } + return n; + } + bool receiveMessage(gmshLocalNetworkClient *master); bool run(); bool kill(); }; diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp index 5c303f4e5b..9b0c09b7c3 100644 --- a/Fltk/onelabGroup.cpp +++ b/Fltk/onelabGroup.cpp @@ -145,8 +145,11 @@ class onelabGmshServer : public GmshServer{ } }; -bool gmshLocalNetworkClient::receiveMessage(int &type) +bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master) { + // receive a message on the associated GmshServer; 'master' is only used when + // creating subclients with GMSH_CONNECT. + double timer = GetTimeInSeconds(); if(!getGmshServer()){ @@ -154,11 +157,13 @@ bool gmshLocalNetworkClient::receiveMessage(int &type) return false; } - int length, swap; + int type, length, swap; if(!getGmshServer()->ReceiveHeader(&type, &length, &swap)){ Msg::Error("Abnormal server termination (did not receive message header)"); return false; } + else if(false) // debug + std::cout << "Client " << getName() << " receives header: " << type << std::endl; std::string message(length, ' '); if(!getGmshServer()->ReceiveMessage(length, &message[0])){ @@ -172,6 +177,11 @@ bool gmshLocalNetworkClient::receiveMessage(int &type) break; case GmshSocket::GMSH_STOP: setPid(-1); + if(getFather()){ + std::string reply = getName(); // reply is dummy + getFather()->getGmshServer()->SendMessage + (GmshSocket::GMSH_STOP, reply.size(), &reply[0]); + } break; case GmshSocket::GMSH_PARAMETER: { @@ -327,18 +337,19 @@ bool gmshLocalNetworkClient::receiveMessage(int &type) std::string command = onelab::parameter::getNextToken(message, first); gmshLocalNetworkClient* subClient = new gmshLocalNetworkClient(clientName, command); - onelabGmshServer *server = new onelabGmshServer(subClient); + onelabGmshServer *server = new onelabGmshServer(subClient); subClient->setPid(0); int sock = server->LaunchClient(); if(sock < 0){ // could not establish the connection: aborting server->Shutdown(); delete server; - Msg::Error("Could not connect client '%s'...", subClient->getName().c_str()); + Msg::Error("Could not connect client '%s'", subClient->getName().c_str()); } else{ Msg::StatusBar(true, "Running '%s'...", subClient->getName().c_str()); subClient->setGmshServer(server); - addClient(subClient); + subClient->setFather(this); + master->addClient(subClient); } } break; @@ -428,21 +439,13 @@ bool gmshLocalNetworkClient::run() } } } - // break the while(1) if the master client has stopped or if we encountered // a problem if(stop) break; // if data is available try to get the message from the corresponding // client; break the while(1) if we could not receive the message - int type = 0; - if(haveData && !c->receiveMessage(type)) break; - - // if the client is a subclient and it stopped, notify the master - if((c != this) && (type == GmshSocket::GMSH_STOP)){ - std::string reply = c->getName(); - getGmshServer()->SendMessage(GmshSocket::GMSH_STOP, reply.size(), &reply[0]); - } + if(haveData && !c->receiveMessage(this)) break; // break the while(1) if the master client has stopped if(c == this && c->getPid() < 0) break; @@ -452,10 +455,12 @@ bool gmshLocalNetworkClient::run() // subclients, if any. The servers are not deleted upon GMSH_STOP in // receiveMessage() to make sure we always delete them, even when the // disconnect was not clean. + std::vector<gmshLocalNetworkClient*> toDelete; for(int i = 0; i < getNumClients(); i++){ gmshLocalNetworkClient *c = getClient(i); GmshServer *s = c->getGmshServer(); c->setGmshServer(0); + c->setFather(0); if(s){ s->Shutdown(); delete s; @@ -463,10 +468,13 @@ bool gmshLocalNetworkClient::run() if(c != this){ if(c->getPid() > 0) Msg::Error("Subclient %s was not stopped correctly", c->getName().c_str()); - removeClient(c); - delete c; + toDelete.push_back(c); } } + for(unsigned int i = 0; i < toDelete.size(); i++){ + removeClient(toDelete[i]); + delete toDelete[i]; + } Msg::StatusBar(true, "Done running '%s'", _name.c_str()); @@ -1166,7 +1174,7 @@ static void onelab_number_output_range_cb(Fl_Widget *w, void *data) Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n, bool highlight, Fl_Color c) { - n->labelsize(FL_NORMAL_SIZE + 5); + n->labelsize(FL_NORMAL_SIZE + 4); int ww = _baseWidth - (n->depth() + 1) * _indent; ww /= 2; @@ -1354,7 +1362,7 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n, } ww /= 2; - n->labelsize(FL_NORMAL_SIZE + 5); + n->labelsize(FL_NORMAL_SIZE + 4); // non-editable value if(p.getReadOnly()){ @@ -1432,7 +1440,7 @@ static void onelab_region_input_cb(Fl_Widget *w, void *data) Fl_Widget *onelabGroup::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n, bool highlight, Fl_Color c) { - n->labelsize(FL_NORMAL_SIZE + 5); + n->labelsize(FL_NORMAL_SIZE + 4); int ww = _baseWidth - (n->depth() + 1) * _indent; ww /= 2; @@ -1456,7 +1464,7 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n, Fl_Widget *onelabGroup::_addParameterWidget(onelab::function &p, Fl_Tree_Item *n, bool highlight, Fl_Color c) { - n->labelsize(FL_NORMAL_SIZE + 5); + n->labelsize(FL_NORMAL_SIZE + 4); int ww = _baseWidth - (n->depth() + 1) * _indent; ww /= 2; -- GitLab