diff --git a/Fltk/GmshServer.h b/Fltk/GmshServer.h index 8c2cac5874d8503800ecd19aceff8d499278227a..e60908ad4a077a6f7e322171f8e66efae75992c0 100644 --- a/Fltk/GmshServer.h +++ b/Fltk/GmshServer.h @@ -31,7 +31,7 @@ // Christopher Stott void SystemCall(char *str); -int WaitForData(int socket, int num, int pollint, double waitint); +int WaitForData(int socket, int num, double waitint); #include <stdio.h> #include <stdlib.h> @@ -42,13 +42,12 @@ int WaitForData(int socket, int num, int pollint, double waitint); #if !defined(WIN32) || defined(__CYGWIN__) +#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> -#include <sys/poll.h> #include <sys/un.h> #include <sys/time.h> -#include <unistd.h> #include <netinet/in.h> #else // pure windows @@ -57,6 +56,17 @@ int WaitForData(int socket, int num, int pollint, double waitint); #endif +int myselect(int socket, int seconds) +{ + struct timeval tv; + tv.tv_sec = seconds; + tv.tv_usec = 0; + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(socket, &rfds); + return select(socket + 1, &rfds, NULL, NULL, &tv); +} + class GmshServer { public: // This should match what's in GmshClient.h @@ -146,7 +156,7 @@ class GmshServer { #if !defined(WIN32) || defined(__CYGWIN__) unlink(_sockname); #endif - + // make the socket s = socket(PF_UNIX, SOCK_STREAM, 0); if(s < 0) @@ -193,20 +203,14 @@ class GmshServer { return -3; // Error: Socket listen failed if(justwait){ - // wait indefinitely until we get data, polling every 10 ms - if(WaitForData(s, -1, 10, 1.)) + // wait indefinitely until we get data + if(WaitForData(s, -1, 0.5)) return -6; // not an actual error: we just stopped listening } else{ // Wait at most _maxdelay seconds for data, issue error if no // connection in that amount of time - struct timeval tv; - tv.tv_sec = _maxdelay; - tv.tv_usec = 0; - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(s, &rfds); - if(!select(s + 1, &rfds, NULL, NULL, &tv)) + if(!myselect(s, _maxdelay)) return -4; // Error: Socket listening timeout } @@ -216,18 +220,6 @@ class GmshServer { return _sock; } - int ReceiveString(int *type, char str[]) - { - _ReceiveData(type, sizeof(int)); - int len; - if(_ReceiveData(&len, sizeof(int))) { - if(_ReceiveData(str, len) == len) { - str[len] = '\0'; - return 1; - } - } - return 0; - } int ReceiveMessageHeader(int *type, int *len) { _ReceiveData(type, sizeof(int)); diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp index 203ab336bbade4bdeaecf3f80e5a02562026e409..ceb09b8036e82dd0d36ef69379c4e94ebc254700 100644 --- a/Fltk/Solvers.cpp +++ b/Fltk/Solvers.cpp @@ -1,4 +1,4 @@ -// $Id: Solvers.cpp,v 1.46 2006-02-24 04:03:38 geuzaine Exp $ +// $Id: Solvers.cpp,v 1.47 2006-02-24 14:24:46 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -21,18 +21,7 @@ #include "Gmsh.h" #include "Solvers.h" - -SolverInfo SINFO[MAXSOLVERS]; - -#if !defined(WIN32) || defined(__CYGWIN__) - #include "GmshServer.h" - -// FIXME: this should be removed (and we should set the socket options -// so that the addresses can be reused) -int GmshServer::init = 0; -int GmshServer::s; - #include "OpenFile.h" #include "GmshUI.h" #include "GUI.h" @@ -43,40 +32,42 @@ int GmshServer::s; extern Context_T CTX; extern GUI *WID; -// This routine polls the socket file descriptor every pollint -// milliseconds until data is avalable; when nothing is available, we -// just tend to pending GUI events. The routine returns 0 if data is -// available and 1 if there was en error or if the process was killed. -// (This is much easier to manage than non-blocking IO. The real -// solution is of course to use threads, or to fork a new process for -// each new connection, but that's still a bit of a nightmare to -// maintain in a portable way on all the platforms.) +SolverInfo SINFO[MAXSOLVERS]; -// FIXME: we should reimplement this using Fl::add_fd() +// FIXME: this should be removed (and we should set the socket options +// so that the addresses can be reused) +int GmshServer::init = 0; +int GmshServer::s; -int WaitForData(int socket, int num, int pollint, double waitint) -{ - struct pollfd pfd; - pfd.fd = socket; - pfd.events = POLLIN; +// This routine polls the socket at least every 'waitint' seconds and +// returns 0 if data is available or 1 if there was en error or if the +// process was 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()) +int WaitForData(int socket, int num, double waitint) +{ while(1){ - if( (num >= 0 && SINFO[num].pid < 0) || // process has been killed - (num < 0 && !CTX.solver.listen) ) // we stopped listening + if((num >= 0 && SINFO[num].pid < 0) || (num < 0 && !CTX.solver.listen)){ + // process has been killed or we stopped listening return 1; - - int ret = poll(&pfd, 1, pollint); - - if(ret == 0){ // nothing available - // use wait() with a delay instead of check() to reduce CPU - // usage + } + + // check if there is data (call select with a zero timeout to + // return immediately, i.e., do polling) + int ret = myselect(socket, 0); + + if(ret == 0){ + // nothing available: wait at most waitint seconds WID->wait(waitint); - //WID->check(); } - else if(ret > 0){ // data is there + else if(ret > 0){ + // data is there return 0; } - else{ // error + else{ + // an error happened if(num >= 0) SINFO[num].pid = -1; return 1; @@ -181,7 +172,7 @@ int Solver(int num, char *args) if(stop || (num >= 0 && SINFO[num].pid < 0)) break; - stop = WaitForData(sock, num, 10, 0.1); + stop = WaitForData(sock, num, 0.1); if(stop || (num >= 0 && SINFO[num].pid < 0)) break; @@ -290,13 +281,3 @@ int Solver(int num, char *args) return 1; } - -#else // pure windows - -int Solver(int num, char *args) -{ - Msg(GERROR, "Solver interface not available on Windows without Cygwin"); - return 1; -} - -#endif diff --git a/utils/solvers/c++/interactive.cpp b/utils/solvers/c++/interactive.cpp index c98248cb516e3706a0c38ad1b1432a4a060707bb..c120a1636151f82de04e54e7c34b2dacbebb1d3e 100644 --- a/utils/solvers/c++/interactive.cpp +++ b/utils/solvers/c++/interactive.cpp @@ -31,6 +31,7 @@ class GmshInteractiveClient{ add_history("Point(1) = {0,0,0,lc};"); add_history("Point(2) = {5,0,0,lc};"); add_history("Line(1) = {1,2};"); + add_history("argh"); while (1) { // read input char until CR, LF, EOF, ^D @@ -50,6 +51,22 @@ class GmshInteractiveClient{ // direct system calls system("ls -al"); } + else if(!strcmp(ptr, "argh")){ + // test speed of string sending with a 1Mb view + char *dat = new char[1200000]; + strcpy(dat, "View \"test\" {\n"); + int n = strlen(dat); + for(int i = 0; i < 100; i++){ + for(int j = 0; j < 200; j++){ + n += sprintf(&dat[n], "SQ(%d,%d,0,%d,%d,0,%d,%d,0,%d,%d,0){%d,%d,%d,%d};\n", + i, j, i+1, j, i+1, j+1, i, j+1, i, i+1, j, j+1); + } + } + strcat(dat, "};"); + printf("n=%d\n", n); + _client.ParseString(dat); + delete [] dat; + } else{ // pass any other command to gmsh _client.ParseString(ptr);