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

update

parent 475fc35b
Branches
Tags
No related merge requests found
......@@ -27,7 +27,6 @@
#ifndef _GMSH_SOCKET_H_
#define _GMSH_SOCKET_H_
//#include "GmshConfig.h"
#include <string>
#include <stdio.h>
#include <stdlib.h>
......@@ -62,25 +61,30 @@ 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_PARAMETER = 23,
GMSH_PARAMETER_QUERY = 24,
GMSH_PARAM_QUERY_ALL = 25,
GMSH_PARAM_QUERY_END = 26,
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_PARAMETER_QUERY_ALL = 25,
GMSH_PARAMETER_QUERY_END = 26,
GMSH_CONNECT = 27,
GMSH_OLPARSE = 28,
GMSH_PARAMETER_NOT_FOUND = 29,
GMSH_SPEED_TEST = 30,
GMSH_PARAMETER_CLEAR = 31,
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:
// the socket descriptor
int _sock;
......@@ -150,10 +154,10 @@ class GmshSocket{
WSACleanup();
#endif
}
// utility function to wait for some data to read on a socket (if
// seconds and microseconds == 0 we check for available data and
// return immediately, i.e., we do polling). Returns 0 when data is
// available.
// Wait for some data to read on the socket (if seconds and microseconds == 0
// we check for available data and return immediately, i.e., we do
// polling). Returns 1 when data is available, 0 when nothing happened before
// the time delay, -1 on error.
int Select(int seconds, int microseconds, int socket=-1)
{
int s = (socket < 0) ? _sock : socket;
......@@ -163,8 +167,8 @@ class GmshSocket{
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(s, &rfds);
// select checks all IO descriptors between 0 and its first arg,
// minus 1... hence the +1 below
// 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);
}
void SendMessage(int type, int length, const void *msg)
......@@ -195,7 +199,7 @@ class GmshSocket{
int ReceiveHeader(int *type, int *len, int *swap)
{
*swap = 0;
if(_ReceiveData(type, sizeof(int))){
if(_ReceiveData(type, sizeof(int)) > 0){
if(*type < 0) return 0;
if(*type > 65535){
// the data comes from a machine with different endianness and
......@@ -203,7 +207,7 @@ class GmshSocket{
*swap = 1;
_SwapBytes((char*)type, sizeof(int), 1);
}
if(_ReceiveData(len, sizeof(int))){
if(_ReceiveData(len, sizeof(int)) > 0){
if(*len < 0) return 0;
if(*swap) _SwapBytes((char*)len, sizeof(int), 1);
return 1;
......@@ -318,8 +322,10 @@ class GmshServer : public GmshSocket{
public:
GmshServer() : GmshSocket(), _portno(-1) {}
virtual ~GmshServer(){}
virtual int SystemCall(const char *str) = 0;
virtual int NonBlockingWait(int socket, double waitint, double timeout) = 0;
virtual int NonBlockingSystemCall(const char *str) = 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)
{
if(!sockname) throw "Invalid (null) socket name";
......@@ -361,7 +367,7 @@ class GmshServer : public GmshSocket{
#if !defined(WIN32) || defined(__CYGWIN__)
if(tmpsock < 0)
#else
if(tmpsock == INVALID_SOCKET)
if(tmpsock == (int)INVALID_SOCKET)
#endif
throw "Couldn't create socket";
// bind the socket to its name
......@@ -376,7 +382,7 @@ class GmshServer : public GmshSocket{
}
if(!_portno){ // retrieve name if randomly assigned port
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);
int pos = _sockname.find(':'); // remove trailing ' ' or '0'
char tmp[256];
......@@ -386,13 +392,9 @@ class GmshServer : public GmshSocket{
}
if(command && strlen(command)){
// we assume that the command line always ends with the socket name
std::string cmd(command);
cmd += " " + _sockname;
#if !defined(WIN32)
cmd += " &";
#endif
SystemCall(cmd.c_str()); // start the solver
char cmd[1024];
sprintf(cmd, command, _sockname.c_str());
NonBlockingSystemCall(cmd); // starts the solver
}
else{
timeout = 0.; // no command launched: don't set a timeout
......@@ -406,7 +408,7 @@ class GmshServer : public GmshSocket{
}
// wait until we get data
int ret = NonBlockingWait(tmpsock, 0.001, timeout);
int ret = NonBlockingWait(0.001, timeout, tmpsock);
if(ret){
CloseSocket(tmpsock);
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
// obtaining a copy of this software and associated documentation
......@@ -22,7 +22,8 @@
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// 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_
#define _ONELAB_H_
......@@ -630,6 +631,35 @@ namespace onelab{
std::set<string*, parameterLessThan> _strings;
std::set<region*, parameterLessThan> _regions;
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
// (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.
......@@ -672,7 +702,7 @@ namespace onelab{
}
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(_strings.begin(), _strings.end());
......@@ -682,16 +712,25 @@ namespace onelab{
public:
parameterSpace(){}
~parameterSpace(){ clear(); }
void clear()
void clear(const std::string &name="", const std::string &client="")
{
std::set<parameter*> ps;
_getAllParameters(ps);
for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++)
delete *it;
_numbers.clear();
_strings.clear();
_regions.clear();
_functions.clear();
if(name.empty() && client.empty()){
std::set<parameter*, parameterLessThan> ps;
_getAllParameters(ps);
for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
it != ps.end(); it++)
delete *it;
_numbers.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,
const std::string &client=""){ return _set(p, client, _numbers); }
......@@ -711,14 +750,15 @@ namespace onelab{
const std::string &client=""){ return _get(ps, name, client, _functions); }
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
bool hasClient(const std::string &client) const
{
std::set<parameter*> ps;
std::set<parameter*, parameterLessThan> 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;
return false;
}
......@@ -726,9 +766,10 @@ namespace onelab{
// parameters that depend on a given client)
bool getChanged(const std::string &client="") const
{
std::set<parameter*> ps;
std::set<parameter*, parameterLessThan> 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()){
return true;
}
......@@ -739,9 +780,10 @@ namespace onelab{
// parameters that depend on a given client)
bool setChanged(bool changed, const std::string &client="")
{
std::set<parameter*> ps;
std::set<parameter*, parameterLessThan> 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)->setChanged(changed);
return true;
......@@ -751,9 +793,10 @@ namespace onelab{
std::vector<std::string> toChar(const std::string &client="") const
{
std::vector<std::string> s;
std::set<parameter*> ps;
std::set<parameter*, parameterLessThan> 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))
s.push_back((*it)->toChar());
return s;
......@@ -813,6 +856,7 @@ namespace onelab{
virtual void sendMergeFileRequest(const std::string &msg){}
virtual void sendParseStringRequest(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 string &p) = 0;
virtual bool set(const region &p) = 0;
......@@ -889,7 +933,10 @@ namespace onelab{
if(!_server) _server = new server(address);
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="")
{
return _parameterSpace.set(p, client);
......@@ -902,7 +949,7 @@ namespace onelab{
typedef std::map<std::string, client*>::iterator citer;
citer firstClient(){ return _clients.begin(); }
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); }
void registerClient(client *c)
{
......@@ -962,6 +1009,11 @@ namespace onelab{
{
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 string &p){ return _set(p); }
virtual bool set(const function &p){ return _set(p); }
......@@ -1006,10 +1058,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,8 +1085,8 @@ namespace onelab{
std::string msg = p.toChar();
if (name.size())
_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]);
else //get all parameters
_gmshClient->SendMessage(GmshSocket::GMSH_PARAM_QUERY_ALL, msg.size(), &msg[0]);
else // get all parameters
_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY_ALL, msg.size(), &msg[0]);
while(1){
// stop if we have no communications for 5 minutes
......@@ -1065,17 +1115,21 @@ namespace onelab{
ps.push_back(p);
return true;
}
if(type == GmshSocket::GMSH_PARAM_QUERY_ALL){
if(type == GmshSocket::GMSH_PARAMETER_QUERY_ALL){
T p;
p.fromChar(msg);
ps.push_back(p);
// 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;
}
else if(type == GmshSocket::GMSH_INFO){
// parameter not found or all aparameters have been sent
return true;
}
else{
......@@ -1109,6 +1163,14 @@ namespace onelab{
}
GmshClient *getGmshClient(){ return _gmshClient; }
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 string &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.
Please register or to comment