diff --git a/slsDetectorGui/client/qClient.cpp b/slsDetectorGui/client/qClient.cpp index 08bf87ff2..1583bae52 100644 --- a/slsDetectorGui/client/qClient.cpp +++ b/slsDetectorGui/client/qClient.cpp @@ -40,6 +40,15 @@ qClient::qClient(char* hostname){ delete mySocket; exit(-1); } + + //create socket to connect to stop server + myStopSocket = new MySocketTCP(hostname, DEFAULT_GUI_PORTNO+1); + if (myStopSocket->getErrorStatus()){ + cout << "Error: could not connect to host:" << hostname << " with port " << DEFAULT_GUI_PORTNO + 1 << endl; + delete myStopSocket; + exit(-1); + } + } @@ -47,6 +56,7 @@ qClient::qClient(char* hostname){ qClient::~qClient() { if(mySocket) delete mySocket; + if(myStopSocket) delete myStopSocket; } @@ -82,9 +92,9 @@ int qClient::executeLine(int narg, char *args[]){ argument = args[1]; //start acquisition if(argument == "start") - sendToGuiServer(F_START_ACQUISITION); + startAcquisition(); else if (argument == "stop") - sendToGuiServer(F_STOP_ACQUISITION); + stopAcquisition(); else{ cout << "Error: could not parse arguments: " << argument << endl; printCommands(); @@ -96,16 +106,13 @@ int qClient::executeLine(int narg, char *args[]){ else if (cmd == "acquire"){ - sendToGuiServer(F_START_AND_READ_ALL); + startAcquisition(true); retval = getStatus(); } else if (cmd == "exit"){ - if (sendToGuiServer(F_EXIT_SERVER) == OK) - retval = "Gui Server Exited successfully."; - else - retval = "Gui Server could not exit successfully"; + return exitServer(); } @@ -127,7 +134,7 @@ int qClient::executeLine(int narg, char *args[]){ string qClient::printCommands(){ ostringstream os; - os << "\nexit \t exits server in gui" << std::endl; + os << "\nexit \t exits servers in gui" << std::endl; os << "status \t gets status of acquisition in gui. - can be running or idle" << std::endl; os << "status i starts/stops acquistion in gui-non blocking. i is start or stop" << std::endl; os << "acquire starts acquistion in gui-blocking" << std::endl; @@ -145,12 +152,12 @@ string qClient::getStatus(){ int progress = 0; char answer[100]; - if (mySocket->Connect() >= 0) { - mySocket->SendDataOnly(&fnum,sizeof(fnum)); - mySocket->ReceiveDataOnly(&ret,sizeof(ret)); - mySocket->ReceiveDataOnly(&retval,sizeof(retval)); - mySocket->ReceiveDataOnly(&progress,sizeof(progress)); - mySocket->Disconnect(); + if (myStopSocket->Connect() >= 0) { + myStopSocket->SendDataOnly(&fnum,sizeof(fnum)); + myStopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + myStopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + myStopSocket->ReceiveDataOnly(&progress,sizeof(progress)); + myStopSocket->Disconnect(); }else exit(-1); @@ -165,9 +172,10 @@ string qClient::getStatus(){ //------------------------------------------------------------------------------------------------------------------------------------------------- -int qClient::sendToGuiServer(int fnum){ +int qClient::startAcquisition(bool blocking){ + int fnum = F_START_ACQUISITION; + if(blocking) fnum = F_START_AND_READ_ALL; int ret = FAIL; - char mess[100] = ""; if (mySocket->Connect() >= 0) { mySocket->SendDataOnly(&fnum,sizeof(fnum)); @@ -186,3 +194,41 @@ int qClient::sendToGuiServer(int fnum){ //------------------------------------------------------------------------------------------------------------------------------------------------- + +int qClient::stopAcquisition(){ + int fnum = F_STOP_ACQUISITION; + int ret = FAIL; + + if (myStopSocket->Connect() >= 0) { + myStopSocket->SendDataOnly(&fnum,sizeof(fnum)); + myStopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret == FAIL){ + myStopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Gui returned error: " << mess << std::endl; + } + myStopSocket->Disconnect(); + }else + exit(-1); + + return ret; +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + +int qClient::exitServer(){ + int fnum = F_EXIT_SERVER; + int ret = FAIL; + + if (myStopSocket->Connect() >= 0) { + myStopSocket->SendDataOnly(&fnum,sizeof(fnum)); + myStopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + myStopSocket->ReceiveDataOnly(mess,sizeof(mess)); + cout << mess << endl; + myStopSocket->Disconnect(); + }else + exit(-1); + + return ret; +} diff --git a/slsDetectorGui/client/qClient.h b/slsDetectorGui/client/qClient.h index 05413cbc1..fbec87a95 100644 --- a/slsDetectorGui/client/qClient.h +++ b/slsDetectorGui/client/qClient.h @@ -36,15 +36,28 @@ private: /** Print list of commands */ string printCommands(); - /** Send to Gui Server */ - int sendToGuiServer(int fnum); + /** Start Acquisition + * @param blocking true if its a blocking acquistion + */ + int startAcquisition(bool blocking = false); + + /** Stops Acquisition */ + int stopAcquisition(); /** Gets run status */ string getStatus(); + /** Exits Server */ + int exitServer(); + /** client socket */ MySocketTCP *mySocket; + /** client socket */ + MySocketTCP *myStopSocket; + + char mess[MAX_STR_LENGTH]; + }; diff --git a/slsDetectorGui/include/qDetectorMain.h b/slsDetectorGui/include/qDetectorMain.h index 7b0723e7e..751aaec47 100644 --- a/slsDetectorGui/include/qDetectorMain.h +++ b/slsDetectorGui/include/qDetectorMain.h @@ -77,8 +77,6 @@ public: /** Returns progress bar value */ int GetProgress(){return tab_measurement->GetProgress();}; - /** Uncheck the Listen to Gui Client mode when server has exited using exit command */ - void GuiServerExited(){actionListenGuiClient->setChecked(false);}; private: /** The Qt Application */ @@ -181,6 +179,10 @@ void EnableTabs(); * */ void SetZoomToolTip(bool disable); +/** Uncheck the Listen to gui client mode when the server has exited + */ +void UncheckServer(); + protected: /** Adjust the resizing to resize plot, except for actions tab * */ diff --git a/slsDetectorGui/include/qServer.h b/slsDetectorGui/include/qServer.h index ed2b38fa5..bd26080c6 100644 --- a/slsDetectorGui/include/qServer.h +++ b/slsDetectorGui/include/qServer.h @@ -12,17 +12,19 @@ #include "sls_detector_defs.h" #include "qDefs.h" class qDetectorMain; - /** Project Class Headers */ class multiSlsDetector; class MySocketTCP; +/** Qt Include Headers */ +#include /** C++ Include Headers */ /** *@short Sets up the gui server */ -class qServer: public virtual slsDetectorDefs{ +class qServer: public QWidget, public virtual slsDetectorDefs{ + Q_OBJECT public: @@ -41,10 +43,10 @@ private: int FunctionTable(); /** Decodes Function */ - int DecodeFunction(); + int DecodeFunction(MySocketTCP* sock); - /** Unrecognized Function */ - int M_nofunc(); + /** Exit Server */ + int ExitServer(); /** @@ -61,8 +63,21 @@ private: */ int StartServer(); - /** Exit Server */ - int ExitServer(); + /** + * Static function - Thread started which listens to client gui to stop acquisition + * Called by StartStopServer() + * @param this_pointer pointer to this object + */ + static void* StopServerThread(void *this_pointer); + + /** + * Thread started which listens to client gui to stop acquisition. + * Called by startServerThread() + * + */ + int StopServer(); + + /** Get Detector Status */ int GetStatus(); @@ -83,8 +98,12 @@ private: /** tcp socket to gui client */ MySocketTCP *mySocket; + /** tcp socket to gui client to stop or get status */ + MySocketTCP *myStopSocket; + /** server port number*/ int port_no; + /** Lock Status if server locked to a client */ int lockStatus; @@ -97,13 +116,20 @@ private: static int gui_server_thread_running; /** thread listening to gui client*/ pthread_t gui_server_thread; + /** thread also listening to gui client to stop acquisition*/ + pthread_t gui_stop_server_thread; /** server started */ int checkStarted; + int checkStopStarted; /** Message */ char mess[MAX_STR_LENGTH]; + +signals: + void ServerStoppedSignal(); + }; diff --git a/slsDetectorGui/src/qDetectorMain.cpp b/slsDetectorGui/src/qDetectorMain.cpp index 7ab0af43f..c293bf83e 100644 --- a/slsDetectorGui/src/qDetectorMain.cpp +++ b/slsDetectorGui/src/qDetectorMain.cpp @@ -285,6 +285,10 @@ void qDetectorMain::Initialization(){ connect(menuUtilities, SIGNAL(triggered(QAction*)), this,SLOT(ExecuteUtilities(QAction*))); // Help Menu connect(menuHelp, SIGNAL(triggered(QAction*)), this,SLOT(ExecuteHelp(QAction*))); + + +//server + connect(myServer, SIGNAL(ServerStoppedSignal()), this,SLOT(UncheckServer())); } @@ -329,9 +333,12 @@ void qDetectorMain::EnableModes(QAction *action){ //listen to gui client if(action==actionListenGuiClient){ - disconnect(menuModes, SIGNAL(triggered(QAction*)), this,SLOT(EnableModes(QAction*))); - actionListenGuiClient->setChecked(myServer->StartStopServer(actionListenGuiClient->isChecked())); - connect(menuModes, SIGNAL(triggered(QAction*)), this,SLOT(EnableModes(QAction*))); + + myServer->StartStopServer(actionListenGuiClient->isChecked()); + + //disconnect(menuModes, SIGNAL(triggered(QAction*)), this,SLOT(EnableModes(QAction*))); + //actionListenGuiClient->setChecked(myServer->StartStopServer(actionListenGuiClient->isChecked())); + //connect(menuModes, SIGNAL(triggered(QAction*)), this,SLOT(EnableModes(QAction*))); } //Set DebugMode else if(action==actionDebug){ @@ -782,4 +789,17 @@ int qDetectorMain::StartStopAcquisitionFromClient(bool start){ } +//------------------------------------------------------------------------------------------------------------------------------------------------- + + +void qDetectorMain::UncheckServer(){ +#ifdef VERBOSE + cout << "Unchecking Mode : Listen to Gui Client" << endl; +#endif + disconnect(menuModes, SIGNAL(triggered(QAction*)), this,SLOT(EnableModes(QAction*))); + actionListenGuiClient->setChecked(false); + connect(menuModes, SIGNAL(triggered(QAction*)), this,SLOT(EnableModes(QAction*))); +} + + //------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/slsDetectorGui/src/qServer.cpp b/slsDetectorGui/src/qServer.cpp index 98879d01e..5a25e686d 100644 --- a/slsDetectorGui/src/qServer.cpp +++ b/slsDetectorGui/src/qServer.cpp @@ -27,7 +27,7 @@ int qServer::gui_server_thread_running(0); qServer::qServer(qDetectorMain *t): - myMainTab(t), mySocket(NULL),port_no(DEFAULT_GUI_PORTNO),lockStatus(0){ + myMainTab(t), mySocket(NULL),myStopSocket(NULL),port_no(DEFAULT_GUI_PORTNO),lockStatus(0){ FunctionTable(); @@ -40,6 +40,7 @@ qServer::qServer(qDetectorMain *t): qServer::~qServer(){ delete myMainTab; if(mySocket) delete mySocket; + if(myStopSocket) delete myStopSocket; } @@ -48,9 +49,6 @@ qServer::~qServer(){ int qServer::FunctionTable(){ - for (int i=0;iReceiveDataOnly(&fnum,sizeof(fnum)); + n = sock->ReceiveDataOnly(&fnum,sizeof(fnum)); if (n <= 0) { #ifdef VERYVERBOSE cout << "ERROR reading from socket " << n << ", " << fnum << endl; @@ -86,8 +84,26 @@ int qServer::DecodeFunction(){ cout << "calling function fnum = "<< fnum << hex << ":"<< flist[fnum] << endl; #endif - if (fnum<0 || fnum>NUMBER_OF_FUNCTIONS-1) - fnum = NUMBER_OF_FUNCTIONS-1; + + + if (((sock == myStopSocket) && ((fnum == F_GET_RUN_STATUS) || (fnum == F_STOP_ACQUISITION) || (fnum == F_EXIT_SERVER))) || + ((sock == mySocket) && ((fnum == F_START_ACQUISITION) || (fnum == F_START_AND_READ_ALL)))) + ; + //unrecognized functions exit guis + else{ + ret = qDefs::FAIL; + sprintf(mess,"Unrecognized Function\n"); + cout << mess << endl; + + if (mySocket) + mySocket->ShutDownSocket(); + + myStopSocket->SendDataOnly(&ret,sizeof(ret)); + myStopSocket->SendDataOnly(mess,sizeof(mess)); + return GOODBYE; + } + + //calling function ret = (this->*flist[fnum])(); if (ret==qDefs::FAIL) @@ -100,20 +116,24 @@ int qServer::DecodeFunction(){ //------------------------------------------------------------------------------------------------------------------------------------------ -int qServer::M_nofunc(){ +int qServer::ExitServer(){ - int ret = qDefs::FAIL; - sprintf(mess,"Unrecognized Function\n"); + int ret = OK; + strcpy(mess," Gui Server closed successfully\n"); + + if(mySocket) + mySocket->ShutDownSocket(); + + myStopSocket->SendDataOnly(&ret,sizeof(ret)); + myStopSocket->SendDataOnly(mess,sizeof(mess)); cout << mess << endl; - mySocket->SendDataOnly(&ret,sizeof(ret)); - mySocket->SendDataOnly(mess,sizeof(mess)); - return GOODBYE; } -//------------------------------------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------------------------------ + int qServer::StartStopServer(int start){ @@ -125,26 +145,43 @@ int qServer::StartStopServer(int start){ #endif if(!gui_server_thread_running){ -#ifdef VERBOSE - cout << "Starting gui server thread ...." << endl; -#endif gui_server_thread_running=1; - checkStarted=1; + + //error creating thread + checkStarted=1; if (pthread_create(&gui_server_thread, NULL,StartServerThread, (void*) this)){ gui_server_thread_running=0; qDefs::Message(qDefs::WARNING,"Can't create gui server thread", "Server"); - return 0; + cout << "ERROR: Can't create gui server thread" << endl; + return FAIL; } while(checkStarted); - checkStarted=0; + checkStarted = 0; #ifdef VERBOSE if(gui_server_thread_running) cout << "Server thread created successfully." << endl; #endif + + + //error creating thread + checkStopStarted=1; + if (pthread_create(&gui_stop_server_thread, NULL,StopServerThread, (void*) this)){ + gui_server_thread_running=0; + qDefs::Message(qDefs::WARNING,"Can't create gui stop server thread", "Server"); + cout << "ERROR: Can't create gui stop server thread" << endl; + return FAIL; + } + while(checkStopStarted); + checkStopStarted=0; +#ifdef VERBOSE + if(gui_server_thread_running) + cout << "Server Stop thread created successfully." << endl; +#endif } } + //stop server else{ #ifdef VERBOSE @@ -152,10 +189,8 @@ int qServer::StartStopServer(int start){ #endif if(gui_server_thread_running){ -#ifdef VERBOSE - cout << "Stopping gui server thread ...." << endl; -#endif gui_server_thread_running=0; + if(mySocket) mySocket->ShutDownSocket(); pthread_join(gui_server_thread,NULL); @@ -163,13 +198,20 @@ int qServer::StartStopServer(int start){ delete mySocket; mySocket = NULL; } + + if(myStopSocket) + myStopSocket->ShutDownSocket(); + pthread_join(gui_stop_server_thread,NULL); + if(myStopSocket){ + delete myStopSocket; + myStopSocket = NULL; + } } #ifdef VERBOSE - cout << "Server stopped successfully." << endl; + cout << "Server threads stopped successfully." << endl; #endif } - return gui_server_thread_running; } @@ -177,6 +219,71 @@ int qServer::StartStopServer(int start){ //------------------------------------------------------------------------------------------------------------------------------------------------- +void* qServer::StopServerThread(void* this_pointer){ + ((qServer*)this_pointer)->StopServer(); + return this_pointer; +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + + +int qServer::StopServer(){ +#ifdef VERYVERBOSE + cout << "In StopServer()" << endl; +#endif + int ret = qDefs::OK; + + myStopSocket = new MySocketTCP(port_no+1); + if (myStopSocket->getErrorStatus()){ + gui_server_thread_running = 0; + qDefs::Message(qDefs::WARNING,"Could not start gui stop server socket","Server"); + } + checkStopStarted = 0; + + while ((gui_server_thread_running) && (ret!=GOODBYE)) { +#ifdef VERBOSE + cout<< endl; +#endif +#ifdef VERYVERBOSE + cout << "Waiting for client call" << endl; +#endif + if(myStopSocket->Connect()>=0){ +#ifdef VERYVERBOSE + cout << "Conenction accepted" << endl; +#endif + ret = DecodeFunction(myStopSocket); +#ifdef VERYVERBOSE + cout << "function executed" << endl; +#endif + myStopSocket->Disconnect(); +#ifdef VERYVERBOSE + cout << "connection closed" << endl; +#endif + } + } +#ifdef VERBOSE + cout << "Stopped gui stop server thread" << endl; +#endif + gui_server_thread_running = 0; + //delete socket(via exit server) + if(myStopSocket){ + delete myStopSocket; + myStopSocket = NULL; + } + + if(!gui_server_thread_running) + emit ServerStoppedSignal(); + + return qDefs::OK; +} + + +//------------------------------------------------------------------------------------------------------------------------------------------------- + + + void* qServer::StartServerThread(void* this_pointer){ ((qServer*)this_pointer)->StartServer(); return this_pointer; @@ -189,7 +296,7 @@ void* qServer::StartServerThread(void* this_pointer){ int qServer::StartServer(){ #ifdef VERYVERBOSE - cout << "In StartServer()\n"); + cout << "In StartServer()" << endl; #endif int ret = qDefs::OK; @@ -211,7 +318,7 @@ int qServer::StartServer(){ #ifdef VERYVERBOSE cout << "Conenction accepted" << endl; #endif - ret = DecodeFunction(); + ret = DecodeFunction(mySocket); #ifdef VERYVERBOSE cout << "function executed" << endl; #endif @@ -230,8 +337,10 @@ int qServer::StartServer(){ delete mySocket; mySocket = NULL; } - //uncheck the server in modes(via exit server) - myMainTab->GuiServerExited(); + + if(!gui_server_thread_running) + emit ServerStoppedSignal(); + return qDefs::OK; } @@ -254,9 +363,9 @@ int qServer::GetStatus(){ progress = myMainTab->GetProgress(); // send answer - mySocket->SendDataOnly(&ret,sizeof(ret)); - mySocket->SendDataOnly(&retval,sizeof(retval)); - mySocket->SendDataOnly(&progress,sizeof(progress)); + myStopSocket->SendDataOnly(&ret,sizeof(ret)); + myStopSocket->SendDataOnly(&retval,sizeof(retval)); + myStopSocket->SendDataOnly(&progress,sizeof(progress)); //return ok/fail return ret; } @@ -286,9 +395,9 @@ int qServer::StopsAcquisition(){ strcpy(mess,"Could not stop acquisition in gui. \n"); int ret = myMainTab->StartStopAcquisitionFromClient(false); - mySocket->SendDataOnly(&ret,sizeof(ret)); + myStopSocket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL) - mySocket->SendDataOnly(mess,sizeof(mess)); + myStopSocket->SendDataOnly(mess,sizeof(mess)); return ret; } @@ -316,18 +425,3 @@ int qServer::Acquire(){ //------------------------------------------------------------------------------------------------------------------------------------------ - -int qServer::ExitServer(){ - - int ret = OK; - strcpy(mess,"closing gui server"); - - mySocket->SendDataOnly(&ret,sizeof(ret)); - mySocket->SendDataOnly(mess,sizeof(mess)); - cout << mess << endl; - - return GOODBYE; -} - - -//------------------------------------------------------------------------------------------------------------------------------------------