Skip to content
Snippets Groups Projects
Commit 3709ef83 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

onelab work:

- now OK to communicate with several clients at once, over different sockets (unique socket name/ip port is
  created automatically)
- started to replace old ConnectionManager infrastructure with onelab (already ok with "gmsh -listen")
parent d1f97610
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,7 @@
#include "CommandLine.h"
#include "OS.h"
#include "Context.h"
#include "ConnectionManager.h"
#include "onelab.h"
#include "robustPredicates.h"
#if defined(HAVE_MESH)
......@@ -252,8 +252,9 @@ int GmshFLTK(int argc, char **argv)
// listen to external solvers
if(CTX::instance()->solver.listen){
ConnectionManager::get(-1)->name = "unknown";
ConnectionManager::get(-1)->run("");
onelab::localNetworkClient *c = new onelab::localNetworkClient("Listen", "");
onelab::server::instance()->registerClient(c);
c->run("");
}
// loop
......
......@@ -449,10 +449,14 @@ namespace onelab{
protected:
// the name of the client
std::string _name;
// the id of the client, used to create a unique socket for this client
int _id;
public:
client(const std::string &name) : _name(name){}
virtual ~client(){}
std::string getName(){ return _name; }
void setId(int id){ _id = id; }
int getId(){ return _id; }
virtual bool run(const std::string &what){ return false; }
virtual bool isNetworkClient(){ return false; }
virtual bool kill(){ return false; }
......@@ -507,6 +511,7 @@ namespace onelab{
{
if(_clients.count(c->getName())) return false;
_clients[c->getName()] = c;
c->setId(_clients.size());
return true;
}
typedef std::map<std::string, client*>::iterator citer;
......@@ -569,15 +574,19 @@ namespace onelab{
std::string _commandLine;
// pid of the remote network client
int _pid;
// underlying GmshServer
GmshServer *_gmshServer;
public:
localNetworkClient(const std::string &name, const std::string &commandLine)
: localClient(name), _commandLine(commandLine), _pid(-1) {}
: localClient(name), _commandLine(commandLine), _pid(-1), _gmshServer(0) {}
virtual ~localNetworkClient(){}
virtual bool isNetworkClient(){ return true; }
const std::string &getCommandLine(){ return _commandLine; }
void setCommandLine(const std::string &s){ _commandLine = s; }
int getPid(){ return _pid; }
void setPid(int pid){ _pid = pid; }
GmshServer const *getServer(){ return _gmshServer; }
void setServer(GmshServer *server){ _gmshServer = server; }
virtual bool run(const std::string &what);
virtual bool kill();
};
......
......@@ -46,8 +46,9 @@ class onelabGmshServer : public GmshServer{
if(timeout > 0 && GetTimeInSeconds() - start > timeout)
return 2; // timout
if(_client->getPid() < 0)
return 1; // process has been killed
if(_client->getPid() < 0 ||
(_client->getCommandLine().empty() && !CTX::instance()->solver.listen))
return 1; // process has been killed or we stopped listening
// check if there is data (call select with a zero timeout to
// return immediately, i.e., do polling)
......@@ -64,6 +65,7 @@ class onelabGmshServer : public GmshServer{
else{
// an error happened
_client->setPid(-1);
_client->setServer(0);
return 1;
}
}
......@@ -72,29 +74,38 @@ class onelabGmshServer : public GmshServer{
bool onelab::localNetworkClient::run(const std::string &what)
{
new_connection:
_pid = 0;
_gmshServer = 0;
onelabGmshServer *server = new onelabGmshServer(this);
std::string sockname;
std::ostringstream tmp;
if(!strstr(CTX::instance()->solver.socketName.c_str(), ":")){
// Unix socket
std::ostringstream tmp;
tmp << CTX::instance()->homeDir << CTX::instance()->solver.socketName;
tmp << CTX::instance()->homeDir << CTX::instance()->solver.socketName << getId();
sockname = FixWindowsPath(tmp.str());
}
else{
// TCP/IP socket
sockname = CTX::instance()->solver.socketName;
// if only the port is given, prepend the host name
if(sockname.size() && sockname[0] == ':')
sockname = GetHostName() + sockname;
if(CTX::instance()->solver.socketName.size() &&
CTX::instance()->solver.socketName[0] == ':')
tmp << GetHostName(); // prepend hostname if only port is given
tmp << CTX::instance()->solver.socketName << getId();
sockname = tmp.str();
}
std::string prog = FixWindowsPath(_commandLine);
std::string command = prog + " " + what + " -onelab " + sockname;
std::string command = FixWindowsPath(_commandLine);
if(command.size()){
command += " " + what + " -onelab " + sockname;
#if !defined(WIN32)
command += " &";
command += " &";
#endif
}
else{
Msg::Info("Listening on socket '%s'", sockname.c_str());
}
int sock;
try{
......@@ -116,10 +127,15 @@ bool onelab::localNetworkClient::run(const std::string &what)
while(1) {
if(_pid < 0) break;
if(_pid < 0 || (command.empty() && !CTX::instance()->solver.listen))
break;
int stop = server->NonBlockingWait(sock, 0.1, 0.);
if(stop || _pid < 0) break;
if(stop || _pid < 0 || (command.empty() && !CTX::instance()->solver.listen))
break;
double timer = GetTimeInSeconds();
int type, length, swap;
if(!server->ReceiveHeader(&type, &length, &swap)){
......@@ -136,9 +152,11 @@ bool onelab::localNetworkClient::run(const std::string &what)
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:
{
......@@ -215,7 +233,11 @@ bool onelab::localNetworkClient::run(const std::string &what)
ParseString(message);
drawContext::global()->draw();
break;
/* FIXME need to change PViewDataRemote to work without ConnectionManager
case GmshSocket::GMSH_SPEED_TEST:
Msg::Info("got %d Mb message in %g seconds",
length / 1024 / 1024, GetTimeInSeconds() - timer);
break;
/* FIXME PViewDataRemote should store the onelab::localNetworkClient
case GmshSocket::GMSH_VERTEX_ARRAY:
{
int n = PView::list.size();
......@@ -233,10 +255,17 @@ bool onelab::localNetworkClient::run(const std::string &what)
FlGui::instance()->check();
}
_gmshServer = 0;
server->Shutdown();
delete server;
Msg::StatusBar(2, true, "Done running '%s'", _name.c_str());
if(command.empty()){
Msg::Info("Client disconnected: starting new connection");
goto new_connection;
}
return true;
}
......@@ -336,7 +365,10 @@ void onelab_cb(Fl_Widget *w, void *data)
for(onelab::server::citer it = onelab::server::instance()->firstClient();
it != onelab::server::instance()->lastClient(); it++){
onelab::client *c = it->second;
if(c->getName() == "Gmsh") continue;
if(c->getName() == "Gmsh" || // local Gmsh client
c->getName() == "Listen" || // unknown client connecting through "-listen"
c->getName() == "GmshRemote") // distant post-processing Gmsh client
continue;
std::string what = FlGui::instance()->onelab->getModelName();
if(action == "initial check" || action == "check"){
c->run(what);
......@@ -609,4 +641,3 @@ void solver_cb(Fl_Widget *w, void *data)
}
#endif
......@@ -61,21 +61,23 @@ class GmshSocket{
// receive data from a machine with a different byte ordering, and
// we swap the bytes in the payload)
enum MessageType{
GMSH_START = 1,
GMSH_STOP = 2,
GMSH_INFO = 10,
GMSH_WARNING = 11,
GMSH_ERROR = 12,
GMSH_PROGRESS = 13,
GMSH_MERGE_FILE = 20,
GMSH_PARSE_STRING = 21,
GMSH_VERTEX_ARRAY = 22,
GMSH_SPEED_TEST = 30,
GMSH_OPTION_1 = 100,
GMSH_OPTION_2 = 101,
GMSH_OPTION_3 = 102,
GMSH_OPTION_4 = 103,
GMSH_OPTION_5 = 104};
GMSH_START = 1,
GMSH_STOP = 2,
GMSH_INFO = 10,
GMSH_WARNING = 11,
GMSH_ERROR = 12,
GMSH_PROGRESS = 13,
GMSH_MERGE_FILE = 20,
GMSH_PARSE_STRING = 21,
GMSH_VERTEX_ARRAY = 22,
GMSH_PARAMETER = 23,
GMSH_PARAMETER_QUERY = 24,
GMSH_SPEED_TEST = 30,
GMSH_OPTION_1 = 100,
GMSH_OPTION_2 = 101,
GMSH_OPTION_3 = 102,
GMSH_OPTION_4 = 103,
GMSH_OPTION_5 = 104};
protected:
// the socket descriptor
int _sock;
......@@ -204,6 +206,11 @@ class GmshSocket{
}
return 0;
}
int ReceiveMessage(int len, void *buffer)
{
if(_ReceiveData(buffer, len) == len) return 1;
return 0;
}
// str should be allocated with size (len+1)
int ReceiveString(int len, char *str)
{
......@@ -365,7 +372,7 @@ class GmshServer : public GmshSocket{
}
if(command && strlen(command)){
SystemCall(command); // Start the solver
SystemCall(command); // start the solver
}
else{
timeout = 0.; // no command launched: don't set a timeout
......
......@@ -25,7 +25,7 @@ class GmshInteractiveClient{
_client.Stop();
_client.Disconnect();
}
void read(char *prompt)
void read(const char *prompt)
{
// pre-load a few commands in the history:
add_history("lc = 1.;");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment