Re: How to stop properly a TServerSocket running in a TThread

From: Gerri Ganis <gerardo.ganis_at_cern.ch>
Date: Tue, 06 Feb 2007 08:31:40 +0100

Dear Luc,

It looks like there is problem with "double" deletion of the thread:

      TThread::Delete(fThreadNet);
      delete fThreadNet; 

but I could not debug it in depth yet.
I will investigate asap and let you know.

Regards,

Gerri Ganis

Legeard Luc wrote:

>
> Hello Rooters
>
> I 'd like to run a histograms server on a network.
> I' d like also stop it and restart it when i want.
>
> So to do that, i 've done a example of server and client given in
> attached files .
> I can used like that
> 1) Running the server in a root session and define the object to be
> served ( in this case , it's histograms)
> root [0] gROOT->LoadMacro("ServerRoot.C++");
> root [1] TH1S* histo1= new TH1S("Histo1","histo1",10,0,10);
> root [2] TH1S* histo2= new TH1S("Histo2","histo2 ",10,0,10);
> root [3] for (int i = 0;i<10;i++){histo1 ->Fill(i,i);histo2
> ->Fill(i,10-i);}
> root [4] ServerRoot* serv = new ServerRoot();
> root [5] serv ->StartGNetServer();
> root [6] serv ->SetSpectra(histo1); // to serve histo1
> ......
> root [10] serv ->SetSpectra(histo2);// to serve histo1
>
>
>
> 2) Running a client in a other Root session
> root [0] gROOT->LoadMacro("ClientRoot.C++");
> root [2] ClientRoot* client =new ClientRoot();
> root [3] client->Open();
> root [4] client->TestServer();
>
> root [5] TH1* hista1= client->GetSpectrum();
>
> root [6] hista1 -> Draw();
> root [7] client->Close();
>
>
>
> All this runs if we don't try to stop server:
>
>
> root [16] serv ->StopGNetServer();
>
> *********************
> Net Server stopped
> *********************
> root [17]
> *** Break *** segmentation violation
>
> *** Break *** segmentation violation
> (no debugging symbols found)
> Using host libthread_db library "/lib/libthread_db.so.1".
> Attaching to program: /proc/25190/exe, process 25190
> (no debugging symbols found)
> Using host libthread_db library "/lib/libthread_db.so.1".
> Attaching to program: /proc/25190/exe, process 25190
> ptrace: Opération non permise.
> /home/legeard/test/TestServerRoot/25190: Aucun fichier ou répertoire
> de ce type.
> `shared object read from target memory' has disappeared; keeping its
> symbols.
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> [Thread debugging using libthread_db enabled]
> [New Thread -1208400192 (LWP 25190)]
> [New Thread -1208583248 (LWP 25236)]
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> (no debugging symbols found)...done.
> 0x00192410 in __kernel_vsyscall ()
> Thread 2 (Thread -1208583248 (LWP 25236)):
> #0 0x00192410 in __kernel_vsyscall ()
> #1 0x074e40db in __waitpid_nocancel () from /lib/libc.so.6
> #2 0x0748cda7 in do_system () from /lib/libc.so.6
> #3 0x0748d138 in system () from /lib/libc.so.6
> #4 0x001773d5 in system () from /lib/libpthread.so.0
> #5 0x006f7ee7 in TUnixSystem::Exec () from
> /usr/global/root/root5.14//lib/libCore.so
> #6 0x006ffb86 in TUnixSystem::StackTrace () from
> /usr/global/root/root5.14//lib/libCore.so
> #7 0x006fef63 in TUnixSystem::DispatchSignals () from
> /usr/global/root/root5.14//lib/libCore.so
> #8 0x006ff0f1 in SigHandler () from
> /usr/global/root/root5.14//lib/libCore.so
> #9 0x006f8d5c in sighandler () from
> /usr/global/root/root5.14//lib/libCore.so
> #10 <signal handler called>
> #11 0x00bd4d68 in vtable for TString () from
> /usr/global/root/root5.14//lib/libCore.so
> #12 0x006d0b91 in TMonitor::SetReady () from
> /usr/global/root/root5.14//lib/libCore.so
> #13 0x006d0be3 in TTimeOutTimer::Notify () from
> /usr/global/root/root5.14//lib/libCore.so
> #14 0x0062646b in TTimer::CheckTimer () from
> /usr/global/root/root5.14//lib/libCore.so
> #15 0x006fad99 in TUnixSystem::DispatchTimers () from
> /usr/global/root/root5.14//lib/libCore.so
> #16 0x006ff56c in TUnixSystem::DispatchOneEvent () from
> /usr/global/root/root5.14//lib/libCore.so
> #17 0x00619714 in TSystem::InnerLoop () from
> /usr/global/root/root5.14//lib/libCore.so
> #18 0x006d1af4 in TMonitor::Select () from
> /usr/global/root/root5.14//lib/libCore.so
> #19 0x030496f7 in ServerRoot::ThreadWaitCommandsFromClient () from
> /home/legeard/test/TestServerRoot/./ServerRoot_C.so
> #20 0x0615b4b3 in TThread::Function () from
> /usr/global/root/root5.14//lib/libThread.so
> #21 0x00171bd4 in start_thread () from /lib/libpthread.so.0
> #22 0x075224fe in clone () from /lib/libc.so.6
>
> Thread 1 (Thread -1208400192 (LWP 25190)):
> #0 0x00192410 in __kernel_vsyscall ()
> #1 0x074e40db in __waitpid_nocancel () from /lib/libc.so.6
> #2 0x0748cda7 in do_system () from /lib/libc.so.6
> #3 0x0748d138 in system () from /lib/libc.so.6
> #4 0x001773d5 in system () from /lib/libpthread.so.0
> #5 0x006f7ee7 in TUnixSystem::Exec () from
> /usr/global/root/root5.14//lib/libCore.so
> #6 0x006ffb86 in TUnixSystem::StackTrace () from
> /usr/global/root/root5.14//lib/libCore.so
> #7 0x006fef63 in TUnixSystem::DispatchSignals () from
> /usr/global/root/root5.14//lib/libCore.so
> #8 0x006ff0f1 in SigHandler () from
> /usr/global/root/root5.14//lib/libCore.so
> #9 0x006f8d5c in sighandler () from
> /usr/global/root/root5.14//lib/libCore.so
> #10 <signal handler called>
> #11 0x00bd4d68 in vtable for TString () from
> /usr/global/root/root5.14//lib/libCore.so
> #12 0x006d0b91 in TMonitor::SetReady () from
> /usr/global/root/root5.14//lib/libCore.so
> #13 0x006d0be3 in TTimeOutTimer::Notify () from
> /usr/global/root/root5.14//lib/libCore.so
> #14 0x0062646b in TTimer::CheckTimer () from
> /usr/global/root/root5.14//lib/libCore.so
> #15 0x006fad99 in TUnixSystem::DispatchTimers () from
> /usr/global/root/root5.14//lib/libCore.so
> #16 0x006ff56c in TUnixSystem::DispatchOneEvent () from
> /usr/global/root/root5.14//lib/libCore.so
> #17 0x00619714 in TSystem::InnerLoop () from
> /usr/global/root/root5.14//lib/libCore.so
> #18 0x006196ba in TSystem::Run () from
> /usr/global/root/root5.14//lib/libCore.so
> #19 0x00598757 in TApplication::Run () from
> /usr/global/root/root5.14//lib/libCore.so
> #20 0x0011d565 in TRint::Run () from
> /usr/global/root/root5.14//lib/libRint.so
> Root >
>
>
>
>
>
>
>
>
> I don't understand where can be my mistake!
> Have you a idea?
>
>
> Thanks a lot
>
> Luc
>
>------------------------------------------------------------------------
>
>
>#include <TObject.h>
>#include <TFile.h>
>#include <TString.h>
>#include <TROOT.h>
>#include <TThread.h>
>#include <TMessage.h>
>#include <TSocket.h>
>#include <TServerSocket.h>
>#include <TMonitor.h>
>#include <TH1.h>
>#include <TThread.h>
>#include <iostream>
>//_________________________________________________________________________________________
>class ServerRoot : public TObject{
>
> private:
>
> TH1* fHisto; //!
> TServerSocket *fServSock ; //! Server
> TList *fSockList; //! List of open socket with client
> TMonitor *fMon; //! socket monitor (if we want to drive few client connection)
> TThread *fThreadNet; //!
> bool fRunning; // informe about running of server
> bool fStarting; // informe about starting of server
> public:
>
> ServerRoot();
> ~ServerRoot();
>
> virtual void SetSpectra(TH1* histo){fHisto=histo;};
> virtual void StartGNetServer();
> virtual void StopGNetServer();
>
> virtual void TreatmentCommands(TSocket *localsock);
>
> private:
> static void ThreadWaitCommandsFromClient(void* arg);
> void GiveSpectrum(TSocket *localsock);
> ClassDef (ServerRoot ,1); // Nerwork ROOT Server to send spectra
>};
>
>
>ClassImp(ServerRoot);
>//_________________________________________________________________________________________
>ServerRoot::ServerRoot()
>{
> fRunning=false;
> fSockList=NULL;
> fThreadNet=NULL;
> fServSock=NULL;
> fMon =NULL;
> fHisto = NULL;
> fStarting=false;
>}
>//_________________________________________________________________________________________
>ServerRoot::~ServerRoot()
>{
>// desctructor
>StopGNetServer();
>}
>
>//_________________________________________________________________________________________
>void ServerRoot::StopGNetServer ()
>{
> // Stop the Network server
>
>
>
>
> if (fRunning==false){
>
> cout<<"Server already stopped\n";
> return;
> }
>
> if (fServSock) fServSock->Close();
> if (fSockList) {
> fSockList->Delete();
> delete (fSockList);
> fSockList=NULL;
> }
> if (fServSock) {
> fMon->Remove(fServSock);
> delete (fServSock);
> fServSock=NULL;
> }
>
> if (fMon ) {
> delete (fMon);
> fMon =NULL;
> }
> if (fServSock) fServSock->Close();
> fRunning = false;
> if(fThreadNet)
> {
> TThread::Delete(fThreadNet);
> delete fThreadNet;
> fThreadNet=NULL;
> fRunning = false;
> cout<<"\n\t*********************\n\t Net Server stopped\n\t*********************\n";
> }else{
> cout <<" Thread no present\n";
> }
>}
>//_________________________________________________________________________________________
>
>void ServerRoot::StartGNetServer()
>{
> // Start the Network server
> if ( fRunning==false){
> fStarting = true;
> fServSock = new TServerSocket(9090, kTRUE);
> fMon = new TMonitor;
> fMon->Add(fServSock); //
> fSockList = new TList; // Creation of list of all client connections
> fSockList->SetOwner(); //
> // si le thread n'existe pas, on le cree
>
> if(!fThreadNet){
> fThreadNet=new TThread("MESSAGE_Net_Server", (void (*)(void *))&ServerRoot::ThreadWaitCommandsFromClient, (void*) this);
> fThreadNet->Run();
> fRunning=true;
> // fStarting = false;
> }
> }else{
> cout <<" Server already running\n";
> }
>}
>
>//_________________________________________________________________________________________
>void ServerRoot::ThreadWaitCommandsFromClient(void* arg)
>{
>
> // All command are:
> // MESSAGE HISTO -> ask to receive a histogram with name NAME_OF_HISTOGRAM
> // MESSAGE TEST -> test
> //
> ServerRoot* iGNet = (ServerRoot*) arg; // instance of ServerRoot given in parameter
> bool test;
>
> cout<<"\n\t***********************\n\t Server is running\n\t***********************\n\n";
> iGNet->fStarting = false;
> while (iGNet->fRunning ){
> TSocket *localsock;
> test = ((localsock= iGNet->fMon->Select(40)) != (TSocket*)-1);
> if (test) iGNet->TreatmentCommands(localsock);
> }// end of while
>}
>
>//________________________________________________________________________________________
>void ServerRoot::TreatmentCommands(TSocket *localsock)
>{
>
> char recp[256];
> char *word;
>
> if (localsock->IsA() == TServerSocket::Class()) {
>
> // accept new connection from client
> TSocket *sock = ((TServerSocket*)localsock)->Accept();
> fMon->Add(sock);
> fSockList->Add(sock);
> cout<< "accepted connection from "<< sock->GetInetAddress().GetHostName()<<"\n";
>
> } else {
>
> // we only get string based requests from the client
> // receive command
>
> if (localsock->Recv(recp, sizeof(recp)) <= 0) {
> fMon->Remove(localsock);
> fSockList->Remove(localsock);
> cout << "closed connection from "<< localsock->GetInetAddress().GetHostName()<<"\n";
> delete localsock ;
> return;
> }
> cout<< "Received Command : "<< recp<<"\n";
>
> //Get GROUP command word
> word = strtok (recp," ");
> if (strcmp(word,"MESSAGE")!=0) {
> cout<< " It is not a MESSAGE Net commmand! : "<<word <<"\n";;
> return;
> }
>
> //Get VERBE command word
> word = strtok (NULL, " ,.");
>
> if (strcmp(word,"HISTO")==0) { GiveSpectrum(localsock); }
>
> if (strcmp(word,"TEST")==0)
> {
> localsock->Send("MESSAGE_TESTOK");
> cout<< "send "" MESSAGE_TESTOK"" \n";
> }
>
> } //end of else
>}
>//_________________________________________________________________________________________
>void ServerRoot::GiveSpectrum(TSocket *localsock)
>{
>
> TMessage mess(kMESS_OBJECT);
>
> if(fHisto == NULL){
> cout << " No spectrum \n";
> localsock->Send("MESSAGE_NO_SPECTRUM");
> return;
> }
> mess.Reset(); // re-use TMessage object
> mess.WriteObject(fHisto); // write object in message buffer
> localsock->Send(mess); // send message
>
> // delete (mess);
>}
>//_________________________________________________________________________________________
>
>
>------------------------------------------------------------------------
>
>
>#include <iostream>
>using std::ostream;
>
>#include <TObject.h>
>#include <TFile.h>
>#include <TString.h>
>#include <TNtuple.h>
>#include <TROOT.h>
>#include <TH1.h>
>#include <TSocket.h>
>#include <TMessage.h>
>
>
>//_________________________________________________________________________________________
>class ClientRoot : public TObject{
>
> private:
>
> TSocket *sock;
> char str[1024];
> char fName[256];
>
> bool fIsOpen;
>
> public:
> ClientRoot(char* host ="localhost");
> ~ClientRoot();
>
> virtual bool TestServer();
> virtual TH1* GetSpectrum();
>
> virtual void Open();
> virtual void Close();
>
>private:
> void InitClient();
> virtual TH1* ReceiveSpectrum();
> ClassDef ( ClientRoot,1); // Nerwork ROOT Client to Receive spectra
>};
>
>ClassImp(ClientRoot);
>//_________________________________________________________________________________________
>
> ClientRoot::ClientRoot(char* host)
>{
> fIsOpen =false;
> strcpy (fName,host);
> cout<< "Client vers : "<< fName <<"\n";
>}
>//_________________________________________________________________________________________
>
> ClientRoot::~ClientRoot(){}
>//_________________________________________________________________________________________
>
>TH1* ClientRoot::GetSpectrum()
>{
>//return the histogram with "histoname"
>
> char cmd[256];
> char *word;
> TH1 * h1=NULL;
>
> char command[256];
>
> strcpy (command,"MESSAGE HISTO ");
> strcpy (cmd,command);
>
> if(!fIsOpen)
> {
> cout<<"\t*** any connected server ! ***\n";
> return(NULL);
> }else{
>
> cout << " Send command : "<<command<<" to "<< fName <<". \n";
>
> //Get GROUP command word
> word = strtok (cmd," ");
> if (strcmp(word,"MESSAGE")!=0) {
> cout<< " It is not a MESSAGE Net commmand group ! "<<word <<"=! MESSAGE\n";
> Close();
> return(NULL);
> }
>
> //Get VERBE command word
> word = strtok (NULL, " ,.");
>
> if (strcmp(word,"HISTO")==0)
> {
> sock->Send(command);
> h1= ReceiveSpectrum();
> return(h1);
> }
> cout << "Error in GetSpectrum\n";
> return(NULL);
> }
>}
>//_________________________________________________________________________________________
>
>TH1* ClientRoot::ReceiveSpectrum()
>{
> TH1 *h =NULL; //pointeur sur l'histo à recevoir;
> TMessage *message =NULL;
>
> sock->Recv(message);
> if (message ) {
> if (message->What()==kMESS_STRING){
>
> message->ReadString(str,sizeof(str));
> if(strcmp(str,"MESSAGE_NO"))
> {
> cout<<" No spectrum with this name\n";
> delete message;
> return (NULL);
> }
>
> if(strcmp(str,"MESSAGE_SPECTRA_NOT_READY"))
> {
> cout<<" No ready spectrum on server\n";
> delete message;
> return (NULL);
> }
> cout << "Error of message in ReceiveSpectrum \n";
> delete message;
> return (NULL);
> }
>
> if(message->GetClass()->InheritsFrom(TH1::Class()))
> {
> h = (TH1*)message->ReadObject(message->GetClass());
> cout << "\n DONE\n";
> delete message;
> return (h);
> }
> }
> cout << "ERROR DONE in ReceiveSpectrum \n";
> return (NULL);
>}
>
>
>//_________________________________________________________________________________________
>void ClientRoot::Open()
>{
>//set and start network root server
> sock=NULL;
>
> if (strcmp (fName,"")==0) {
> cout <<" Root device name not valid!\n";
> return;
>}
> if (!fIsOpen){
> fIsOpen = true;
> sock=NULL;
> sock = new TSocket(fName,9090);
> if (sock){
> cout << " Connection to : "<< fName <<" done \n";
> fIsOpen = true;
> }else{
> cout<<" Error in connection to : "<< fName <<" \n";
> }
>
> }
>}
>
>//_________________________________________________________________________________________
>void ClientRoot::Close()
>{ if (fIsOpen){
>//set and start network root server
> sock->Close();
> fIsOpen =false;
>
> }
>}
>//_________________________________________________________________________________________
>
>bool ClientRoot::TestServer()
>{ // test server
> // return is true if server seem to be good and started
> // else return is false
>
> char *command ="MESSAGE TEST";
> char cmd[256];
> char *word;
> bool retour = false;
>
> strcpy (cmd,command);
> // we suppose that connexion is open
> if(!fIsOpen)
> {
> cout<<"\t*** any connected server ! ***\n";
> return(retour);
> } else{
>
> //Get GROUP command word
> word = strtok (cmd," ");
> if (strcmp(word,"MESSAGE")!=0) {
> cout<< " It is not a MESSAGE Net commmand group ! "<<word <<"=! MESSAGE\n";
> Close();
> return(retour);
> }
>
> //Get VERBE command word
> word = strtok (NULL, " ,.");
>
> if (strcmp(word, "TEST")==0 )
> {
> //gcout << " Commande envoyee ; "<< command << "\n";
> sock->Send(command);
> char message[64];
> message[0]= '\0';//initialisation
> sock->Recv(message, sizeof(message));
> if (strcmp(message,"MESSAGE_TESTOK")==0) {
> cout <<" Retour recu = MESSAGE_TESTOK\n";
> retour = true;
> }
> else {
> Close();
> retour = false;
> }
> }
> }
> return(retour);
>}
>//_________________________________________________________________________________________
>
>

-- 
+--------------------------------------------------------------------------+
  Gerardo GANIS    PH Department, CERN
        address    CERN, CH 1211 Geneve 23  
                   room: 32-RC-017, tel / fax: +412276 76439 / 69133
         e-mail    gerardo.ganis_at_cern.ch
+--------------------------------------------------------------------------+
Received on Tue Feb 06 2007 - 08:32:19 CET

This archive was generated by hypermail 2.2.0 : Tue Feb 06 2007 - 17:50:01 CET