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

replaced poll() with direct call to select(). This should help in getting
the solver interface eventually work on Windows without cygwin
parent 83522783
Branches
Tags
No related merge requests found
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
// Christopher Stott // Christopher Stott
void SystemCall(char *str); 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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -42,13 +42,12 @@ int WaitForData(int socket, int num, int pollint, double waitint); ...@@ -42,13 +42,12 @@ int WaitForData(int socket, int num, int pollint, double waitint);
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/poll.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h>
#include <netinet/in.h> #include <netinet/in.h>
#else // pure windows #else // pure windows
...@@ -57,6 +56,17 @@ int WaitForData(int socket, int num, int pollint, double waitint); ...@@ -57,6 +56,17 @@ int WaitForData(int socket, int num, int pollint, double waitint);
#endif #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 { class GmshServer {
public: public:
// This should match what's in GmshClient.h // This should match what's in GmshClient.h
...@@ -146,7 +156,7 @@ class GmshServer { ...@@ -146,7 +156,7 @@ class GmshServer {
#if !defined(WIN32) || defined(__CYGWIN__) #if !defined(WIN32) || defined(__CYGWIN__)
unlink(_sockname); unlink(_sockname);
#endif #endif
// make the socket // make the socket
s = socket(PF_UNIX, SOCK_STREAM, 0); s = socket(PF_UNIX, SOCK_STREAM, 0);
if(s < 0) if(s < 0)
...@@ -193,20 +203,14 @@ class GmshServer { ...@@ -193,20 +203,14 @@ class GmshServer {
return -3; // Error: Socket listen failed return -3; // Error: Socket listen failed
if(justwait){ if(justwait){
// wait indefinitely until we get data, polling every 10 ms // wait indefinitely until we get data
if(WaitForData(s, -1, 10, 1.)) if(WaitForData(s, -1, 0.5))
return -6; // not an actual error: we just stopped listening return -6; // not an actual error: we just stopped listening
} }
else{ else{
// Wait at most _maxdelay seconds for data, issue error if no // Wait at most _maxdelay seconds for data, issue error if no
// connection in that amount of time // connection in that amount of time
struct timeval tv; if(!myselect(s, _maxdelay))
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))
return -4; // Error: Socket listening timeout return -4; // Error: Socket listening timeout
} }
...@@ -216,18 +220,6 @@ class GmshServer { ...@@ -216,18 +220,6 @@ class GmshServer {
return _sock; 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) int ReceiveMessageHeader(int *type, int *len)
{ {
_ReceiveData(type, sizeof(int)); _ReceiveData(type, sizeof(int));
......
// $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 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
// //
...@@ -21,18 +21,7 @@ ...@@ -21,18 +21,7 @@
#include "Gmsh.h" #include "Gmsh.h"
#include "Solvers.h" #include "Solvers.h"
SolverInfo SINFO[MAXSOLVERS];
#if !defined(WIN32) || defined(__CYGWIN__)
#include "GmshServer.h" #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 "OpenFile.h"
#include "GmshUI.h" #include "GmshUI.h"
#include "GUI.h" #include "GUI.h"
...@@ -43,40 +32,42 @@ int GmshServer::s; ...@@ -43,40 +32,42 @@ int GmshServer::s;
extern Context_T CTX; extern Context_T CTX;
extern GUI *WID; extern GUI *WID;
// This routine polls the socket file descriptor every pollint SolverInfo SINFO[MAXSOLVERS];
// 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.)
// 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) // 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
struct pollfd pfd; // process was killed. Otherwise it just tends to current GUI events
pfd.fd = socket; // (this is easier to manage than non-blocking IO, and simpler than
pfd.events = POLLIN; // 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){ while(1){
if( (num >= 0 && SINFO[num].pid < 0) || // process has been killed if((num >= 0 && SINFO[num].pid < 0) || (num < 0 && !CTX.solver.listen)){
(num < 0 && !CTX.solver.listen) ) // we stopped listening // process has been killed or we stopped listening
return 1; return 1;
}
int ret = poll(&pfd, 1, pollint);
// check if there is data (call select with a zero timeout to
if(ret == 0){ // nothing available // return immediately, i.e., do polling)
// use wait() with a delay instead of check() to reduce CPU int ret = myselect(socket, 0);
// usage
if(ret == 0){
// nothing available: wait at most waitint seconds
WID->wait(waitint); WID->wait(waitint);
//WID->check();
} }
else if(ret > 0){ // data is there else if(ret > 0){
// data is there
return 0; return 0;
} }
else{ // error else{
// an error happened
if(num >= 0) if(num >= 0)
SINFO[num].pid = -1; SINFO[num].pid = -1;
return 1; return 1;
...@@ -181,7 +172,7 @@ int Solver(int num, char *args) ...@@ -181,7 +172,7 @@ int Solver(int num, char *args)
if(stop || (num >= 0 && SINFO[num].pid < 0)) if(stop || (num >= 0 && SINFO[num].pid < 0))
break; break;
stop = WaitForData(sock, num, 10, 0.1); stop = WaitForData(sock, num, 0.1);
if(stop || (num >= 0 && SINFO[num].pid < 0)) if(stop || (num >= 0 && SINFO[num].pid < 0))
break; break;
...@@ -290,13 +281,3 @@ int Solver(int num, char *args) ...@@ -290,13 +281,3 @@ int Solver(int num, char *args)
return 1; return 1;
} }
#else // pure windows
int Solver(int num, char *args)
{
Msg(GERROR, "Solver interface not available on Windows without Cygwin");
return 1;
}
#endif
...@@ -31,6 +31,7 @@ class GmshInteractiveClient{ ...@@ -31,6 +31,7 @@ class GmshInteractiveClient{
add_history("Point(1) = {0,0,0,lc};"); add_history("Point(1) = {0,0,0,lc};");
add_history("Point(2) = {5,0,0,lc};"); add_history("Point(2) = {5,0,0,lc};");
add_history("Line(1) = {1,2};"); add_history("Line(1) = {1,2};");
add_history("argh");
while (1) { while (1) {
// read input char until CR, LF, EOF, ^D // read input char until CR, LF, EOF, ^D
...@@ -50,6 +51,22 @@ class GmshInteractiveClient{ ...@@ -50,6 +51,22 @@ class GmshInteractiveClient{
// direct system calls // direct system calls
system("ls -al"); 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{ else{
// pass any other command to gmsh // pass any other command to gmsh
_client.ParseString(ptr); _client.ParseString(ptr);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment