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

made client startup non blocking + prepare SINFO refactoring
parent 5772f317
Branches
Tags
No related merge requests found
...@@ -17,6 +17,7 @@ int GmshDaemon(std::string socket) ...@@ -17,6 +17,7 @@ int GmshDaemon(std::string socket)
return 1; return 1;
} }
client.Start(); client.Start();
client.Info("Server sucessfully started. Listening...");
// read large data file, // read large data file,
// initialize mpi job, // initialize mpi job,
......
...@@ -125,17 +125,18 @@ class GmshSocket{ ...@@ -125,17 +125,18 @@ class GmshSocket{
// seconds and microseconds == 0 we check for available data and // seconds and microseconds == 0 we check for available data and
// return immediately, i.e., we do polling). Returns 0 when data is // return immediately, i.e., we do polling). Returns 0 when data is
// available. // available.
int Select(int socket, int seconds, int microseconds) int Select(int seconds, int microseconds, int socket=-1)
{ {
int s = (socket < 0) ? _sock : socket;
struct timeval tv; struct timeval tv;
tv.tv_sec = seconds; tv.tv_sec = seconds;
tv.tv_usec = microseconds; tv.tv_usec = microseconds;
fd_set rfds; fd_set rfds;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(socket, &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... hence the +1 below // minus 1... hence the +1 below
return select(socket + 1, &rfds, NULL, NULL, &tv); return select(s + 1, &rfds, NULL, NULL, &tv);
} }
void SendString(int type, const char *str) void SendString(int type, const char *str)
{ {
...@@ -146,6 +147,19 @@ class GmshSocket{ ...@@ -146,6 +147,19 @@ class GmshSocket{
// send body // send body
_SendData(str, len); _SendData(str, len);
} }
void Info(const char *str){ SendString(INFO, str); }
void Warning(const char *str){ SendString(WARNING, str); }
void Error(const char *str){ SendString(ERROR, str); }
void Progress(const char *str){ SendString(PROGRESS, str); }
void MergeFile(const char *str){ SendString(MERGE_FILE, str); }
void ParseString(const char *str){ SendString(PARSE_STRING, str); }
void SpeedTest(const char *str){ SendString(SPEED_TEST, str); }
void Option(int num, const char *str)
{
if(num < 1) num = 1;
if(num > 5) num = 5;
SendString(OPTION_1 + num - 1, str);
}
int ReceiveHeader(int *type, int *len) int ReceiveHeader(int *type, int *len)
{ {
bool swap = false; bool swap = false;
...@@ -201,8 +215,7 @@ class GmshClient : public GmshSocket { ...@@ -201,8 +215,7 @@ class GmshClient : public GmshSocket {
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
// UNIX socket (testing ":" is not enough with Windows paths) // UNIX socket (testing ":" is not enough with Windows paths)
_sock = socket(PF_UNIX, SOCK_STREAM, 0); _sock = socket(PF_UNIX, SOCK_STREAM, 0);
if(_sock < 0) if(_sock < 0) return -1;
return -1; // Error: Couldn't create socket
// try to connect socket to given name // try to connect socket to given name
struct sockaddr_un addr_un; struct sockaddr_un addr_un;
memset((char *) &addr_un, 0, sizeof(addr_un)); memset((char *) &addr_un, 0, sizeof(addr_un));
...@@ -220,8 +233,7 @@ class GmshClient : public GmshSocket { ...@@ -220,8 +233,7 @@ class GmshClient : public GmshSocket {
else{ else{
// TCP/IP socket // TCP/IP socket
_sock = socket(AF_INET, SOCK_STREAM, 0); _sock = socket(AF_INET, SOCK_STREAM, 0);
if(_sock < 0) if(_sock < 0) return -1;
return -1; // Error: Couldn't create socket
// try to connect socket to host:port // try to connect socket to host:port
const char *port = strstr(sockname, ":"); const char *port = strstr(sockname, ":");
int portno = atoi(port + 1); int portno = atoi(port + 1);
...@@ -233,7 +245,7 @@ class GmshClient : public GmshSocket { ...@@ -233,7 +245,7 @@ class GmshClient : public GmshSocket {
struct hostent *server; struct hostent *server;
if(!(server = gethostbyname(remote))){ if(!(server = gethostbyname(remote))){
CloseSocket(_sock); CloseSocket(_sock);
return -3; // Error: No such host return -3; // no such host
} }
struct sockaddr_in addr_in; struct sockaddr_in addr_in;
memset((char *) &addr_in, 0, sizeof(addr_in)); memset((char *) &addr_in, 0, sizeof(addr_in));
...@@ -247,11 +259,7 @@ class GmshClient : public GmshSocket { ...@@ -247,11 +259,7 @@ class GmshClient : public GmshSocket {
} }
} }
CloseSocket(_sock); CloseSocket(_sock);
return -2; // Error: Couldn't connect return -2; // couldn't connect
}
int Select(int seconds, int microseconds)
{
return GmshSocket::Select(_sock, seconds, microseconds);
} }
void Start() void Start()
{ {
...@@ -264,19 +272,6 @@ class GmshClient : public GmshSocket { ...@@ -264,19 +272,6 @@ class GmshClient : public GmshSocket {
SendString(START, tmp); SendString(START, tmp);
} }
void Stop(){ SendString(STOP, "Goodbye!"); } void Stop(){ SendString(STOP, "Goodbye!"); }
void Info(const char *str){ SendString(INFO, str); }
void Warning(const char *str){ SendString(WARNING, str); }
void Error(const char *str){ SendString(ERROR, str); }
void Progress(const char *str){ SendString(PROGRESS, str); }
void MergeFile(const char *str){ SendString(MERGE_FILE, str); }
void ParseString(const char *str){ SendString(PARSE_STRING, str); }
void SpeedTest(const char *str){ SendString(SPEED_TEST, str); }
void Option(int num, const char *str)
{
if(num < 1) num = 1;
if(num > 5) num = 5;
SendString(OPTION_1 + num - 1, str);
}
void Disconnect(){ CloseSocket(_sock); } void Disconnect(){ CloseSocket(_sock); }
}; };
...@@ -287,10 +282,9 @@ class GmshServer : public GmshSocket{ ...@@ -287,10 +282,9 @@ class GmshServer : public GmshSocket{
GmshServer() : GmshSocket(), _portno(-1) {} GmshServer() : GmshSocket(), _portno(-1) {}
virtual ~GmshServer(){} virtual ~GmshServer(){}
virtual int SystemCall(const char *str) = 0; virtual int SystemCall(const char *str) = 0;
virtual int NonBlockingWait(int socket, int num, double waitint) = 0; virtual int NonBlockingWait(int socket, int num, double waitint, double timeout) = 0;
int StartClient(const char *command, const char *sockname=0, int timeout=5) int Start(int num, const char *command, const char *sockname, double timeout)
{ {
bool justwait = (!command || !strlen(command));
_sockname = sockname; _sockname = sockname;
// no socket? launch the command directly // no socket? launch the command directly
...@@ -308,8 +302,7 @@ class GmshServer : public GmshSocket{ ...@@ -308,8 +302,7 @@ class GmshServer : public GmshSocket{
unlink(_sockname); unlink(_sockname);
// create a socket // create a socket
tmpsock = socket(PF_UNIX, SOCK_STREAM, 0); tmpsock = socket(PF_UNIX, SOCK_STREAM, 0);
if(tmpsock < 0) if(tmpsock < 0) throw "Couldn't create socket";
return -1; // Error: Couldn't create socket
// bind the socket to its name // bind the socket to its name
struct sockaddr_un addr_un; struct sockaddr_un addr_un;
memset((char *) &addr_un, 0, sizeof(addr_un)); memset((char *) &addr_un, 0, sizeof(addr_un));
...@@ -317,12 +310,12 @@ class GmshServer : public GmshSocket{ ...@@ -317,12 +310,12 @@ class GmshServer : public GmshSocket{
addr_un.sun_family = AF_UNIX; addr_un.sun_family = AF_UNIX;
if(bind(tmpsock, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0){ if(bind(tmpsock, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0){
CloseSocket(tmpsock); CloseSocket(tmpsock);
return -2; // Error: Couldn't bind socket to name throw "Couldn't bind socket to name";
} }
// change permissions on the socket name in case it has to be rm'd later // change permissions on the socket name in case it has to be rm'd later
chmod(_sockname, 0666); chmod(_sockname, 0666);
#else #else
return -7; // Unix sockets not available on Windows throw "Unix sockets not available on Windows";
#endif #endif
} }
else{ else{
...@@ -336,7 +329,7 @@ class GmshServer : public GmshSocket{ ...@@ -336,7 +329,7 @@ class GmshServer : public GmshSocket{
#else #else
if(tmpsock == INVALID_SOCKET) if(tmpsock == INVALID_SOCKET)
#endif #endif
return -1; // Error: Couldn't create socket throw "Couldn't create socket";
// bind the socket to its name // bind the socket to its name
struct sockaddr_in addr_in; struct sockaddr_in addr_in;
memset((char *) &addr_in, 0, sizeof(addr_in)); memset((char *) &addr_in, 0, sizeof(addr_in));
...@@ -345,33 +338,33 @@ class GmshServer : public GmshSocket{ ...@@ -345,33 +338,33 @@ class GmshServer : public GmshSocket{
addr_in.sin_port = htons(_portno); addr_in.sin_port = htons(_portno);
if(bind(tmpsock, (struct sockaddr *)&addr_in, sizeof(addr_in)) < 0){ if(bind(tmpsock, (struct sockaddr *)&addr_in, sizeof(addr_in)) < 0){
CloseSocket(tmpsock); CloseSocket(tmpsock);
return -2; // Error: Couldn't bind socket to name throw "Couldn't bind socket to name";
} }
} }
if(!justwait) 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
}
// listen on socket (queue up to 20 connections before having // listen on socket (queue up to 20 connections before having
// them automatically rejected) // them automatically rejected)
if(listen(tmpsock, 20)){ if(listen(tmpsock, 20)){
CloseSocket(tmpsock); CloseSocket(tmpsock);
return -3; // Error: Socket listen failed throw "Socket listen failed";
} }
if(justwait){ // wait until we get data
// wait indefinitely until we get data int ret = NonBlockingWait(tmpsock, num, 0.5, timeout);
if(NonBlockingWait(tmpsock, -1, 0.5)){ if(ret){
CloseSocket(tmpsock); CloseSocket(tmpsock);
return -6; // not an actual error: we just stopped listening if(ret == 2){
} throw "Socket listening timeout";
} }
else{ else{
// Wait at most timeout seconds for data, issue error if no return -1; // stopped listening
// connection in that amount of time
if(!Select(tmpsock, timeout, 0)){
CloseSocket(tmpsock);
return -4; // Error: Socket listening timeout
} }
} }
...@@ -381,8 +374,6 @@ class GmshServer : public GmshSocket{ ...@@ -381,8 +374,6 @@ class GmshServer : public GmshSocket{
struct sockaddr_un from_un; struct sockaddr_un from_un;
socklen_t len = sizeof(from_un); socklen_t len = sizeof(from_un);
_sock = accept(tmpsock, (struct sockaddr *)&from_un, &len); _sock = accept(tmpsock, (struct sockaddr *)&from_un, &len);
#else
_sock = -7; // Unix sockets not available on Windows
#endif #endif
} }
else{ else{
...@@ -393,7 +384,7 @@ class GmshServer : public GmshSocket{ ...@@ -393,7 +384,7 @@ class GmshServer : public GmshSocket{
CloseSocket(tmpsock); CloseSocket(tmpsock);
if(_sock < 0) if(_sock < 0)
return -5; // Error: Socket accept failed throw "Socket accept failed";
return _sock; return _sock;
} }
int Shutdown() int Shutdown()
......
...@@ -62,14 +62,14 @@ std::string SanitizeTeXString(const char *in, int equation) ...@@ -62,14 +62,14 @@ std::string SanitizeTeXString(const char *in, int equation)
return out; return out;
} }
std::string FixWindowsPath(const char *in) std::string FixWindowsPath(std::string in)
{ {
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
char tmp[1024]; char tmp[1024];
cygwin_conv_to_win32_path(in, tmp); cygwin_conv_to_win32_path(in.c_str(), tmp);
return std::string(tmp); return std::string(tmp);
#else #else
return std::string(in); return in;
#endif #endif
} }
...@@ -115,6 +115,21 @@ std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len) ...@@ -115,6 +115,21 @@ std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len)
return out; return out;
} }
std::string ReplacePercentS(std::string in, std::string val)
{
std::string out;
for(unsigned int i = 0; i < in.size(); i++){
if(in[i] == '%' && i + 1 < in.size() && in[i + 1] == 's'){
out += val;
i++;
}
else{
out += in[i];
}
}
return out;
}
void ReplaceMultiFormat(const char *in, const char *val, char *out) void ReplaceMultiFormat(const char *in, const char *val, char *out)
{ {
unsigned int i = 0, j = 0; unsigned int i = 0, j = 0;
......
...@@ -13,10 +13,11 @@ ...@@ -13,10 +13,11 @@
void SwapBytes(char *array, int size, int n); void SwapBytes(char *array, int size, int n);
std::string ExtractDoubleQuotedString(const char *str, int len); std::string ExtractDoubleQuotedString(const char *str, int len);
std::string SanitizeTeXString(const char *in, int equation); std::string SanitizeTeXString(const char *in, int equation);
std::string FixWindowsPath(const char *in); std::string FixWindowsPath(std::string in);
std::string FixRelativePath(std::string reference, std::string in); std::string FixRelativePath(std::string reference, std::string in);
std::vector<std::string> SplitFileName(std::string fileName); std::vector<std::string> SplitFileName(std::string fileName);
std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len); std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len);
std::string ReplacePercentS(std::string in, std::string val);
void ReplaceMultiFormat(const char *in, const char *val, char *out); void ReplaceMultiFormat(const char *in, const char *val, char *out);
#endif #endif
...@@ -26,23 +26,30 @@ class myGmshServer : public GmshServer{ ...@@ -26,23 +26,30 @@ class myGmshServer : public GmshServer{
myGmshServer() : GmshServer() {} myGmshServer() : GmshServer() {}
~myGmshServer() {} ~myGmshServer() {}
int SystemCall(const char *str){ return ::SystemCall(str); } int SystemCall(const char *str){ return ::SystemCall(str); }
int NonBlockingWait(int socket, int num, double waitint) int NonBlockingWait(int socket, int num, double waitint, double timeout)
{ {
// This routine polls the socket at least every 'waitint' seconds and // This routine polls the socket at least every 'waitint' seconds,
// returns 0 if data is available or 1 if there was en error or if the // and for at most timout seconds (or indefinitely if
// process was killed. Otherwise it just tends to current GUI events // timeout==0). The routine returns 0 as soon as data is available
// (this is easier to manage than non-blocking IO, and simpler than // and 1 if there was en error or if the process was
// using the "real" solution, i.e., threads. Another possibility would // killed. Otherwise it just tends to current GUI events (this is
// easier to manage than non-blocking IO, and simpler than using
// the "real" solution, i.e., threads. Another possibility would
// be to use Fl::add_fd()) // be to use Fl::add_fd())
double start = GetTimeInSeconds();
while(1){ while(1){
if((num >= 0 && SINFO[num].pid < 0) || (num < 0 && !CTX::instance()->solver.listen)){ if(timeout > 0 && GetTimeInSeconds() - start > timeout) {
// process has been killed or we stopped listening return 2; // timout
return 1; }
if((num >= 0 && SINFO[num].pid < 0) ||
(num < 0 && !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 // check if there is data (call select with a zero timeout to
// return immediately, i.e., do polling) // return immediately, i.e., do polling)
int ret = Select(socket, 0, 0); int ret = Select(0, 0, socket);
if(ret == 0){ if(ret == 0){
// nothing available: wait at most waitint seconds, and in the // nothing available: wait at most waitint seconds, and in the
...@@ -50,8 +57,7 @@ class myGmshServer : public GmshServer{ ...@@ -50,8 +57,7 @@ class myGmshServer : public GmshServer{
FlGui::instance()->wait(waitint); FlGui::instance()->wait(waitint);
} }
else if(ret > 0){ else if(ret > 0){
// data is there return 0; // data is there!
return 0;
} }
else{ else{
// an error happened // an error happened
...@@ -73,7 +79,7 @@ std::string GetSocketName(int num) ...@@ -73,7 +79,7 @@ std::string GetSocketName(int num)
std::ostringstream tmp; std::ostringstream tmp;
tmp << CTX::instance()->homeDir << CTX::instance()->solver.socketName; tmp << CTX::instance()->homeDir << CTX::instance()->solver.socketName;
if(num >= 0) tmp << "-" << num; if(num >= 0) tmp << "-" << num;
sockname = FixWindowsPath(tmp.str().c_str()); sockname = FixWindowsPath(tmp.str());
} }
else{ else{
// TCP/IP socket // TCP/IP socket
...@@ -97,19 +103,21 @@ int Solver(int num, const char *args) ...@@ -97,19 +103,21 @@ int Solver(int num, const char *args)
GmshServer *server = new myGmshServer; GmshServer *server = new myGmshServer;
if(num >= 0){ if(num >= 0){
prog = FixWindowsPath(SINFO[num].executable_name.c_str()); prog = FixWindowsPath(SINFO[num].executable_name);
if(!SINFO[num].client_server) { if(!SINFO[num].client_server) {
command = prog + " " + args; command = prog + " " + args;
#if !defined(WIN32) #if !defined(WIN32)
command += " &"; command += " &";
#endif #endif
server->StartClient(command.c_str()); server->Start(num, command.c_str(), 0, 0.);
delete server;
return 1; return 1;
} }
} }
else{ else{
if(!CTX::instance()->solver.listen){ if(!CTX::instance()->solver.listen){
Msg::Info("Stopped listening for solver connections"); Msg::Info("Stopped listening for solver connections");
delete server;
return 0; return 0;
} }
// we don't know who will (maybe) contact us // we don't know who will (maybe) contact us
...@@ -128,51 +136,31 @@ int Solver(int num, const char *args) ...@@ -128,51 +136,31 @@ int Solver(int num, const char *args)
#endif #endif
} }
int sock = server->StartClient(command.c_str(), sockname.c_str()); if(num >= 0){
SINFO[num].pid = 0;
SINFO[num].server = 0;
}
bool initOption[5] = {true, true, true, true, true};
if(sock < 0) { int sock;
switch (sock) { try{
case -1: sock = server->Start(num, command.c_str(), sockname.c_str(), 5.);
Msg::Error("Couldn't create socket '%s'", sockname.c_str());
break;
case -2:
Msg::Error("Couldn't bind socket to name '%s'", sockname.c_str());
break;
case -3:
Msg::Error("Socket listen failed on '%s'", sockname.c_str());
break;
case -4:
Msg::Error("Socket listen timeout on '%s'", sockname.c_str());
Msg::Error("Is '%s' correctly installed?", prog.c_str());
break;
case -5:
Msg::Error("Socket accept failed on '%s'", sockname.c_str());
break;
case -6:
Msg::Info("Stopped listening for solver connections");
server->Shutdown();
break;
case -7:
Msg::Error("Unix sockets not available on Windows without Cygwin");
Msg::Error("Use TCP/IP sockets instead");
break;
case -8:
Msg::Error("Could not initialize Windows sockets");
break;
} }
catch(const char *err){
Msg::Error("%s (on socket '%s')", err, sockname.c_str());
sock = -1;
}
if(sock < 0){
if(num >= 0){ if(num >= 0){
for(int i = 0; i < SINFO[num].nboptions; i++) for(int i = 0; i < SINFO[num].nboptions; i++)
FlGui::instance()->solver[num]->choice[i]->clear(); FlGui::instance()->solver[num]->choice[i]->clear();
} }
server->Shutdown();
delete server;
return 0; return 0;
} }
if(num >= 0){
SINFO[num].pid = 0;
SINFO[num].server = 0;
}
bool initOption[5] = {true, true, true, true, true};
Msg::StatusBar(2, false, "Running '%s'", prog.c_str()); Msg::StatusBar(2, false, "Running '%s'", prog.c_str());
while(1) { while(1) {
...@@ -182,7 +170,7 @@ int Solver(int num, const char *args) ...@@ -182,7 +170,7 @@ int Solver(int num, const char *args)
if(stop || (num >= 0 && SINFO[num].pid < 0)) if(stop || (num >= 0 && SINFO[num].pid < 0))
break; break;
stop = server->NonBlockingWait(sock, num, 0.1); stop = server->NonBlockingWait(sock, num, 0.1, 0.);
if(stop || (num >= 0 && SINFO[num].pid < 0)) if(stop || (num >= 0 && SINFO[num].pid < 0))
break; break;
...@@ -312,16 +300,19 @@ int Solver(int num, const char *args) ...@@ -312,16 +300,19 @@ int Solver(int num, const char *args)
FlGui::instance()->solver[num]->choice[i]->value(0); FlGui::instance()->solver[num]->choice[i]->value(0);
} }
} }
// only necessary in case of error
SINFO[num].server = 0;
} }
server->Shutdown(); server->Shutdown();
delete server;
if(num >= 0){ if(num >= 0){
Msg::StatusBar(2, false, ""); Msg::StatusBar(2, false, "");
} }
else{ else{
Msg::Info("Client disconnected: starting new connection"); Msg::Info("Client disconnected: starting new connection");
delete server;
goto new_connection; goto new_connection;
} }
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
static void help_license_cb(Fl_Widget *w, void *data) static void help_license_cb(Fl_Widget *w, void *data)
{ {
std::string prog = FixWindowsPath(CTX::instance()->webBrowser.c_str()); std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
char cmd[1024]; char cmd[1024];
ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/LICENSE.txt", cmd); ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/LICENSE.txt", cmd);
SystemCall(cmd); SystemCall(cmd);
...@@ -25,7 +25,7 @@ static void help_license_cb(Fl_Widget *w, void *data) ...@@ -25,7 +25,7 @@ static void help_license_cb(Fl_Widget *w, void *data)
static void help_credits_cb(Fl_Widget *w, void *data) static void help_credits_cb(Fl_Widget *w, void *data)
{ {
std::string prog = FixWindowsPath(CTX::instance()->webBrowser.c_str()); std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
char cmd[1024]; char cmd[1024];
ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/CREDITS.txt", cmd); ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/CREDITS.txt", cmd);
SystemCall(cmd); SystemCall(cmd);
......
...@@ -150,13 +150,13 @@ static void file_remote_cb(Fl_Widget *w, void *data) ...@@ -150,13 +150,13 @@ static void file_remote_cb(Fl_Widget *w, void *data)
{ {
std::string str((const char*)data); std::string str((const char*)data);
if(str == "connect"){ if(str == "start"){
Msg::Info("Starting remote Gmsh"); Msg::Info("Starting remote Gmsh server");
if(SINFO[MAX_NUM_SOLVERS].server){ if(SINFO[MAX_NUM_SOLVERS].server){
Msg::Info("A server is already running, trying to stop it first"); Msg::Error("A server is already running");
SINFO[MAX_NUM_SOLVERS].server->SendString(GmshSocket::STOP, "DISCONNECTING!");
} }
SINFO[MAX_NUM_SOLVERS].name = "Gmsh Daemon"; else{
SINFO[MAX_NUM_SOLVERS].name = "Gmsh Server";
SINFO[MAX_NUM_SOLVERS].executable_name = "./gmsh"; SINFO[MAX_NUM_SOLVERS].executable_name = "./gmsh";
SINFO[MAX_NUM_SOLVERS].socket_command = "-socket %s"; SINFO[MAX_NUM_SOLVERS].socket_command = "-socket %s";
SINFO[MAX_NUM_SOLVERS].nboptions = 0; SINFO[MAX_NUM_SOLVERS].nboptions = 0;
...@@ -165,22 +165,23 @@ static void file_remote_cb(Fl_Widget *w, void *data) ...@@ -165,22 +165,23 @@ static void file_remote_cb(Fl_Widget *w, void *data)
SINFO[MAX_NUM_SOLVERS].merge_views = 1; SINFO[MAX_NUM_SOLVERS].merge_views = 1;
Solver(MAX_NUM_SOLVERS, ""); Solver(MAX_NUM_SOLVERS, "");
} }
else if(str == "disconnect"){ }
else if(str == "stop"){
if(SINFO[MAX_NUM_SOLVERS].server){ if(SINFO[MAX_NUM_SOLVERS].server){
Msg::Info("Stopping remote Gmsh"); Msg::Info("Stopping remote Gmsh server");
SINFO[MAX_NUM_SOLVERS].server->SendString(GmshSocket::STOP, "DISCONNECTING!"); SINFO[MAX_NUM_SOLVERS].server->SendString(GmshSocket::STOP, "DISCONNECTING!");
} }
else{ else{
Msg::Warning("Cannot disconnect remote Gmsh: server not running"); Msg::Error("Cannot stop remote Gmsh: server not running");
} }
} }
else if(str == "test"){ else if(str == "test"){
if(SINFO[MAX_NUM_SOLVERS].server){ if(SINFO[MAX_NUM_SOLVERS].server){
Msg::Info("Testing remote Gmsh daemon"); Msg::Info("Testing remote Gmsh server");
SINFO[MAX_NUM_SOLVERS].server->SendString(9999, "GENERATE A VIEW!"); SINFO[MAX_NUM_SOLVERS].server->SendString(9999, "GENERATE A VIEW!");
} }
else{ else{
Msg::Warning("Cannot test remote Gmsh: must be connected first!"); Msg::Error("Cannot test remote Gmsh: server not running");
} }
} }
} }
...@@ -520,7 +521,7 @@ static void help_command_line_cb(Fl_Widget *w, void *data) ...@@ -520,7 +521,7 @@ static void help_command_line_cb(Fl_Widget *w, void *data)
static void help_online_cb(Fl_Widget *w, void *data) static void help_online_cb(Fl_Widget *w, void *data)
{ {
std::string prog = FixWindowsPath(CTX::instance()->webBrowser.c_str()); std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
char cmd[1024]; char cmd[1024];
ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/texinfo/", cmd); ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/texinfo/", cmd);
SystemCall(cmd); SystemCall(cmd);
...@@ -573,8 +574,8 @@ static void geometry_physical_cb(Fl_Widget *w, void *data) ...@@ -573,8 +574,8 @@ static void geometry_physical_cb(Fl_Widget *w, void *data)
static void geometry_edit_cb(Fl_Widget *w, void *data) static void geometry_edit_cb(Fl_Widget *w, void *data)
{ {
std::string prog = FixWindowsPath(CTX::instance()->editor.c_str()); std::string prog = FixWindowsPath(CTX::instance()->editor);
std::string file = FixWindowsPath(GModel::current()->getFileName().c_str()); std::string file = FixWindowsPath(GModel::current()->getFileName());
char cmd[1024]; char cmd[1024];
ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd); ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd);
SystemCall(cmd); SystemCall(cmd);
...@@ -2237,10 +2238,10 @@ static Fl_Menu_Item sysbar_table[] = { ...@@ -2237,10 +2238,10 @@ static Fl_Menu_Item sysbar_table[] = {
{"Vertically", 0, (Fl_Callback *)file_window_cb, (void*)"split_v"}, {"Vertically", 0, (Fl_Callback *)file_window_cb, (void*)"split_v"},
{"Clear", 0, (Fl_Callback *)file_window_cb, (void*)"split_u"}, {"Clear", 0, (Fl_Callback *)file_window_cb, (void*)"split_u"},
{0}, {0},
#if 0 // test remote gmsh daemon #if 1 // test remote Gmsh server
{"Connect...", 0, (Fl_Callback *)file_remote_cb, (void*)"connect"}, {"Start server...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"},
{"Test remote!", 0, (Fl_Callback *)file_remote_cb, (void*)"test"}, {"Test server!", 0, (Fl_Callback *)file_remote_cb, (void*)"test"},
{"Disconnect", 0, (Fl_Callback *)file_remote_cb, (void*)"disconnect", FL_MENU_DIVIDER}, {"Stop server", 0, (Fl_Callback *)file_remote_cb, (void*)"stop", FL_MENU_DIVIDER},
#endif #endif
{"Rename...", FL_META+'r', (Fl_Callback *)file_rename_cb, 0}, {"Rename...", FL_META+'r', (Fl_Callback *)file_rename_cb, 0},
{"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0}, {"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0},
......
...@@ -50,7 +50,7 @@ void solver_cb(Fl_Widget *w, void *data) ...@@ -50,7 +50,7 @@ void solver_cb(Fl_Widget *w, void *data)
std::string inputFile(FlGui::instance()->solver[num]->input[0]->value()); std::string inputFile(FlGui::instance()->solver[num]->input[0]->value());
if(SINFO[num].nboptions && inputFile.size()) { if(SINFO[num].nboptions && inputFile.size()) {
std::string file = FixWindowsPath(inputFile.c_str()); std::string file = FixWindowsPath(inputFile);
char tmp[256], tmp2[256]; char tmp[256], tmp2[256];
sprintf(tmp, "\"%s\"", file.c_str()); sprintf(tmp, "\"%s\"", file.c_str());
sprintf(tmp2, SINFO[num].name_command.c_str(), tmp); sprintf(tmp2, SINFO[num].name_command.c_str(), tmp);
...@@ -70,7 +70,7 @@ static void solver_file_open_cb(Fl_Widget *w, void *data) ...@@ -70,7 +70,7 @@ static void solver_file_open_cb(Fl_Widget *w, void *data)
if(file_chooser(0, 0, "Choose", tmp)) { if(file_chooser(0, 0, "Choose", tmp)) {
FlGui::instance()->solver[num]->input[0]->value(file_chooser_get_name(1).c_str()); FlGui::instance()->solver[num]->input[0]->value(file_chooser_get_name(1).c_str());
if(SINFO[num].nboptions) { if(SINFO[num].nboptions) {
std::string file = FixWindowsPath(file_chooser_get_name(1).c_str()); std::string file = FixWindowsPath(file_chooser_get_name(1));
sprintf(tmp, "\"%s\"", file.c_str()); sprintf(tmp, "\"%s\"", file.c_str());
sprintf(tmp2, SINFO[num].name_command.c_str(), tmp); sprintf(tmp2, SINFO[num].name_command.c_str(), tmp);
sprintf(tmp, "%s %s", SINFO[num].option_command.c_str(), tmp2); sprintf(tmp, "%s %s", SINFO[num].option_command.c_str(), tmp2);
...@@ -82,7 +82,7 @@ static void solver_file_open_cb(Fl_Widget *w, void *data) ...@@ -82,7 +82,7 @@ static void solver_file_open_cb(Fl_Widget *w, void *data)
static void solver_file_edit_cb(Fl_Widget *w, void *data) static void solver_file_edit_cb(Fl_Widget *w, void *data)
{ {
int num = (int)(long)data; int num = (int)(long)data;
std::string prog = FixWindowsPath(CTX::instance()->editor.c_str()); std::string prog = FixWindowsPath(CTX::instance()->editor);
std::string file = FixWindowsPath(FlGui::instance()->solver[num]->input[0]->value()); std::string file = FixWindowsPath(FlGui::instance()->solver[num]->input[0]->value());
char cmd[1024]; char cmd[1024];
ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd); ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd);
...@@ -139,7 +139,6 @@ static void solver_command_cb(Fl_Widget *w, void *data) ...@@ -139,7 +139,6 @@ static void solver_command_cb(Fl_Widget *w, void *data)
sprintf(command, SINFO[num].button_command[idx].c_str(), sprintf(command, SINFO[num].button_command[idx].c_str(),
SINFO[num].option[usedopts][val].c_str()); SINFO[num].option[usedopts][val].c_str());
else{ else{
Msg::Warning("Invalid choice (%d) for option %d", val, usedopts);
strcpy(command, ""); strcpy(command, "");
} }
} }
......
...@@ -19,8 +19,8 @@ Build Gmsh using CMake's graphical user interface ...@@ -19,8 +19,8 @@ Build Gmsh using CMake's graphical user interface
------------------------------------------------- -------------------------------------------------
* Launch CMake and fill-in the two top input fields (telling where the * Launch CMake and fill-in the two top input fields (telling where the
Gmsh source is located and where you want the Gmsh binary to be Gmsh source directory is located and where you want the Gmsh binary
created). to be created).
* Click on "Add entry" and define the variable CMAKE_PREFIX_PATH, of * Click on "Add entry" and define the variable CMAKE_PREFIX_PATH, of
type "PATH", pointing to the location(s) of any external package(s) type "PATH", pointing to the location(s) of any external package(s)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment