TMonitor::Ready(TSocket*) not executed

Hello Rooters,

I am trying to implement a server-client connection using TSocket.
Basicly the server is waiting for a signal TMonitor::Ready(TSocket*). If it gets such a signal the socket is added to a list and it sends stuff to it (in the attached example its a 2d-Histogram).
Everything works fine, but when the server is running a while() loop the signal will be processed only after a long time, even though I put a gSystem->ProcessEvents() statement into that while loop. I thought that every pending event will be processed when the program comes to this statement.

Am I doing something wrong?

Here is a short Discription of the attached code:
Run testserver.c (.x testserver.c) and then run testclient.c (.x testclient.c) in a new rootsession. You will see that everything works fine. The server finds the client immediately and connects to it.
Now run testserver.c (.x testserver.c) and press the start button (the Histogram will get filled and the rate is shown). Now run testclient.c (.x testclient.c) in a new rootsession. It takes about 5 min. for the client to connect to the server. If you press the stop button, the client will connect instantaneously to the server.
Is there something wrong in the way I am doing this?

Thank you

Lutz
testserver.c (6.28 KB)
testclient.c (2 KB)

Dear Lutz,

Your implementation looks fine, and indeed there seems to be a problem with gSystem->ProcessEvents() in detecting descriptor activity, problem well reproduceable with your macros.
This under investigation.

In the meanwhile, the following workaround to detect activity on the socket should work:

add method “checkMonitor()” to MyServer:


class MyServer : public TQObject
{
public:
	MyServer();
	virtual ~MyServer();
	
	void send(TH2F * histo);
	bool handleSocket(TSocket * sock); // modified return
        void checkman();
        void checkMonitor();      // new method
	
private:
	TMonitor * mon;
	TServerSocket *servs;
	TList * socks;
};

The new method should do the following:


MyServer::checkMonitor()
{
   // Now check whether somebody is connecting ...
   // (Select with timeout 1 ms: just to check)
   TList Ready;
   Int_t rc = mon->Select(&Ready,0,1);
   if (rc > 0) {
      TIter next(&Ready);
      TSocket *s = 0;
      // Loop to avoid spurious signals ...
      while ((s = (TSocket *)next()) && (s != (TSocket *)(-1))) {
         if (handleSocket(s))
            return;
      }
   }
   return;
}

The modified handleSocket:

bool MyServer::handleSocket(TSocket * sock)
{
	if (sock->IsA() == TServerSocket::Class()) 
	{
		// accept new connection from client
		TSocket *s = ((TServerSocket*)sock)->Accept();
		s->SetOption(kNoBlock,1);
		socks->Add(s);
		cout <<"accepted connection from "<< s->GetInetAddress().GetHostName()<<" "<<endl;
                return 1;
	}
	else
	{
		cout <<" dont know what came in, but something came in"<<endl;
	}
        return 0;
}

Now, call checkMonitor() in MyDaq::acquire after gSystem->ProcessEvents():

        ...			
        time->Start(true);
     }

     // Still needed for Ctrl-C and GUI events
     gSystem->ProcessEvents();

     // Handle pending connections ...
     ser->checkMonitor();
		
     if  (wait || !running)
         continue;
     ...

(and possibly also after the first call to gSystem->ProcessEvents()).

The modified testserver.C is in attachment.

Gerri Ganis
testserver.C (6.82 KB)

Dear Lutz,

We have found a problem with the way gSystem->ProcessEvents() was detecting descriptor activity. The fix is now in the CVS head and will be included in the next ROOT release.
I’ve tried your macros and they seem to work fine.
If you have a chance to try it, please let us know if it is ok for you.

Thanks for reporting the problem.

Gerri Ganis

Dear Garri,

Thank you for investigating my Problem. I will wait for the next Release of ROOT and then try my Program again. I will let you know wether I still see the problem, or wether its gone.

Thank you

Lutz