diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index 464d09f70818202a07a135f8cbbb8cae22b8d20d..cb41c22026949e871501e6e6bdaa5fffc3c28ddf 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -419,6 +419,11 @@ FlGui *FlGui::instance(int argc, char **argv) int FlGui::run() { +#ifdef HAVE_ONELAB2 + // Enable multi-thread support by locking from the main thread + Fl::lock(); +#endif + // bounding box computation necessary if we run the gui without merging any // files (e.g. if we build the geometry with python and create the gui from // the python script) diff --git a/contrib/onelab2/GmshLocalClient.cpp b/contrib/onelab2/GmshLocalClient.cpp index 2c18ef6cfb4d47ddb4298bf474f7b9286500afc3..011cab5304765a4456720eec888d960eff7423e9 100644 --- a/contrib/onelab2/GmshLocalClient.cpp +++ b/contrib/onelab2/GmshLocalClient.cpp @@ -1,12 +1,54 @@ #include "GmshLocalClient.h" #include "onelabUtils.h" #ifdef HAVE_FLTK +#include "GmshMessage.h" #include "onelab2Group.h" void GmshLocalClient::setCallback(onelabGroup *cb) {_cb_obj = cb;} -void GmshLocalClient::onNewParameter(onelab::parameter *p){if(_cb_obj) _cb_obj->addParameter(*p);} -void GmshLocalClient::onUpdateParameter(onelab::parameter *p){if(_cb_obj) _cb_obj->updateParameter(*p);} -void GmshLocalClient::onRemoveParameter(onelab::parameter *p){if(_cb_obj) _cb_obj->removeParameter(*p);} +void GmshLocalClient::onNewParameter(onelab::parameter *p) +{ + if(_cb_obj) { + Fl::lock(); + _cb_obj->addParameter(*p); + Fl::unlock(); + } + Fl::awake((void *)NULL); +} +void GmshLocalClient::onUpdateParameter(onelab::parameter *p) +{ + if(_cb_obj) { + Fl::lock(); + _cb_obj->updateParameter(*p); + Fl::unlock(); + } + Fl::awake((void *)NULL); +} +void GmshLocalClient::onRemoveParameter(onelab::parameter *p) +{ + if(_cb_obj) { + Fl::lock(); + _cb_obj->removeParameter(*p); + Fl::unlock(); + } + Fl::awake((void *)NULL); +} +void GmshLocalClient::onMessage(const std::string & name, const std::string &message, int level) +{ + Fl::lock(); + switch(level) { + case OnelabAttrMessage::Info: + Msg::Direct("Info : %s - %s", name.c_str(), message.c_str()); + break; + case OnelabAttrMessage::Warning: + Msg::Warning("%s - %s", name.c_str(), message.c_str()); + break; + case OnelabAttrMessage::Error: + Msg::Error("%s - %s", name.c_str(), message.c_str()); + break; + } + Fl::unlock(); + Fl::awake((void *)NULL); +} #endif void GmshLocalClient::run(std::string action) { diff --git a/contrib/onelab2/GmshLocalClient.h b/contrib/onelab2/GmshLocalClient.h index 9c87fcf9af12c6fdfbd8529dcb7ace22bcd4899a..8b7e9714e2f7443527a7d1d37aba5e5ce1a9a599 100644 --- a/contrib/onelab2/GmshLocalClient.h +++ b/contrib/onelab2/GmshLocalClient.h @@ -24,6 +24,7 @@ public: void onNewParameter(onelab::parameter *p); void onUpdateParameter(onelab::parameter *p); void onRemoveParameter(onelab::parameter *p); + void onMessage(const std::string &name, const std::string &message, int level); #else GmshLocalClient(std::string name, onelab::parameterSpace *parameterSpace) : OnelabLocalClient(name, parameterSpace){} diff --git a/contrib/onelab2/OnelabLocalClient.h b/contrib/onelab2/OnelabLocalClient.h index 18a7f8f184723023b068cb6cf44761a5569cde52..cb71e790825845f2e0ab363acc7ff5a2eebbb45b 100644 --- a/contrib/onelab2/OnelabLocalClient.h +++ b/contrib/onelab2/OnelabLocalClient.h @@ -21,6 +21,7 @@ public: virtual void onNewParameter(onelab::parameter *p){} virtual void onUpdateParameter(onelab::parameter *p){} virtual void onRemoveParameter(onelab::parameter *p){} + virtual void onMessage(const std::string &name, const std::string &message, int level){} virtual void run(std::string action) {} void stop() {} diff --git a/contrib/onelab2/OnelabServer.cpp b/contrib/onelab2/OnelabServer.cpp index a8a938fdb09617aba717a753ad74e13076a991ed..ce6ae8087d8ede9897919cea2da5feca050cac1f 100644 --- a/contrib/onelab2/OnelabServer.cpp +++ b/contrib/onelab2/OnelabServer.cpp @@ -21,18 +21,11 @@ #include "GModel.h" #include "Options.h" -static bool haveToStop = false; - -void signalHandler(int unused) -{ - haveToStop = true; -} OnelabServer::OnelabServer(UInt32 iface, UInt16 port) { _ip.address = iface; _ip.port = port; - #ifdef HAVE_UDT UDT::startup(); _fdu = udt_socket(_ip, SOCK_STREAM); @@ -139,7 +132,7 @@ void OnelabServer::sendto(std::string client, UInt8 *buff, UInt32 len) } } -OnelabLocalNetworkClient *OnelabServer::getClient(UInt32 ip, UInt16 port) +OnelabLocalNetworkClient *OnelabServer::getClient(const UInt32 ip, const UInt16 port) { for(std::vector<OnelabLocalNetworkClient>::iterator it = _clients.begin(); it != _clients.end(); ++it) { if((*it).getIp() == ip && (*it).getPort() == port) @@ -148,7 +141,7 @@ OnelabLocalNetworkClient *OnelabServer::getClient(UInt32 ip, UInt16 port) return NULL; } -OnelabLocalNetworkClient *OnelabServer::getClient(std::string name) +OnelabLocalNetworkClient *OnelabServer::getClient(const std::string &name) { for(std::vector<OnelabLocalNetworkClient>::iterator it = _clients.begin(); it != _clients.end(); ++it) { if((*it).getName() == name) @@ -156,7 +149,7 @@ OnelabLocalNetworkClient *OnelabServer::getClient(std::string name) } return NULL; } -OnelabLocalClient *OnelabServer::getLocalClient(std::string name) +OnelabLocalClient *OnelabServer::getLocalClient(const std::string &name) { for(std::vector<OnelabLocalClient *>::iterator it = _localClients.begin(); it != _localClients.end(); ++it) { if((*it)->getName() == name) @@ -166,6 +159,30 @@ OnelabLocalClient *OnelabServer::getLocalClient(std::string name) } +void OnelabServer::waitForClient(const std::string &name) +{ + std::cout << "======= check when cli " << name << "end:" << std::cout; + OnelabLocalNetworkClient *cli = getClient(name); + OnelabLocalClient *lcli = getLocalClient(name); + if(lcli != NULL) { + // TODO + return; + } + if(cli == NULL) { // wait for the client to connect + sleep(1); + cli = getClient(name); + } + if(cli != NULL) { // wait for the client to stop + std::cout << "======= cli is remote wait with select()" << std::cout; + fd_set errorfds; + FD_ZERO(&errorfds); + FD_SET(cli->getSSocket(), &errorfds); + select(cli->getSSocket()+1, NULL, NULL, &errorfds, NULL); // Wait for the server to answer + // TODO wait until the client close + std::cout << "======= cli " << cli->getName() << "just ended ?" << std::cout; + } +} + void OnelabServer::removeClient(OnelabLocalNetworkClient *client) { for(std::vector<OnelabLocalNetworkClient>::iterator it = _clients.begin(); it != _clients.end(); ++it) { @@ -195,11 +212,8 @@ void OnelabServer::performAction(const std::string action, const std::string cli localcli->run(action); } else { // client does not exist (Gmsh is used as a server), launch the client - std::cout << action << " on " << client << "(launch a new remote Gmsh)" << std::endl; - if(launchClient(client) >= 0) - ;// FIXME then action or action is store in onelab DB ? - else - ;// TODO save action and wait for the cli ? + std::cout << action << " on " << client << "(launch a new remote client)" << std::endl; + launchClient(client); } } else { @@ -345,19 +359,9 @@ void *listenOnClients(void *param) UDT::close(*it); break; case OnelabProtocol::OnelabMessage: - // TODO do not use Gmsh, send message to GUI if(msg.attrs.size()==1 && msg.attrs[0]->getAttributeType() == OnelabAttrMessage::attributeType()) { - switch(((OnelabAttrMessage *)msg.attrs[0])->getLevel()) { - case OnelabAttrMessage::Info: - Msg::Direct("Info : %s - %s", cli->getName().c_str(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage()); - break; - case OnelabAttrMessage::Warning: - Msg::Warning("%s - %s", cli->getName().c_str(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage()); - break; - case OnelabAttrMessage::Error: - Msg::Error("%s - %s", cli->getName().c_str(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage()); - break; - } + OnelabLocalClient *gui = OnelabServer::instance()->getLocalClient("localGUI"); + if(gui) gui->onMessage(cli->getName(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage(), ((OnelabAttrMessage *)msg.attrs[0])->getLevel()); } break; case OnelabProtocol::OnelabRequest: @@ -532,8 +536,6 @@ void OnelabServer::Run() #endif } udt_socket_close(_fdu); -#else - // TODO - ip4_socket_close(_fds); #endif + ip4_socket_close(_fds); } diff --git a/contrib/onelab2/OnelabServer.h b/contrib/onelab2/OnelabServer.h index c188676894283b4b13b20a3847f9c33af5c2cd35..b3558414ffd4894e9eb9242228c0ab893de37158 100644 --- a/contrib/onelab2/OnelabServer.h +++ b/contrib/onelab2/OnelabServer.h @@ -28,13 +28,16 @@ private: UDTSOCKET _fdu; int _eid; void sendto(std::string client, UInt8 *buff, UInt32 len); - std::string waitForClientName(UDTSOCKET fd); #endif public: OnelabServer(UInt16 port); OnelabServer(UInt32 iface, UInt16 port); static OnelabServer *instance(const UInt32 iface=0, const UInt16 port=0) { if(!_server) _server = new OnelabServer(iface, port); + else if(iface != 0 || port != 0) { + delete _server; + _server = new OnelabServer(iface, port); + } return _server; } static void setInstance(OnelabServer *s) { _server = s; } @@ -59,9 +62,10 @@ public: void removeClient(OnelabLocalNetworkClient *client); std::vector<OnelabLocalNetworkClient> &getClients() {return _clients;} std::vector<OnelabLocalClient *> &getLocalClients() {return _localClients;} - OnelabLocalNetworkClient *getClient(UInt32 ip, UInt16 port); - OnelabLocalNetworkClient *getClient(std::string name); - OnelabLocalClient *getLocalClient(std::string name); + OnelabLocalNetworkClient *getClient(const UInt32 ip, const UInt16 port); + OnelabLocalNetworkClient *getClient(const std::string &name); + OnelabLocalClient *getLocalClient(const std::string &name); + void waitForClient(const std::string &name); void sendAllParameter(OnelabLocalNetworkClient *cli); // Parameters methods void clear(const std::string &name="", const std::string &client="") { @@ -82,7 +86,6 @@ public: pp->addClient("localGUI", true); } for(std::vector<OnelabLocalClient *>::iterator it = _localClients.begin() ; it != _localClients.end(); ++it) { - std::cout << (*it)->getName() << " and is " << ((isNew)?"new ":"updated ") << " from " << client << std::endl; if((*it)->getName() != client) { if(isNew)(*it)->onNewParameter(pp); else (*it)->onUpdateParameter(pp);