Hi,
I have run into a strange problem. I am working on a server-client model (using the examples hclient.C and hserv2.C as a prototype), and I am trying to do some cleanup when a client goes down.
In my example, the server makes a copy of the histogram that the client sends. When it detects that the connection has been dropped, it deletes the (copy of the) histogram. When a new connection opens again, I’m getting a crash as soon as I attempt to read the first histogram from the new client.
I am attaching the modified macros that reproduce the problem. By setting the “use_my_own” flag to true, the server uses its own copy of the histogram (and the code crashes). If I set it to false, everything goes smoothly, no matter how many times the client goes down and then up again.
Any clues?
Cheers,
–Christos
PS $ which root
/afs/cern.ch/sw/root/v4.02.00/rh73_slc3/root/bin/root
The server macro:
{
// if true, causes crashes when connections go down and then open again
bool use_my_own = true;
// Create canvas and pad to display the histogram
TCanvas *c1 = new TCanvas("c1","The Ntuple canvas",200,10,600,480);
c1->Draw();
// Open a server socket looking for connections on a named service or
// on a specified port.
TServerSocket *ss = new TServerSocket(9090, kTRUE);
TMonitor *mon = new TMonitor;
mon->Add(ss);
TSocket *s0 = 0;
// this is my histogram
TH1F * my_h = 0;
// # of updates
int updates = 0;
while (1) {
TMessage *mess;
TSocket *s = mon->Select();
if (s->IsA() == TServerSocket::Class()) {
if (!s0) {
s0 = ((TServerSocket *)s)->Accept();
s0->Send("go");
mon->Add(s0);
cout << " New connection opened " << endl;
}
else
printf("only accept one client connection\n");
continue;
}
s->Recv(mess);
if(!mess)
{
cout << " *** Oops! Connection has been dropped " << endl;
// connection has been dropped - do some cleanup
mon->Remove(s0); s0->Close();
s0 = 0;
if(use_my_own && my_h)
delete my_h;
continue;
}
++updates;
cout << " # of updates = " << updates << endl;
if (mess->What() == kMESS_OBJECT) {
TH1F *h = (TH1F *)mess->ReadObject(mess->GetClass());
if(use_my_own && !my_h)
{
my_h = new TH1F("my name", h->GetTitle(), h->GetNbinsX(),
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax());
my_h->SetDirectory(0);
}
if(use_my_own)
{
h->Copy(*my_h);
my_h->Draw();
}
else
h->DrawCopy();
c1->Modified();
c1->Update();
delete h; // delete histogram that has been read in
}
else {
printf("*** Unexpected message ***\n");
}
delete mess;
}
// we get here only if we break out of the loop
s0->Close(); // close the socket
}
The client macro:
{
// Open connection to server
TSocket *sock = new TSocket("localhost", 9090);
// Wait till we get the start message
char str[32];
sock->Recv(str, 32);
TH1 *hpx;
// Create the histogram
hpx = new TH1F("hpx","This is the px distribution",100,-4,4);
hpx->SetFillColor(48); // set nice fillcolor
hpx->SetFillStyle(0);
TMessage mess(kMESS_OBJECT);
// Fill histogram randomly
gRandom->SetSeed();
Float_t px;
bool stay_in_loop = true;
while(stay_in_loop)
{
for(int i = 0; i != 100; ++i)
{
px = gRandom->Gaus(0, 1);
hpx->Fill(px);
}
mess.Reset(); // re-use TMessage object
mess.WriteObject(hpx); // write object in message buffer
sock->Send(mess); // send message
gSystem->Sleep(1000); // wait for 1 sec
} // infinite loop
// we get here only if we break out of the loop
sock->Close(); // close the socket
}