diff --git a/CMakeLists.txt b/CMakeLists.txt index 62ae814b2b73712f15cbbfaf29b5e431e479d832..720868fb1e5e708a713b4f1788dc1cc9ea6179e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ option(ENABLE_WRAP_PYTHON "Build Python wrappers" OFF) set(GMSH_MAJOR_VERSION 2) set(GMSH_MINOR_VERSION 7) -set(GMSH_PATCH_VERSION 0) +set(GMSH_PATCH_VERSION 1) set(GMSH_EXTRA_VERSION "" CACHE STRING "Gmsh extra version string") set(GMSH_VERSION "${GMSH_MAJOR_VERSION}.${GMSH_MINOR_VERSION}") @@ -109,7 +109,8 @@ set(GMSH_API Solver/dofManager.h Solver/femTerm.h Solver/laplaceTerm.h Solver/elasticityTerm.h Solver/crossConfTerm.h Solver/orthogonalTerm.h Solver/linearSystem.h Solver/linearSystemGMM.h Solver/linearSystemCSR.h - Solver/linearSystemFull.h Solver/elasticitySolver.h Solver/sparsityPattern.h Solver/groupOfElements.h Solver/linearSystemPETSc.h + Solver/linearSystemFull.h Solver/elasticitySolver.h Solver/sparsityPattern.h + Solver/groupOfElements.h Solver/linearSystemPETSc.h Post/PView.h Post/PViewData.h Plugin/PluginManager.h Post/OctreePost.h Post/PViewDataGModel.h Post/PViewOptions.h Post/ColorTable.h Numeric/nodalBasis.h diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp index f24a5a429c80c16804893dd6369a1ee7e5503623..730b6fac8da61dcef3b4b4e3a334f4d547a37839 100644 --- a/Common/Gmsh.cpp +++ b/Common/Gmsh.cpp @@ -23,7 +23,7 @@ #endif #if defined(HAVE_ONELAB) -#include "onelab.h" +#include "gmshLocalNetworkClient.h" #endif #if defined(HAVE_MESH) @@ -267,7 +267,7 @@ int GmshFLTK(int argc, char **argv) // listen to external solvers if(CTX::instance()->solver.listen){ - onelab::localNetworkClient *c = new onelab::localNetworkClient("Listen", ""); + gmshLocalNetworkClient *c = new gmshLocalNetworkClient("Listen", ""); c->run(); } diff --git a/Common/GmshSocket.h b/Common/GmshSocket.h index b64542f587aa7ecf6e2eb3a0058ec819fed0353b..de602076e09f0c50a0a31ad2c1cf39d3e74bf246 100644 --- a/Common/GmshSocket.h +++ b/Common/GmshSocket.h @@ -171,7 +171,9 @@ class GmshSocket{ FD_SET(s, &rfds); // select checks all IO descriptors between 0 and its first arg, // minus 1... hence the +1 below - return select(s + 1, &rfds, NULL, NULL, &tv); + int ret = select(s + 1, &rfds, NULL, NULL, &tv); + if(ret > 0 && FD_ISSET(s, &rfds)) return 1; + return ret; } void SendMessage(int type, int length, const void *msg) { diff --git a/Common/onelab.h b/Common/onelab.h index df96583af9abbee9a5405bd682258ed657c3d298..c57d14eab57f6db303306ff16a6c12f2ea5f74ab 100644 --- a/Common/onelab.h +++ b/Common/onelab.h @@ -1006,10 +1006,8 @@ namespace onelab{ void setPid(int pid){ _pid = pid; } GmshServer *getGmshServer(){ return _gmshServer; } void setGmshServer(GmshServer *server){ _gmshServer = server; } - #ifndef SWIG - virtual bool run(); - virtual bool kill(); - #endif + virtual bool run() = 0; + virtual bool kill() = 0; }; // The remote part of a network client. @@ -1035,7 +1033,7 @@ namespace onelab{ std::string msg = p.toChar(); if (name.size()) _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]); - else //get all parameters + else // get all parameters _gmshClient->SendMessage(GmshSocket::GMSH_PARAM_QUERY_ALL, msg.size(), &msg[0]); while(1){ diff --git a/Fltk/gmshLocalNetworkClient.h b/Fltk/gmshLocalNetworkClient.h new file mode 100644 index 0000000000000000000000000000000000000000..0f732409b08fac0a968006089dfc47f37f49735c --- /dev/null +++ b/Fltk/gmshLocalNetworkClient.h @@ -0,0 +1,43 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. + +#ifndef _GMSH_LOCAL_NETWORK_CLIENT_H_ +#define _GMSH_LOCAL_NETWORK_CLIENT_H_ + +#include <vector> +#include "onelab.h" + +class gmshLocalNetworkClient : public onelab::localNetworkClient{ + private: + std::vector<onelab::localNetworkClient*> _clients; + public: + gmshLocalNetworkClient(const std::string &name, const std::string &executable, + const std::string &remoteLogin="") + : onelab::localNetworkClient(name, executable, remoteLogin) + { + addClient(this); + } + void addClient(onelab::localNetworkClient *client) + { + _clients.push_back(client); + } + void removeClient(onelab::localNetworkClient *client) + { + std::vector<onelab::localNetworkClient*>::iterator it; + it = std::find(_clients.begin(), _clients.end(), client); + if(it != _clients.end()) _clients.erase(it); + } + int getNumClients(){ return _clients.size(); } + onelab::localNetworkClient *getClient(int i) + { + if(i >= 0 && i < getNumClients()) return _clients[i]; + return 0; + } + bool receiveMessage(); + bool run(); + bool kill(); +}; + +#endif diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index f628e9e11c16a7f1b8cf9e8157eb72d1285db5a1..57f68317b191d1e313f1c9d0346e8013ef508d87 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -33,6 +33,7 @@ typedef unsigned long intptr_t; #include "pluginWindow.h" #include "helpWindow.h" #include "onelabGroup.h" +#include "gmshLocalNetworkClient.h" #include "fileDialogs.h" #include "extraDialogs.h" #include "partitionDialog.h" @@ -186,7 +187,7 @@ static void file_remote_cb(Fl_Widget *w, void *data) onelab::localNetworkClient *c; onelab::server::citer it = onelab::server::instance()->findClient("GmshRemote"); if(it == onelab::server::instance()->lastClient()){ - c = new onelab::localNetworkClient("GmshRemote", ""); + c = new gmshLocalNetworkClient("GmshRemote", ""); c->setSocketSwitch("-socket"); } else diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp index e6f632d0729b0e197907c2673642c6fbaa2cfdf4..cca1fa7305fabfad6cfd40fb3c38f2e3c622b8aa 100644 --- a/Fltk/onelabGroup.cpp +++ b/Fltk/onelabGroup.cpp @@ -13,6 +13,7 @@ typedef unsigned long intptr_t; #include "GmshMessage.h" #include "onelab.h" +#include "gmshLocalNetworkClient.h" #include <FL/Fl_Check_Button.H> #include <FL/Fl_Box.H> #include <FL/Fl_Choice.H> @@ -89,18 +90,249 @@ class onelabGmshServer : public GmshServer{ else{ // an error happened _client->setPid(-1); - _client->setGmshServer(0); return 1; } } } }; -bool onelab::localNetworkClient::run() +bool gmshLocalNetworkClient::receiveMessage() +{ + double timer = GetTimeInSeconds(); + + if(!getGmshServer()){ + Msg::Error("Abnormal server termination (no valid server)"); + return false; + } + + int type, length, swap; + if(!getGmshServer()->ReceiveHeader(&type, &length, &swap)){ + Msg::Error("Abnormal server termination (did not receive message header)"); + return false; + } + + std::string message(length, ' '); + if(!getGmshServer()->ReceiveMessage(length, &message[0])){ + Msg::Error("Abnormal server termination (did not receive message body)"); + return false; + } + + switch (type) { + case GmshSocket::GMSH_START: + setPid(atoi(message.c_str())); + break; + case GmshSocket::GMSH_STOP: + setPid(-1); + break; + case GmshSocket::GMSH_PARAMETER: + { + std::string version, type, name; + onelab::parameter::getInfoFromChar(message, version, type, name); + if(onelab::parameter::version() != version){ + Msg::Error("OneLab version mismatch (server: %s / client: %s)", + onelab::parameter::version().c_str(), version.c_str()); + } + else if(type == "number"){ + onelab::number p; p.fromChar(message); set(p); + if(p.getName() == getName() + "/Progress") + if(FlGui::available()) + FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(), + p.getMin(), p.getMax()); + } + else if(type == "string"){ + onelab::string p; p.fromChar(message); set(p); + } + else if(type == "region"){ + onelab::region p; p.fromChar(message); set(p); + } + else if(type == "function"){ + onelab::function p; p.fromChar(message); set(p); + } + else + Msg::Error("Unknown OneLab parameter type: %s", type.c_str()); + } + break; + case GmshSocket::GMSH_PARAMETER_QUERY: + { + std::string version, type, name, reply; + onelab::parameter::getInfoFromChar(message, version, type, name); + if(onelab::parameter::version() != version){ + Msg::Error("OneLab version mismatch (server: %s / client: %s)", + onelab::parameter::version().c_str(), version.c_str()); + } + else if(type == "number"){ + std::vector<onelab::number> par; get(par, name); + if(par.size() == 1) reply = par[0].toChar(); + } + else if(type == "string"){ + std::vector<onelab::string> par; get(par, name); + if(par.size() == 1) reply = par[0].toChar(); + } + else if(type == "region"){ + std::vector<onelab::region> par; get(par, name); + if(par.size() == 1) reply = par[0].toChar(); + } + else if(type == "function"){ + std::vector<onelab::function> par; get(par, name); + if(par.size() == 1) reply = par[0].toChar(); + } + else + Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str()); + + if(reply.size()){ + getGmshServer()->SendMessage + (GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]); + } + else{ + reply = name; + getGmshServer()->SendMessage + (GmshSocket::GMSH_PARAM_NOT_FOUND, reply.size(), &reply[0]); + } + } + break; + case GmshSocket::GMSH_PARAM_QUERY_ALL: + { + std::string version, type, name, reply; + std::vector<std::string> replies; + onelab::parameter::getInfoFromChar(message, version, type, name); + if(onelab::parameter::version() != version){ + Msg::Error("OneLab version mismatch (server: %s / client: %s)", + onelab::parameter::version().c_str(), version.c_str()); + } + else if(type == "number"){ + std::vector<onelab::number> numbers; get(numbers); + for(std::vector<onelab::number>::iterator it = numbers.begin(); + it != numbers.end(); it++) replies.push_back((*it).toChar()); + } + else if(type == "string"){ + std::vector<onelab::string> strings; get(strings); + for(std::vector<onelab::string>::iterator it = strings.begin(); + it != strings.end(); it++) replies.push_back((*it).toChar()); + } + else if(type == "region"){ + std::vector<onelab::region> regions; get(regions); + for(std::vector<onelab::region>::iterator it = regions.begin(); + it != regions.end(); it++) replies.push_back((*it).toChar()); + } + else if(type == "function"){ + std::vector<onelab::function> functions; get(functions); + for(std::vector<onelab::function>::iterator it = functions.begin(); + it != functions.end(); it++) replies.push_back((*it).toChar()); + } + else + Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str()); + + for(unsigned int i = 0; i < replies.size(); i++) + getGmshServer()->SendMessage + (GmshSocket::GMSH_PARAM_QUERY_ALL, replies[i].size(), &replies[i][0]); + reply = "Sent all OneLab " + type + "s"; + getGmshServer()->SendMessage + (GmshSocket::GMSH_PARAM_QUERY_END, reply.size(), &reply[0]); + } + break; + case GmshSocket::GMSH_PROGRESS: + Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str()); + break; + case GmshSocket::GMSH_INFO: + Msg::Direct("Info : %s - %s", _name.c_str(), message.c_str()); + break; + case GmshSocket::GMSH_WARNING: + Msg::Warning("%s - %s", _name.c_str(), message.c_str()); + break; + case GmshSocket::GMSH_ERROR: + Msg::Error("%s - %s", _name.c_str(), message.c_str()); + break; + case GmshSocket::GMSH_MERGE_FILE: + if(CTX::instance()->solver.autoMergeFile){ + unsigned int n = PView::list.size(); + MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep, + CTX::instance()->solver.autoHideNewViews, true); + drawContext::global()->draw(); + if(FlGui::available() && n != PView::list.size()){ + FlGui::instance()->rebuildTree(); + FlGui::instance()->openModule("Post-processing"); + } + } + break; + case GmshSocket::GMSH_PARSE_STRING: + ParseString(message); + drawContext::global()->draw(); + break; + case GmshSocket::GMSH_SPEED_TEST: + Msg::Info("got %d Mb message in %g seconds", + length / 1024 / 1024, GetTimeInSeconds() - timer); + break; + case GmshSocket::GMSH_VERTEX_ARRAY: + { + int n = PView::list.size(); + PView::fillVertexArray(this, length, &message[0], swap); + if(FlGui::available()) + FlGui::instance()->updateViews(n != (int)PView::list.size()); + drawContext::global()->draw(); + } + break; + case GmshSocket::GMSH_CONNECT: + { + /* + const std::string subClientName = message; + onelab::localNetworkClient *subClient = dynamic_cast<onelab::localNetworkClient*> + (onelab::server::instance()->findClient(subClientName)->second); + if (! subClient) { + subClient = new onelab::localNetworkClient(subClientName, ""); + } + //if (onelab::server::instance()->getChanged(subClientName)) { + std::string sockname; + std::ostringstream tmp; + if(!strstr(CTX::instance()->solver.socketName.c_str(), ":")){ + // Unix socket + tmp << CTX::instance()->homeDir + << CTX::instance()->solver.socketName << subClient->getId(); + sockname = FixWindowsPath(tmp.str()); + } + else{ + // TCP/IP socket + if(CTX::instance()->solver.socketName.size() && + CTX::instance()->solver.socketName[0] == ':') + tmp << GetHostName(); // prepend hostname if only the port number is given + tmp << CTX::instance()->solver.socketName << subClient->getId(); + sockname = tmp.str(); + } + server->SendString(GmshSocket::GMSH_CONNECT, sockname.c_str()); + GmshServer *subServer = new onelabGmshServer(subClient, true); + subServer->Start("", sockname.c_str(), CTX::instance()->solver.timeout); + addClient(subClient, subServer); + */ + } + break; + case GmshSocket::GMSH_OLPARSE: + { +#if defined(HAVE_ONELAB_METAMODEL) + /* + localSolverClient *c = new InterfacedClient("OLParser","",""); + std::string ofileName = message ; + std::ofstream outfile(ofileName.c_str()); + if (outfile.is_open()) + c->convert_onefile(ofileName + ".ol",outfile); + else + Msg::Error("The file <%s> cannot be opened",ofileName.c_str()); + outfile.close(); + delete c; + */ +#endif + } + break; + default: + Msg::Warning("Received unknown message type (%d)", type); + break; + } + + return true; +} + +bool gmshLocalNetworkClient::run() { new_connection: - _pid = 0; - _gmshServer = 0; + setPid(0); // dummy pid, should be non-negative onelabGmshServer *server = new onelabGmshServer(this); @@ -120,7 +352,7 @@ bool onelab::localNetworkClient::run() sockname = tmp.str(); } - std::string command = FixWindowsPath(_executable); + std::string command = FixWindowsPath(getExecutable()); if(command.size()){ std::vector<std::string> args = onelabUtils::getCommandLine(this); for(unsigned int i = 0; i < args.size(); i++) @@ -137,11 +369,13 @@ bool onelab::localNetworkClient::run() CTX::instance()->solver.timeout); } catch(const char *err){ - Msg::Error("%s (on socket '%s')", err, sockname.c_str()); + Msg::Error("Abnormal server termination (%s on socket %s)", err, + sockname.c_str()); sock = -1; } if(sock < 0){ + // could not start the server: aborting server->Shutdown(); delete server; return false; @@ -149,195 +383,68 @@ bool onelab::localNetworkClient::run() Msg::StatusBar(true, "Running '%s'...", _name.c_str()); - while(1) { + setGmshServer(server); - if(_pid < 0 || (command.empty() && !CTX::instance()->solver.listen)) - break; - - int stop = server->NonBlockingWait(sock, 0.001, 0.); - - if(stop || _pid < 0 || (command.empty() && !CTX::instance()->solver.listen)) - break; - - double timer = GetTimeInSeconds(); - - int type, length, swap; - if(!server->ReceiveHeader(&type, &length, &swap)){ - Msg::Error("Did not receive message header: stopping server"); - break; - } - - std::string message(length, ' '); - if(!server->ReceiveMessage(length, &message[0])){ - Msg::Error("Did not receive message body: stopping server"); - break; - } - - switch (type) { - case GmshSocket::GMSH_START: - _pid = atoi(message.c_str()); - _gmshServer = server; - break; - case GmshSocket::GMSH_STOP: - _pid = -1; - _gmshServer = 0; - break; - case GmshSocket::GMSH_PARAMETER: - { - std::string version, type, name; - onelab::parameter::getInfoFromChar(message, version, type, name); - if(onelab::parameter::version() != version){ - Msg::Error("OneLab version mismatch (server: %s / client: %s)", - onelab::parameter::version().c_str(), version.c_str()); - } - else if(type == "number"){ - onelab::number p; p.fromChar(message); set(p); - if(p.getName() == getName() + "/Progress") - if(FlGui::available()) - FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(), - p.getMin(), p.getMax()); - } - else if(type == "string"){ - onelab::string p; p.fromChar(message); set(p); - } - else if(type == "region"){ - onelab::region p; p.fromChar(message); set(p); - } - else if(type == "function"){ - onelab::function p; p.fromChar(message); set(p); - } - else - Msg::Error("Unknown OneLab parameter type: %s", type.c_str()); + while(1) { + // loop on all the clients (usually only one, but can be more if we spawned + // subclients; in that case we might want to start from the one after the + // one we read from last, for better load balancing) + bool stop = false, haveData = false; + onelab::localNetworkClient *c = 0; + for(int i = 0; i < getNumClients(); i++){ + if(command.empty() && !CTX::instance()->solver.listen){ + // we stopped listening to the special "Listen" client + stop = true; + break; } - break; - case GmshSocket::GMSH_PARAMETER_QUERY: - { - std::string version, type, name, reply; - onelab::parameter::getInfoFromChar(message, version, type, name); - if(onelab::parameter::version() != version){ - Msg::Error("OneLab version mismatch (server: %s / client: %s)", - onelab::parameter::version().c_str(), version.c_str()); - } - else if(type == "number"){ - std::vector<onelab::number> par; get(par, name); - if(par.size() == 1) reply = par[0].toChar(); - } - else if(type == "string"){ - std::vector<onelab::string> par; get(par, name); - if(par.size() == 1) reply = par[0].toChar(); - } - else if(type == "region"){ - std::vector<onelab::region> par; get(par, name); - if(par.size() == 1) reply = par[0].toChar(); - } - else if(type == "function"){ - std::vector<onelab::function> par; get(par, name); - if(par.size() == 1) reply = par[0].toChar(); - } - else - Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str()); - - if(reply.size()){ - server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]); + c = getClient(i); + if(c->getPid() < 0){ + if(c == this){ // the "master" client stopped + stop = true; + break; } - else{ - // FIXME: introduce GMSH_PARAMETER_NOT_FOUND message to handle this - // (need to change onelab.h accordingly) - reply = "OneLab parameter '" + name + "' not found"; - server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]); + else{ // this subclient is not active anymore + continue; } } - break; - case GmshSocket::GMSH_PARAM_QUERY_ALL: - { - std::string version, type, name, reply; - std::vector<std::string> replies; - onelab::parameter::getInfoFromChar(message, version, type, name); - if(onelab::parameter::version() != version){ - Msg::Error("OneLab version mismatch (server: %s / client: %s)", - onelab::parameter::version().c_str(), version.c_str()); - } - else if(type == "number"){ - std::vector<onelab::number> numbers; get(numbers); - for(std::vector<onelab::number>::iterator it = numbers.begin(); - it != numbers.end(); it++) replies.push_back((*it).toChar()); - } - else if(type == "string"){ - std::vector<onelab::string> strings; get(strings); - for(std::vector<onelab::string>::iterator it = strings.begin(); - it != strings.end(); it++) replies.push_back((*it).toChar()); - } - else if(type == "region"){ - std::vector<onelab::region> regions; get(regions); - for(std::vector<onelab::region>::iterator it = regions.begin(); - it != regions.end(); it++) replies.push_back((*it).toChar()); - } - else if(type == "function"){ - std::vector<onelab::function> functions; get(functions); - for(std::vector<onelab::function>::iterator it = functions.begin(); - it != functions.end(); it++) replies.push_back((*it).toChar()); - } - else - Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str()); - - for(unsigned int i = 0; i < replies.size(); i++) - server->SendMessage - (GmshSocket::GMSH_PARAM_QUERY_ALL, replies[i].size(), &replies[i][0]); - reply = "Sent all OneLab " + type + "s"; - server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_END, reply.size(), &reply[0]); + GmshServer *s = c->getGmshServer(); + if(!s){ + Msg::Error("Abnormal server termination (no valid server)"); + stop = true; + break; } - break; - case GmshSocket::GMSH_PROGRESS: - Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str()); - break; - case GmshSocket::GMSH_INFO: - Msg::Direct("Info : %s - %s", _name.c_str(), message.c_str()); - break; - case GmshSocket::GMSH_WARNING: - Msg::Warning("%s - %s", _name.c_str(), message.c_str()); - break; - case GmshSocket::GMSH_ERROR: - Msg::Error("%s - %s", _name.c_str(), message.c_str()); - break; - case GmshSocket::GMSH_MERGE_FILE: - if(CTX::instance()->solver.autoMergeFile){ - unsigned int n = PView::list.size(); - MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep, - CTX::instance()->solver.autoHideNewViews, true); - drawContext::global()->draw(); - if(FlGui::available() && n != PView::list.size()){ - FlGui::instance()->rebuildTree(); - FlGui::instance()->openModule("Post-processing"); - } + else if(!s->NonBlockingWait(-1, 0.001, 0.)){ + // we have data from this particular client + haveData = true; + break; } - break; - case GmshSocket::GMSH_PARSE_STRING: - ParseString(message); - drawContext::global()->draw(); - break; - case GmshSocket::GMSH_SPEED_TEST: - Msg::Info("got %d Mb message in %g seconds", - length / 1024 / 1024, GetTimeInSeconds() - timer); - break; - case GmshSocket::GMSH_VERTEX_ARRAY: - { - int n = PView::list.size(); - PView::fillVertexArray(this, length, &message[0], swap); - if(FlGui::available()) - FlGui::instance()->updateViews(n != (int)PView::list.size()); - drawContext::global()->draw(); + else{ // an error occurred + stop = true; + break; } - break; - default: - Msg::Warning("Received unknown message type (%d)", type); - break; + } + if(stop) break; + if(haveData && !receiveMessage()) break; + if(c == this && c->getPid() < 0) break; + } + + // we are done running the (master) client: delete the servers and the + // subclients, if any. We do not delete the servers when we disconnect to make + // sure we always delete them, even when we disconnect "uncleanly" + for(int i = 0; i < getNumClients(); i++){ + onelab::localNetworkClient *c = getClient(i); + GmshServer *s = c->getGmshServer(); + c->setGmshServer(0); + if(s){ + s->Shutdown(); + delete s; + } + if(c != this){ + removeClient(c); + delete c; } } - _gmshServer = 0; - server->Shutdown(); - delete server; - Msg::StatusBar(true, "Done running '%s'", _name.c_str()); if(command.empty()){ @@ -348,18 +455,19 @@ bool onelab::localNetworkClient::run() return true; } -bool onelab::localNetworkClient::kill() +bool gmshLocalNetworkClient::kill() { - if(_pid > 0) { - if(KillProcess(_pid)){ - Msg::Info("Killed '%s' (pid %d)", _name.c_str(), _pid); + // FIXME: we should kill all the clients in the list + if(getPid() > 0) { + if(KillProcess(getPid())){ + Msg::Info("Killed '%s' (pid %d)", _name.c_str(), getPid()); if(FlGui::available()) FlGui::instance()->setProgress("Killed", 0, 0, 0); - _pid = -1; + setPid(-1); return true; } } - _pid = -1; + setPid(-1); return false; } @@ -1586,20 +1694,19 @@ void onelabGroup::addSolver(const std::string &name, const std::string &executab return; // solver already exists } - // unregister the other non-local clients so we keep only the new one + // delete the other non-local clients so we keep only the new one std::vector<onelab::client*> networkClients; for(onelab::server::citer it = onelab::server::instance()->firstClient(); it != onelab::server::instance()->lastClient(); it++) if(it->second->isNetworkClient()) networkClients.push_back(it->second); for(unsigned int i = 0; i < networkClients.size(); i++){ - onelab::server::instance()->unregisterClient(networkClients[i]); delete networkClients[i]; } // create and register the new client - onelab::localNetworkClient *c = new onelab::localNetworkClient(name, executable, - remoteLogin); + onelab::localNetworkClient *c = new gmshLocalNetworkClient(name, executable, + remoteLogin); c->setIndex(index); opt_solver_name(index, GMSH_SET, name); if(executable.empty()) onelab_choose_executable_cb(0, (void *)c); @@ -1617,7 +1724,6 @@ void onelabGroup::removeSolver(const std::string &name) if(it != onelab::server::instance()->lastClient()){ onelab::client *c = it->second; if(c->isNetworkClient()){ - onelab::server::instance()->unregisterClient(c); if(c->getIndex() >= 0 && c->getIndex() < 5){ opt_solver_name(c->getIndex(), GMSH_SET, ""); opt_solver_executable(c->getIndex(), GMSH_SET, ""); @@ -1668,7 +1774,7 @@ void solver_batch_cb(Fl_Widget *w, void *data) } // create client - onelab::localNetworkClient *c = new onelab::localNetworkClient(name, exe, host); + onelab::localNetworkClient *c = new gmshLocalNetworkClient(name, exe, host); c->setIndex(num); onelab::string o(c->getName() + "/Action"); diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index f8d51c4fafea39e9be6350ce50f68ad44b1779f5..d7a853b372e014a9273a2e632f575569a08cf1ff 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -34,7 +34,7 @@ typedef unsigned long intptr_t; #include "StringUtils.h" #if defined(HAVE_ONELAB) -#include "onelab.h" +#include "gmshLocalNetworkClient.h" #endif extern StringXColor GeneralOptions_Color[] ; @@ -552,7 +552,7 @@ static void solver_options_ok_cb(Fl_Widget *w, void *data) if(!old_listen && o->solver.butt[0]->value()){ onelab::server::citer it = onelab::server::instance()->findClient("Listen"); if(it == onelab::server::instance()->lastClient()){ - onelab::localNetworkClient *c = new onelab::localNetworkClient("Listen", ""); + onelab::localNetworkClient *c = new gmshLocalNetworkClient("Listen", ""); c->run(); } else diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp index 0e2f9671e0a4a6d00b5143c109dbacc8695c9f30..96b418b8d9c88e0a88fe7fe2dd9bff1e7f097f32 100644 --- a/Graphics/drawPost.cpp +++ b/Graphics/drawPost.cpp @@ -70,14 +70,16 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type, } else if (opt->lineType == 1) ctx->drawCylinder(opt->lineWidth, x, y, z, opt->light); - else { /// 2D (for now) MNT DIAGRAMS FOR FRAMES - float l = sqrt ((p0[0]-p1[0])*(p0[0]-p1[0]) + (p0[1]-p1[1])*(p0[1]-p1[1]) + (p0[2]-p1[2])*(p0[2]-p1[2]) ); + else { // 2D (for now) MNT diagrams for frames + float l = sqrt ((p0[0] - p1[0]) * (p0[0] - p1[0]) + + (p0[1] - p1[1]) * (p0[1] - p1[1]) + + (p0[2] - p1[2]) * (p0[2] - p1[2]) ); char *n0 = va->getNormalArray(3 * i); char *n1 = va->getNormalArray(3 * (i + 1)); double v0 = char2float(*n0), v1 = char2float(*n1); - float dir [3] = {(p1[0]-p0[0])/l , (p1[1]-p0[1])/l , (p1[2]-p0[2])/l }; - printf("%g %g %g %g %g %g\n",v0,v1,p0[0],p0[1],p1[0],p1[1]); - ctx->drawVector(1, 0, + float dir [3] = {(p1[0] - p0[0]) / l , (p1[1] - p0[1]) / l , (p1[2] - p0[2]) / l}; + printf("%g %g %g %g %g %g\n", v0, v1, p0[0], p0[1], p1[0], p1[1]); + ctx->drawVector(1, 0, p0[0] - dir[1] * v0 , p0[1] + dir[0] * v0 , 0.0, p1[0] - dir[1] * v1 , p1[1] + dir[0] * v1 , 0.0,opt->light); }