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

update

parent 475fc35b
No related branches found
No related tags found
No related merge requests found
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#ifndef _GMSH_SOCKET_H_ #ifndef _GMSH_SOCKET_H_
#define _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_
//#include "GmshConfig.h"
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -62,25 +61,30 @@ class GmshSocket{ ...@@ -62,25 +61,30 @@ class GmshSocket{
// receive data from a machine with a different byte ordering, and // receive data from a machine with a different byte ordering, and
// we swap the bytes in the payload) // we swap the bytes in the payload)
enum MessageType{ enum MessageType{
GMSH_START = 1, GMSH_START = 1,
GMSH_STOP = 2, GMSH_STOP = 2,
GMSH_INFO = 10, GMSH_INFO = 10,
GMSH_WARNING = 11, GMSH_WARNING = 11,
GMSH_ERROR = 12, GMSH_ERROR = 12,
GMSH_PROGRESS = 13, GMSH_PROGRESS = 13,
GMSH_MERGE_FILE = 20, GMSH_MERGE_FILE = 20,
GMSH_PARSE_STRING = 21, GMSH_PARSE_STRING = 21,
GMSH_VERTEX_ARRAY = 22, GMSH_VERTEX_ARRAY = 22,
GMSH_PARAMETER = 23, GMSH_PARAMETER = 23,
GMSH_PARAMETER_QUERY = 24, GMSH_PARAMETER_QUERY = 24,
GMSH_PARAM_QUERY_ALL = 25, GMSH_PARAMETER_QUERY_ALL = 25,
GMSH_PARAM_QUERY_END = 26, GMSH_PARAMETER_QUERY_END = 26,
GMSH_SPEED_TEST = 30, GMSH_CONNECT = 27,
GMSH_OPTION_1 = 100, GMSH_OLPARSE = 28,
GMSH_OPTION_2 = 101, GMSH_PARAMETER_NOT_FOUND = 29,
GMSH_OPTION_3 = 102, GMSH_SPEED_TEST = 30,
GMSH_OPTION_4 = 103, GMSH_PARAMETER_CLEAR = 31,
GMSH_OPTION_5 = 104}; GMSH_PARAMETER_UPDATE = 32,
GMSH_OPTION_1 = 100,
GMSH_OPTION_2 = 101,
GMSH_OPTION_3 = 102,
GMSH_OPTION_4 = 103,
GMSH_OPTION_5 = 104};
protected: protected:
// the socket descriptor // the socket descriptor
int _sock; int _sock;
...@@ -150,10 +154,10 @@ class GmshSocket{ ...@@ -150,10 +154,10 @@ class GmshSocket{
WSACleanup(); WSACleanup();
#endif #endif
} }
// utility function to wait for some data to read on a socket (if // Wait for some data to read on the socket (if seconds and microseconds == 0
// seconds and microseconds == 0 we check for available data and // we check for available data and return immediately, i.e., we do
// return immediately, i.e., we do polling). Returns 0 when data is // polling). Returns 1 when data is available, 0 when nothing happened before
// available. // the time delay, -1 on error.
int Select(int seconds, int microseconds, int socket=-1) int Select(int seconds, int microseconds, int socket=-1)
{ {
int s = (socket < 0) ? _sock : socket; int s = (socket < 0) ? _sock : socket;
...@@ -163,8 +167,8 @@ class GmshSocket{ ...@@ -163,8 +167,8 @@ class GmshSocket{
fd_set rfds; fd_set rfds;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(s, &rfds); FD_SET(s, &rfds);
// select checks all IO descriptors between 0 and its first arg, // select checks all IO descriptors between 0 and its first arg, minus 1;
// minus 1... hence the +1 below // hence the +1 below
return select(s + 1, &rfds, NULL, NULL, &tv); return select(s + 1, &rfds, NULL, NULL, &tv);
} }
void SendMessage(int type, int length, const void *msg) void SendMessage(int type, int length, const void *msg)
...@@ -195,7 +199,7 @@ class GmshSocket{ ...@@ -195,7 +199,7 @@ class GmshSocket{
int ReceiveHeader(int *type, int *len, int *swap) int ReceiveHeader(int *type, int *len, int *swap)
{ {
*swap = 0; *swap = 0;
if(_ReceiveData(type, sizeof(int))){ if(_ReceiveData(type, sizeof(int)) > 0){
if(*type < 0) return 0; if(*type < 0) return 0;
if(*type > 65535){ if(*type > 65535){
// the data comes from a machine with different endianness and // the data comes from a machine with different endianness and
...@@ -203,7 +207,7 @@ class GmshSocket{ ...@@ -203,7 +207,7 @@ class GmshSocket{
*swap = 1; *swap = 1;
_SwapBytes((char*)type, sizeof(int), 1); _SwapBytes((char*)type, sizeof(int), 1);
} }
if(_ReceiveData(len, sizeof(int))){ if(_ReceiveData(len, sizeof(int)) > 0){
if(*len < 0) return 0; if(*len < 0) return 0;
if(*swap) _SwapBytes((char*)len, sizeof(int), 1); if(*swap) _SwapBytes((char*)len, sizeof(int), 1);
return 1; return 1;
...@@ -318,8 +322,10 @@ class GmshServer : public GmshSocket{ ...@@ -318,8 +322,10 @@ class GmshServer : public GmshSocket{
public: public:
GmshServer() : GmshSocket(), _portno(-1) {} GmshServer() : GmshSocket(), _portno(-1) {}
virtual ~GmshServer(){} virtual ~GmshServer(){}
virtual int SystemCall(const char *str) = 0; virtual int NonBlockingSystemCall(const char *str) = 0;
virtual int NonBlockingWait(int socket, double waitint, double timeout) = 0; virtual int NonBlockingWait(double waitint, double timeout, int socket=-1) = 0;
// start the client by launching "command" (command is supposed to contain
// '%s' where the socket name should appear)
int Start(const char *command, const char *sockname, double timeout) int Start(const char *command, const char *sockname, double timeout)
{ {
if(!sockname) throw "Invalid (null) socket name"; if(!sockname) throw "Invalid (null) socket name";
...@@ -361,7 +367,7 @@ class GmshServer : public GmshSocket{ ...@@ -361,7 +367,7 @@ class GmshServer : public GmshSocket{
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
if(tmpsock < 0) if(tmpsock < 0)
#else #else
if(tmpsock == INVALID_SOCKET) if(tmpsock == (int)INVALID_SOCKET)
#endif #endif
throw "Couldn't create socket"; throw "Couldn't create socket";
// bind the socket to its name // bind the socket to its name
...@@ -376,7 +382,7 @@ class GmshServer : public GmshSocket{ ...@@ -376,7 +382,7 @@ class GmshServer : public GmshSocket{
} }
if(!_portno){ // retrieve name if randomly assigned port if(!_portno){ // retrieve name if randomly assigned port
socklen_t addrlen = sizeof(addr_in); socklen_t addrlen = sizeof(addr_in);
int rc = getsockname(tmpsock, (struct sockaddr *)&addr_in, &addrlen); getsockname(tmpsock, (struct sockaddr *)&addr_in, &addrlen);
_portno = ntohs(addr_in.sin_port); _portno = ntohs(addr_in.sin_port);
int pos = _sockname.find(':'); // remove trailing ' ' or '0' int pos = _sockname.find(':'); // remove trailing ' ' or '0'
char tmp[256]; char tmp[256];
...@@ -386,13 +392,9 @@ class GmshServer : public GmshSocket{ ...@@ -386,13 +392,9 @@ class GmshServer : public GmshSocket{
} }
if(command && strlen(command)){ if(command && strlen(command)){
// we assume that the command line always ends with the socket name char cmd[1024];
std::string cmd(command); sprintf(cmd, command, _sockname.c_str());
cmd += " " + _sockname; NonBlockingSystemCall(cmd); // starts the solver
#if !defined(WIN32)
cmd += " &";
#endif
SystemCall(cmd.c_str()); // start the solver
} }
else{ else{
timeout = 0.; // no command launched: don't set a timeout timeout = 0.; // no command launched: don't set a timeout
...@@ -406,7 +408,7 @@ class GmshServer : public GmshSocket{ ...@@ -406,7 +408,7 @@ class GmshServer : public GmshSocket{
} }
// wait until we get data // wait until we get data
int ret = NonBlockingWait(tmpsock, 0.001, timeout); int ret = NonBlockingWait(0.001, timeout, tmpsock);
if(ret){ if(ret){
CloseSocket(tmpsock); CloseSocket(tmpsock);
if(ret == 2){ if(ret == 2){
......
// OneLab - Copyright (C) 2011-2012 ULg-UCL // OneLab - Copyright (C) 2011-2013 ULg-UCL
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE // ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE. // OF THIS SOFTWARE.
// //
// Please report all bugs and problems to the public mailing list <gmsh@geuz.org>. // Please report all bugs and problems to the public mailing list
// <gmsh@geuz.org>.
#ifndef _ONELAB_H_ #ifndef _ONELAB_H_
#define _ONELAB_H_ #define _ONELAB_H_
...@@ -630,6 +631,35 @@ namespace onelab{ ...@@ -630,6 +631,35 @@ namespace onelab{
std::set<string*, parameterLessThan> _strings; std::set<string*, parameterLessThan> _strings;
std::set<region*, parameterLessThan> _regions; std::set<region*, parameterLessThan> _regions;
std::set<function*, parameterLessThan> _functions; std::set<function*, parameterLessThan> _functions;
// delete a parameter from the parameter space
template <class T> bool _clear(const std::string &name,
const std::string &client,
std::set<T*, parameterLessThan> &ps)
{
if(name.empty() && client.size()){
for(typename std::set<T*, parameterLessThan>::iterator it = ps.begin();
it != ps.end(); it++){
T *p = *it;
if(p->hasClient(client)){
ps.erase(it);
delete p;
}
}
}
else{
T tmp(name);
typename std::set<T*, parameterLessThan>::iterator it = ps.find(&tmp);
if(it != ps.end()){
T *p = *it;
if(client.empty() || p->hasClient(client)){
ps.erase(it);
delete p;
return true;
}
}
}
return false;
}
// set a parameter in the parameter space; if it already exists, update it // set a parameter in the parameter space; if it already exists, update it
// (adding new clients if necessary). This needs to be locked to avoid race // (adding new clients if necessary). This needs to be locked to avoid race
// conditions when several clients try to set a parameter at the same time. // conditions when several clients try to set a parameter at the same time.
...@@ -672,7 +702,7 @@ namespace onelab{ ...@@ -672,7 +702,7 @@ namespace onelab{
} }
return true; return true;
} }
void _getAllParameters(std::set<parameter*> &ps) const void _getAllParameters(std::set<parameter*, parameterLessThan> &ps) const
{ {
ps.insert(_numbers.begin(), _numbers.end()); ps.insert(_numbers.begin(), _numbers.end());
ps.insert(_strings.begin(), _strings.end()); ps.insert(_strings.begin(), _strings.end());
...@@ -682,16 +712,25 @@ namespace onelab{ ...@@ -682,16 +712,25 @@ namespace onelab{
public: public:
parameterSpace(){} parameterSpace(){}
~parameterSpace(){ clear(); } ~parameterSpace(){ clear(); }
void clear() void clear(const std::string &name="", const std::string &client="")
{ {
std::set<parameter*> ps; if(name.empty() && client.empty()){
_getAllParameters(ps); std::set<parameter*, parameterLessThan> ps;
for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++) _getAllParameters(ps);
delete *it; for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
_numbers.clear(); it != ps.end(); it++)
_strings.clear(); delete *it;
_regions.clear(); _numbers.clear();
_functions.clear(); _strings.clear();
_regions.clear();
_functions.clear();
}
else{
bool done = _clear(name, client, _numbers);
if(!done) done = _clear(name, client, _strings);
if(!done) done = _clear(name, client, _regions);
if(!done) done = _clear(name, client, _functions);
}
} }
bool set(const number &p, bool set(const number &p,
const std::string &client=""){ return _set(p, client, _numbers); } const std::string &client=""){ return _set(p, client, _numbers); }
...@@ -711,14 +750,15 @@ namespace onelab{ ...@@ -711,14 +750,15 @@ namespace onelab{
const std::string &client=""){ return _get(ps, name, client, _functions); } const std::string &client=""){ return _get(ps, name, client, _functions); }
unsigned int getNumParameters() unsigned int getNumParameters()
{ {
return _numbers.size() + _strings.size() + _regions.size() + _functions.size(); return (int)(_numbers.size() + _strings.size() + _regions.size() + _functions.size());
} }
// check if at least one parameter depends on the given client // check if at least one parameter depends on the given client
bool hasClient(const std::string &client) const bool hasClient(const std::string &client) const
{ {
std::set<parameter*> ps; std::set<parameter*, parameterLessThan> ps;
_getAllParameters(ps); _getAllParameters(ps);
for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++) for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
it != ps.end(); it++)
if((*it)->hasClient(client)) return true; if((*it)->hasClient(client)) return true;
return false; return false;
} }
...@@ -726,9 +766,10 @@ namespace onelab{ ...@@ -726,9 +766,10 @@ namespace onelab{
// parameters that depend on a given client) // parameters that depend on a given client)
bool getChanged(const std::string &client="") const bool getChanged(const std::string &client="") const
{ {
std::set<parameter*> ps; std::set<parameter*, parameterLessThan> ps;
_getAllParameters(ps); _getAllParameters(ps);
for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++){ for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
it != ps.end(); it++){
if((client.empty() || (*it)->hasClient(client)) && (*it)->getChanged()){ if((client.empty() || (*it)->hasClient(client)) && (*it)->getChanged()){
return true; return true;
} }
...@@ -739,9 +780,10 @@ namespace onelab{ ...@@ -739,9 +780,10 @@ namespace onelab{
// parameters that depend on a given client) // parameters that depend on a given client)
bool setChanged(bool changed, const std::string &client="") bool setChanged(bool changed, const std::string &client="")
{ {
std::set<parameter*> ps; std::set<parameter*, parameterLessThan> ps;
_getAllParameters(ps); _getAllParameters(ps);
for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++) for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
it != ps.end(); it++)
if(client.empty() || (*it)->hasClient(client)) if(client.empty() || (*it)->hasClient(client))
(*it)->setChanged(changed); (*it)->setChanged(changed);
return true; return true;
...@@ -751,9 +793,10 @@ namespace onelab{ ...@@ -751,9 +793,10 @@ namespace onelab{
std::vector<std::string> toChar(const std::string &client="") const std::vector<std::string> toChar(const std::string &client="") const
{ {
std::vector<std::string> s; std::vector<std::string> s;
std::set<parameter*> ps; std::set<parameter*, parameterLessThan> ps;
_getAllParameters(ps); _getAllParameters(ps);
for(std::set<parameter*>::const_iterator it = ps.begin(); it != ps.end(); it++) for(std::set<parameter*, parameterLessThan>::const_iterator it = ps.begin();
it != ps.end(); it++)
if(client.empty() || (*it)->hasClient(client)) if(client.empty() || (*it)->hasClient(client))
s.push_back((*it)->toChar()); s.push_back((*it)->toChar());
return s; return s;
...@@ -813,6 +856,7 @@ namespace onelab{ ...@@ -813,6 +856,7 @@ namespace onelab{
virtual void sendMergeFileRequest(const std::string &msg){} virtual void sendMergeFileRequest(const std::string &msg){}
virtual void sendParseStringRequest(const std::string &msg){} virtual void sendParseStringRequest(const std::string &msg){}
virtual void sendVertexArray(const std::string &msg){} virtual void sendVertexArray(const std::string &msg){}
virtual bool clear(const std::string &name) = 0;
virtual bool set(const number &p) = 0; virtual bool set(const number &p) = 0;
virtual bool set(const string &p) = 0; virtual bool set(const string &p) = 0;
virtual bool set(const region &p) = 0; virtual bool set(const region &p) = 0;
...@@ -889,7 +933,10 @@ namespace onelab{ ...@@ -889,7 +933,10 @@ namespace onelab{
if(!_server) _server = new server(address); if(!_server) _server = new server(address);
return _server; return _server;
} }
void clear(){ _parameterSpace.clear(); } void clear(const std::string &name="", const std::string &client="")
{
_parameterSpace.clear(name, client);
}
template <class T> bool set(const T &p, const std::string &client="") template <class T> bool set(const T &p, const std::string &client="")
{ {
return _parameterSpace.set(p, client); return _parameterSpace.set(p, client);
...@@ -902,7 +949,7 @@ namespace onelab{ ...@@ -902,7 +949,7 @@ namespace onelab{
typedef std::map<std::string, client*>::iterator citer; typedef std::map<std::string, client*>::iterator citer;
citer firstClient(){ return _clients.begin(); } citer firstClient(){ return _clients.begin(); }
citer lastClient(){ return _clients.end(); } citer lastClient(){ return _clients.end(); }
int getNumClients() { return _clients.size(); }; int getNumClients() { return (int)_clients.size(); };
citer findClient(const std::string &name){ return _clients.find(name); } citer findClient(const std::string &name){ return _clients.find(name); }
void registerClient(client *c) void registerClient(client *c)
{ {
...@@ -962,6 +1009,11 @@ namespace onelab{ ...@@ -962,6 +1009,11 @@ namespace onelab{
{ {
server::instance()->unregisterClient(this); server::instance()->unregisterClient(this);
} }
virtual bool clear(const std::string &name="")
{
server::instance()->clear(name);
return true;
}
virtual bool set(const number &p){ return _set(p); } virtual bool set(const number &p){ return _set(p); }
virtual bool set(const string &p){ return _set(p); } virtual bool set(const string &p){ return _set(p); }
virtual bool set(const function &p){ return _set(p); } virtual bool set(const function &p){ return _set(p); }
...@@ -1006,10 +1058,8 @@ namespace onelab{ ...@@ -1006,10 +1058,8 @@ namespace onelab{
void setPid(int pid){ _pid = pid; } void setPid(int pid){ _pid = pid; }
GmshServer *getGmshServer(){ return _gmshServer; } GmshServer *getGmshServer(){ return _gmshServer; }
void setGmshServer(GmshServer *server){ _gmshServer = server; } void setGmshServer(GmshServer *server){ _gmshServer = server; }
#ifndef SWIG virtual bool run() = 0;
virtual bool run(); virtual bool kill() = 0;
virtual bool kill();
#endif
}; };
// The remote part of a network client. // The remote part of a network client.
...@@ -1035,8 +1085,8 @@ namespace onelab{ ...@@ -1035,8 +1085,8 @@ namespace onelab{
std::string msg = p.toChar(); std::string msg = p.toChar();
if (name.size()) if (name.size())
_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]); _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]); _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY_ALL, msg.size(), &msg[0]);
while(1){ while(1){
// stop if we have no communications for 5 minutes // stop if we have no communications for 5 minutes
...@@ -1065,17 +1115,21 @@ namespace onelab{ ...@@ -1065,17 +1115,21 @@ namespace onelab{
ps.push_back(p); ps.push_back(p);
return true; return true;
} }
if(type == GmshSocket::GMSH_PARAM_QUERY_ALL){ if(type == GmshSocket::GMSH_PARAMETER_QUERY_ALL){
T p; T p;
p.fromChar(msg); p.fromChar(msg);
ps.push_back(p); ps.push_back(p);
// do NOT return until all parameters have been downloaded // do NOT return until all parameters have been downloaded
} }
else if(type == GmshSocket::GMSH_PARAM_QUERY_END){ else if(type == GmshSocket::GMSH_PARAMETER_QUERY_END){
// all parameters have been sent
return true;
}
else if(type == GmshSocket::GMSH_PARAMETER_NOT_FOUND){
// parameter not found
return true; return true;
} }
else if(type == GmshSocket::GMSH_INFO){ else if(type == GmshSocket::GMSH_INFO){
// parameter not found or all aparameters have been sent
return true; return true;
} }
else{ else{
...@@ -1109,6 +1163,14 @@ namespace onelab{ ...@@ -1109,6 +1163,14 @@ namespace onelab{
} }
GmshClient *getGmshClient(){ return _gmshClient; } GmshClient *getGmshClient(){ return _gmshClient; }
virtual bool isNetworkClient(){ return true; } virtual bool isNetworkClient(){ return true; }
virtual bool clear(const std::string &name="")
{
if(!_gmshClient) return false;
std::string msg = name;
if(msg.empty()) msg = "*";
_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_CLEAR, msg.size(), &msg[0]);
return true;
}
virtual bool set(const number &p){ return _set(p); } virtual bool set(const number &p){ return _set(p); }
virtual bool set(const string &p){ return _set(p); } virtual bool set(const string &p){ return _set(p); }
virtual bool set(const function &p){ return _set(p); } virtual bool set(const function &p){ return _set(p); }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment