From 30aa937aa227e0cb5d3d63d2827df0aaa4006432 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Fri, 14 Jan 2005 01:40:49 +0000 Subject: [PATCH] small modification to make the solver interface not block the GUI when the solver runs without printing messages --- Fltk/Solvers.cpp | 120 ++++++++++++++++++++++++++++++----------------- doc/VERSIONS | 6 ++- 2 files changed, 80 insertions(+), 46 deletions(-) diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp index c2d97b19f2..22fd93f046 100644 --- a/Fltk/Solvers.cpp +++ b/Fltk/Solvers.cpp @@ -1,4 +1,4 @@ -// $Id: Solvers.cpp,v 1.32 2005-01-13 23:39:10 geuzaine Exp $ +// $Id: Solvers.cpp,v 1.33 2005-01-14 01:40:49 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -40,6 +40,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> +#include <sys/poll.h> #include <sys/un.h> #include <unistd.h> @@ -118,56 +119,87 @@ int Solver(int num, char *args) SINFO[num].nbval[i] = 0; SINFO[num].pid = 0; + struct pollfd pfd; + pfd.fd = sock; + pfd.events = POLLIN|POLLPRI; + while(1) { - if(SINFO[num].pid < 0) - break; - Gmsh_ReceiveString(sock, &type, str); - switch (type) { - case GMSH_CLIENT_START: - SINFO[num].pid = atoi(str); - break; - case GMSH_CLIENT_STOP: - SINFO[num].pid = -1; - stop = 1; - break; - case GMSH_CLIENT_PROGRESS: - Msg(STATUS3N, "%s %s", SINFO[num].name, str); - break; - case GMSH_CLIENT_OPTION_1: - case GMSH_CLIENT_OPTION_2: - case GMSH_CLIENT_OPTION_3: - case GMSH_CLIENT_OPTION_4: - case GMSH_CLIENT_OPTION_5: - i = type - GMSH_CLIENT_OPTION; - strcpy(SINFO[num].option[i][SINFO[num].nbval[i]++], str); - break; - case GMSH_CLIENT_VIEW: - if(SINFO[num].merge_views) { - n = List_Nbr(CTX.post.list); - MergeProblem(str); - Draw(); - if(n != List_Nbr(CTX.post.list)) - WID->set_context(menu_post, 0); + // poll the socket file descriptor every 10 milliseconds until + // data is avalable; when nothing is available, just tend to + // pending GUI events. (This is much easier to manage than + // non-blocking IO. The real solution is of course to use threads, + // but that's still a bit of a nightmare to maintain in a portable + // way on all the platforms.) + while(1){ + if(SINFO[num].pid < 0){ // process has been killed + stop = 1; + break; } + int ret = poll(&pfd, 1, 10); + if(ret == 0){ // nothing available + WID->check(); + } + else if(ret > 0){ // data is there + break; + } + else{ // error + stop = 1; + break; + } + } + + if(stop) break; - case GMSH_CLIENT_INFO: - Msg(SOLVER, "%-8.8s: %s", SINFO[num].name, str); - break; - case GMSH_CLIENT_WARNING: - case GMSH_CLIENT_ERROR: - Msg(SOLVERR, "%-8.8s: %s", SINFO[num].name, str); - break; - default: - Msg(WARNING, "Unknown type of message received from %s", - SINFO[num].name); - Msg(SOLVER, "%-8.8s: %s", SINFO[num].name, str); - break; + + if(Gmsh_ReceiveString(sock, &type, str)){ + switch (type) { + case GMSH_CLIENT_START: + SINFO[num].pid = atoi(str); + break; + case GMSH_CLIENT_STOP: + SINFO[num].pid = -1; + stop = 1; + break; + case GMSH_CLIENT_PROGRESS: + Msg(STATUS3N, "%s %s", SINFO[num].name, str); + break; + case GMSH_CLIENT_OPTION_1: + case GMSH_CLIENT_OPTION_2: + case GMSH_CLIENT_OPTION_3: + case GMSH_CLIENT_OPTION_4: + case GMSH_CLIENT_OPTION_5: + i = type - GMSH_CLIENT_OPTION; + strcpy(SINFO[num].option[i][SINFO[num].nbval[i]++], str); + break; + case GMSH_CLIENT_VIEW: + if(SINFO[num].merge_views) { + n = List_Nbr(CTX.post.list); + MergeProblem(str); + Draw(); + if(n != List_Nbr(CTX.post.list)) + WID->set_context(menu_post, 0); + } + break; + case GMSH_CLIENT_INFO: + Msg(SOLVER, "%-8.8s: %s", SINFO[num].name, str); + break; + case GMSH_CLIENT_WARNING: + case GMSH_CLIENT_ERROR: + Msg(SOLVERR, "%-8.8s: %s", SINFO[num].name, str); + break; + default: + Msg(WARNING, "Unknown type of message received from %s", + SINFO[num].name); + Msg(SOLVER, "%-8.8s: %s", SINFO[num].name, str); + break; + } + WID->check(); } - WID->check(); // update the GUI + if(stop) break; } - + for(i = 0; i < SINFO[num].nboptions; i++) { if(SINFO[num].nbval[i]) { WID->solver[num].choice[i]->clear(); diff --git a/doc/VERSIONS b/doc/VERSIONS index 1942c8cc2d..6877b998c9 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,4 +1,4 @@ -$Id: VERSIONS,v 1.301 2005-01-13 05:45:45 geuzaine Exp $ +$Id: VERSIONS,v 1.302 2005-01-14 01:40:49 geuzaine Exp $ New since 1.58: added support for discrete (triangulated) surfaces, either in STL format or with the new "Discrete Surface" command; added @@ -9,7 +9,9 @@ view data (based on the same or on a different mesh); generalized Plugin(CutGrid); new plugins (Eigenvalues, Gradient, Curl, Divergence); changed default colormap to match Matlab's "Jet" colormap; new transformation matrix option for views (for -non-destructive rotations, symmetries, etc.); fixed small bugs. +non-destructive rotations, symmetries, etc.); improved solver +interface to keep the GUI responsive during solver calls; the fixed +small bugs. New in 1.58: fixed UNIX socket interface on Windows (broken by the TCP solver patch in 1.57); bumped version number of default -- GitLab