netDirectoryServer.cxx File Reference

#include <stdio.h>
#include <assert.h>
#include "netDirectoryServer.h"
#include <TROOT.h>
#include <TClass.h>
#include <TFile.h>
#include <TDirectory.h>
#include <TKey.h>
#include <TFolder.h>
#include <TSocket.h>
#include <TServerSocket.h>
#include <TThread.h>
#include <TMessage.h>
#include <TObjString.h>
#include <TH1.h>
#include <TCutG.h>
#include <deque>
#include <map>
#include <string>
#include "RootLock.h"
Include dependency graph for netDirectoryServer.cxx:

Go to the source code of this file.

Defines

#define THREADRETURN
#define THREADTYPE   void

Functions

static TObject * FollowPath (TObject *container, char *path)
static TObject * FindTopLevelObject (const char *name)
static TObject * TopLevel (char *path, char **opath)
static TObject * FollowPath (char *path)
static void ResetObject (TObject *obj)
static TKey * MakeKey (TObject *obj, int cycle, TDirectory *dir, const char *name=NULL)
static THREADTYPE root_server_thread (void *arg)
static THREADTYPE socket_listener (void *arg)
void VerboseNetDirectoryServer (bool verbose)
void NetDirectoryExport (TDirectory *dir, const char *exportName)
void NetDirectoryExport (TFolder *folder, const char *exportName)
void NetDirectoryExport (TCollection *collection, const char *exportName)
void StartNetDirectoryServer (int port, TDirectory *dir)

Variables

static bool gVerbose = false
static std::deque< std::string > gExports
static std::map< std::string,
std::string > 
gExportNames
static bool gAlreadyRunning = false

Define Documentation

#define THREADRETURN
#define THREADTYPE   void

Definition at line 21 of file netDirectoryServer.cxx.


Function Documentation

static TObject* FindTopLevelObject ( const char *  name  )  [static]

Definition at line 101 of file netDirectoryServer.cxx.

Referenced by root_server_thread(), and TopLevel().

00102 {
00103    TObject *obj = NULL;
00104    //gROOT->GetListOfFiles()->Print();
00105    obj = gROOT->GetListOfFiles()->FindObject(name);
00106    if (obj)
00107       return obj;
00108    obj = gROOT->FindObjectAny(name);
00109    if (obj)
00110       return obj;
00111    return NULL;
00112 }

Here is the caller graph for this function:

static TObject* FollowPath ( char *  path  )  [static]

Definition at line 158 of file netDirectoryServer.cxx.

References FollowPath(), and TopLevel().

00159 {
00160   if (0)
00161     printf("Follow path [%s]\n", path);
00162 
00163   char *s;
00164   TObject *obj = TopLevel(path, &s);
00165 
00166   if (!obj)
00167     return NULL;
00168 
00169   if (!s)
00170     return obj;
00171 
00172   return FollowPath(obj, s);
00173 }

Here is the call graph for this function:

static TObject* FollowPath ( TObject *  container,
char *  path 
) [static]

Definition at line 59 of file netDirectoryServer.cxx.

Referenced by FollowPath(), root_server_thread(), and xroot_server_thread().

00060 {
00061   while (1)
00062     {
00063       if (0)
00064         printf("Follow path [%s] in container %p\n", path, container);
00065 
00066       while (*path == '/')
00067         path++;
00068 
00069       char* s = strchr(path,'/');
00070 
00071       if (s)
00072         *s = 0;
00073 
00074       TObject *obj = NULL;
00075 
00076       if (container->InheritsFrom(TDirectory::Class()))
00077         obj = ((TDirectory*)container)->FindObject(path);
00078       else if (container->InheritsFrom(TFolder::Class()))
00079         obj = ((TFolder*)container)->FindObject(path);
00080       else if (container->InheritsFrom(TCollection::Class()))
00081         obj = ((TCollection*)container)->FindObject(path);
00082       else
00083         {
00084           printf("ERROR: Container \'%s\' of type %s is not a TDirectory, TFolder or TCollection\n", container->GetName(), container->IsA()->GetName());
00085           return NULL;
00086         }
00087 
00088       if (!s)
00089         return obj;
00090 
00091       if (!obj)
00092         return NULL;
00093 
00094       container = obj;
00095 
00096       path = s+1;
00097     }
00098   /* NOT REACHED */
00099 }

Here is the caller graph for this function:

static TKey* MakeKey ( TObject *  obj,
int  cycle,
TDirectory dir,
const char *  name = NULL 
) [static]

Definition at line 206 of file netDirectoryServer.cxx.

Referenced by root_server_thread().

00207 {
00208   static TDirectory* xfile = NULL;
00209   if (!xfile)
00210     xfile = new TFile("/dev/null");
00211 
00212   TClass *xclass = obj->IsA();
00213   
00214   if (xclass->InheritsFrom(TDirectory::Class()))
00215     xclass = TDirectory::Class();
00216   else if (xclass->InheritsFrom(TFolder::Class()))
00217     xclass = TDirectory::Class();
00218   else if (xclass->InheritsFrom(TCollection::Class()))
00219     xclass = TDirectory::Class();
00220 
00221   if (!name)
00222     name = obj->GetName();
00223 
00224   //return new TKey(name, obj->GetTitle(), xclass, cycle, dir);
00225   return new TKey(name, obj->GetTitle(), xclass, 0, xfile);
00226 }

Here is the caller graph for this function:

void NetDirectoryExport ( TCollection *  collection,
const char *  exportName 
)

Definition at line 654 of file netDirectoryServer.cxx.

References gExportNames, gExports, and gVerbose.

00655 {
00656   if (gVerbose)
00657     printf("Export TCollection %p named [%s] of type [%s] as [%s]\n", collection, collection->GetName(), collection->IsA()->GetName(), exportName);
00658 
00659   bool found = false;
00660   for (unsigned int i=0; i<gExports.size(); i++)
00661     {
00662       const char* ename = gExports[i].c_str();
00663       if (strcmp(ename, exportName) == 0)
00664         found = true;
00665     }
00666 
00667   if (!found)
00668     gExports.push_back(exportName);
00669   gExportNames[exportName] = collection->GetName();
00670 }

void NetDirectoryExport ( TFolder *  folder,
const char *  exportName 
)

Definition at line 636 of file netDirectoryServer.cxx.

References gExportNames, gExports, and gVerbose.

00637 {
00638   if (gVerbose)
00639     printf("Export TFolder %p named [%s] of type [%s] as [%s]\n", folder, folder->GetName(), folder->IsA()->GetName(), exportName);
00640 
00641   bool found = false;
00642   for (unsigned int i=0; i<gExports.size(); i++)
00643     {
00644       const char* ename = gExports[i].c_str();
00645       if (strcmp(ename, exportName) == 0)
00646         found = true;
00647     }
00648 
00649   if (!found)
00650     gExports.push_back(exportName);
00651   gExportNames[exportName] = folder->GetName();
00652 }

void NetDirectoryExport ( TDirectory dir,
const char *  exportName 
)

Definition at line 618 of file netDirectoryServer.cxx.

References gExportNames, gExports, and gVerbose.

Referenced by main(), TRootanaEventLoop::OpenRootFile(), StartNetDirectoryServer(), and startRun().

00619 {
00620   if (gVerbose)
00621     printf("Export TDirectory %p named [%s] of type [%s] as [%s]\n", dir, dir->GetName(), dir->IsA()->GetName(), exportName);
00622 
00623   bool found = false;
00624   for (unsigned int i=0; i<gExports.size(); i++)
00625     {
00626       const char* ename = gExports[i].c_str();
00627       if (strcmp(ename, exportName) == 0)
00628         found = true;
00629     }
00630 
00631   if (!found)
00632     gExports.push_back(exportName);
00633   gExportNames[exportName] = dir->GetName();
00634 }

Here is the caller graph for this function:

static void ResetObject ( TObject *  obj  )  [static]

Definition at line 177 of file netDirectoryServer.cxx.

References TDirectory::GetList(), and gVerbose.

Referenced by root_server_thread().

00178 {
00179   assert(obj!=NULL);
00180 
00181   if (gVerbose)
00182     printf("ResetObject object %p name [%s] type [%s]\n", obj, obj->GetName(), obj->IsA()->GetName());
00183 
00184   if (obj->InheritsFrom(TH1::Class()))
00185     {
00186       ((TH1*)obj)->Reset();
00187     }
00188   else if (obj->InheritsFrom(TDirectory::Class()))
00189     {
00190       TDirectory* dir = (TDirectory*)obj;
00191       TList* objs = dir->GetList();
00192 
00193       TIter next = objs;
00194       while(1)
00195         {
00196           TObject *obj = next();
00197           if (obj == NULL)
00198             break;
00199           ResetObject(obj);
00200         }
00201     }
00202 }

Here is the call graph for this function:

Here is the caller graph for this function:

static THREADTYPE root_server_thread ( void *  arg  )  [static]

Definition at line 230 of file netDirectoryServer.cxx.

References FindTopLevelObject(), FollowPath(), TDirectory::GetList(), TDirectory::GetListOfKeys(), gExportNames, gExports, gVerbose, MakeKey(), ResetObject(), THREADRETURN, TopLevel(), and LockRootGuard::Unlock().

00234 {
00235    char request[2560];
00236 
00237    TSocket *sock = (TSocket *) arg;
00238    TMessage message(kMESS_OBJECT);
00239 
00240    do {
00241 
00242       /* close connection if client has disconnected */
00243       int rd = sock->Recv(request, sizeof(request));
00244       if (rd <= 0)
00245         {
00246           if (gVerbose)
00247             fprintf(stderr, "TNetDirectory connection from %s closed\n", sock->GetInetAddress().GetHostName());
00248           sock->Close();
00249           delete sock;
00250           return THREADRETURN;
00251         }
00252 
00253       if (gVerbose)
00254         printf("Request [%s] from %s\n", request, sock->GetInetAddress().GetHostName());
00255 
00256       if (strcmp(request, "GetListOfKeys") == 0)
00257         {
00258           // enumerate top level exported directories
00259 
00260           LockRootGuard lock;
00261           
00262           //printf("Top level exported directories are:\n");
00263           TList* keys = new TList();
00264           
00265           for (unsigned int i=0; i<gExports.size(); i++)
00266             {
00267               const char* ename = gExports[i].c_str();
00268               const char* xname = gExportNames[ename].c_str();
00269 
00270               TObject* obj = FindTopLevelObject(xname);
00271 
00272               if (!obj)
00273                 {
00274                   fprintf(stderr, "GetListOfKeys: Exported name \'%s\' cannot be found!\n", xname);
00275                   continue;
00276                 }
00277 
00278               TKey* key = MakeKey(obj, 1, gROOT, ename);
00279               keys->Add(key);
00280             }
00281           
00282           if (gVerbose)
00283             {
00284               printf("Sending keys %p\n", keys);
00285               keys->Print();
00286             }
00287 
00288           message.Reset(kMESS_OBJECT);
00289           message.WriteObject(keys);
00290           delete keys;
00291           lock.Unlock();
00292           sock->Send(message);
00293         }
00294       else if (strncmp(request, "GetListOfKeys ", 14) == 0)
00295         {
00296           LockRootGuard lock;
00297 
00298           char* dirname = request + 14;
00299 
00300           TObject* obj = FollowPath(dirname);
00301 
00302           if (obj && obj->InheritsFrom(TDirectory::Class()))
00303             {
00304               TDirectory* dir = (TDirectory*)obj;
00305 
00306               //printf("Directory %p\n", dir);
00307               //dir->Print();
00308               
00309               TList* xkeys = dir->GetListOfKeys();
00310               TList* keys = xkeys;
00311               if (!keys)
00312                 keys = new TList();
00313 
00314               //printf("Directory %p keys:\n", dir);
00315               //keys->Print();
00316               
00317               TList* objs = dir->GetList();
00318 
00319               //printf("Directory %p objects:\n", dir);
00320               //objs->Print();
00321               
00322               TIter next = objs;
00323               while(1)
00324                 {
00325                   TObject *obj = next();
00326 
00327                   //printf("object %p\n", obj);
00328 
00329                   if (obj == NULL)
00330                     break;
00331                   
00332                   const char* name      = obj->GetName();
00333                   
00334                   if (!keys->FindObject(name))
00335                     {
00336                       TKey* key = MakeKey(obj, 1, dir);
00337                       keys->Add(key);
00338                     }
00339                 }
00340 
00341               //printf("Sending keys %p\n", keys);
00342               //keys->Print();
00343 
00344               message.Reset(kMESS_OBJECT);
00345               message.WriteObject(keys);
00346               if (keys != xkeys)
00347                 delete keys;
00348             }
00349           else if (obj && obj->InheritsFrom(TFolder::Class()))
00350             {
00351               TFolder* folder = (TFolder*)obj;
00352 
00353               //printf("Folder %p\n", folder);
00354               //folder->Print();
00355 
00356               TIterator *iterator = folder->GetListOfFolders()->MakeIterator();
00357 
00358               TList* keys = new TList();
00359 
00360               while (1)
00361                 {
00362                   TNamed *obj = (TNamed*)iterator->Next();
00363                   if (obj == NULL)
00364                     break;
00365       
00366                   const char* name      = obj->GetName();
00367                   
00368                   if (!keys->FindObject(name))
00369                     {
00370                       TKey* key = MakeKey(obj, 1, gROOT);
00371                       keys->Add(key);
00372                     }
00373                 }
00374               
00375               delete iterator;
00376 
00377               if (gVerbose)
00378                 {
00379                   printf("Sending keys %p\n", keys);
00380                   keys->Print();
00381                 }
00382 
00383               message.Reset(kMESS_OBJECT);
00384               message.WriteObject(keys);
00385               delete keys;
00386             }
00387           else if (obj && obj->InheritsFrom(TCollection::Class()))
00388             {
00389               TCollection* collection = (TCollection*)obj;
00390 
00391               //printf("Collection %p\n", collection);
00392               //collection->Print();
00393 
00394               TIterator *iterator = collection->MakeIterator();
00395 
00396               TList* keys = new TList();
00397 
00398               while (1)
00399                 {
00400                   TNamed *obj = (TNamed*)iterator->Next();
00401                   if (obj == NULL)
00402                     break;
00403       
00404                   const char* name      = obj->GetName();
00405                   
00406                   if (!keys->FindObject(name))
00407                     {
00408                       TKey* key = MakeKey(obj, 1, gROOT);
00409                       keys->Add(key);
00410                     }
00411                 }
00412               
00413               delete iterator;
00414 
00415               if (gVerbose)
00416                 {
00417                   printf("Sending keys %p\n", keys);
00418                   keys->Print();
00419                 }
00420 
00421               message.Reset(kMESS_OBJECT);
00422               message.WriteObject(keys);
00423               delete keys;
00424             }
00425           else if (obj)
00426             {
00427               fprintf(stderr, "netDirectoryServer: ERROR: obj %p name %s, type %s is not a directory!\n", obj, obj->GetName(), obj->IsA()->GetName());
00428               TObjString s("Not a directory");
00429               message.Reset(kMESS_OBJECT);
00430               message.WriteObject(&s);
00431             }
00432           else
00433             {
00434               fprintf(stderr, "netDirectoryServer: ERROR: obj %p not found\n", obj);
00435               TObjString s("Not found");
00436               message.Reset(kMESS_OBJECT);
00437               message.WriteObject(&s);
00438             }
00439               
00440           lock.Unlock();
00441           sock->Send(message);
00442         }
00443       else if (strncmp(request, "FindObjectByName ", 17) == 0)
00444         {
00445           LockRootGuard lock;
00446 
00447           char* top  = request + 17;
00448 
00449           char *s;
00450           TObject *obj = TopLevel(top, &s);
00451 
00452           //printf("toplevel found %p for \'%s\' remaining \'%s\'\n", obj, top, s);
00453 
00454           if (obj && !s)
00455             {
00456               // they requested a top-level object. Give out a fake name
00457 
00458               char str[256];
00459               sprintf(str, "TDirectory %s", obj->GetName());
00460 
00461               for (unsigned int i=0; i<gExports.size(); i++)
00462                 {
00463                   const char* ename = gExports[i].c_str();
00464                   const char* xname = gExportNames[ename].c_str();
00465 
00466                   if (strcmp(xname, obj->GetName()) == 0)
00467                     {
00468                       sprintf(str, "TDirectory %s", ename);
00469                       break;
00470                     }
00471                 }
00472 
00473               obj = new TObjString(str); // FIXME: memory leak!
00474             }
00475           else if (obj)
00476             {
00477               obj = FollowPath(obj, s);
00478             }
00479 
00480           if (obj && obj->InheritsFrom(TDirectory::Class()))
00481             {
00482               char str[256];
00483               sprintf(str, "TDirectory %s", obj->GetName());
00484               obj = new TObjString(str);
00485             }
00486           
00487           if (obj && obj->InheritsFrom(TFolder::Class()))
00488             {
00489               char str[256];
00490               sprintf(str, "TDirectory %s", obj->GetName());
00491               obj = new TObjString(str);
00492             }
00493           
00494           if (obj && obj->InheritsFrom(TCollection::Class()))
00495             {
00496               char str[256];
00497               sprintf(str, "TDirectory %s", obj->GetName());
00498               obj = new TObjString(str);
00499             }
00500           
00501           if (gVerbose)
00502             {
00503               if (obj)
00504                 printf("Sending object %p name \'%s\' class \'%s\'\n", obj, obj->GetName(), obj->IsA()->GetName());
00505               else
00506                 printf("Sending object %p\n", obj);
00507               //obj->Print();
00508             }
00509 
00510           message.Reset(kMESS_OBJECT);
00511           message.WriteObject(obj);
00512           lock.Unlock();
00513           sock->Send(message);
00514         }
00515       else if (strncmp(request, "ResetTH1 ", 9) == 0)
00516         {
00517           LockRootGuard lock;
00518           
00519           char* path = request + 9;
00520 
00521           if (strlen(path) > 1)
00522             {
00523               TObject *obj = FollowPath(path);
00524 
00525               if (obj)
00526                 ResetObject(obj);
00527             }
00528           else
00529             {
00530               for (unsigned int i=0; i<gExports.size(); i++)
00531                 {
00532                   const char* ename = gExports[i].c_str();
00533                   const char* xname = gExportNames[ename].c_str();
00534 
00535                   TObject* obj = FindTopLevelObject(xname);
00536 
00537                   if (!obj)
00538                     {
00539                       fprintf(stderr, "ResetTH1: Exported name \'%s\' cannot be found!\n", xname);
00540                       continue;
00541                     }
00542 
00543                   ResetObject(obj);
00544                 }
00545             }
00546           
00547           TObjString s("Success");
00548 
00549           message.Reset(kMESS_OBJECT);
00550           message.WriteObject(&s);
00551           lock.Unlock();
00552           sock->Send(message);
00553         }
00554       else
00555         {
00556           fprintf(stderr, "netDirectoryServer: Received unknown request \"%s\"\n", request);
00557           LockRootGuard lock;
00558           TObjString s("Unknown request");
00559           message.Reset(kMESS_OBJECT);
00560           message.WriteObject(&s);
00561           lock.Unlock();
00562           sock->Send(message);
00563         }
00564    } while (1);
00565 
00566    return THREADRETURN;
00567 }

Here is the call graph for this function:

static THREADTYPE socket_listener ( void *  arg  )  [static]

Definition at line 571 of file netDirectoryServer.cxx.

References gVerbose, root_server_thread(), and THREADRETURN.

Referenced by StartNetDirectoryServer().

00572 {
00573   // Server loop listening for incoming network connections on specified port.
00574   // Starts a searver_thread for each connection.
00575 
00576   int port = *(int *) arg;
00577   
00578   fprintf(stderr, "NetDirectory server listening on port %d...\n", port);
00579   TServerSocket *lsock = new TServerSocket(port, kTRUE);
00580   
00581   while (1)
00582     {
00583       TSocket *sock = lsock->Accept();
00584       
00585       if (sock==NULL)
00586         {
00587           printf("TNetDirectory server accept() error\n");
00588           break;
00589         }
00590       
00591       if (gVerbose)
00592         fprintf(stderr, "TNetDirectory connection from %s\n", sock->GetInetAddress().GetHostName());
00593       
00594 #if 1
00595       TThread *thread = new TThread("NetDirectoryServer", root_server_thread, sock);
00596       thread->Run();
00597 #else
00598       LPDWORD lpThreadId = 0;
00599       CloseHandle(CreateThread(NULL, 1024, &root_server_thread, sock, 0, lpThreadId));
00600 #endif
00601     }
00602   
00603   return THREADRETURN;
00604 }

Here is the call graph for this function:

Here is the caller graph for this function:

void StartNetDirectoryServer ( int  port,
TDirectory dir 
)

Definition at line 672 of file netDirectoryServer.cxx.

References gAlreadyRunning, NetDirectoryExport(), root_socket_server(), socket_listener(), and StartLockRootTimer().

Referenced by TRootanaEventLoop::ExecuteLoop(), and main().

00673 {
00674   if (dir)
00675     NetDirectoryExport(dir, dir->GetName());
00676 
00677   if (gAlreadyRunning)
00678     return;
00679 
00680   if (port==0)
00681     return;
00682 
00683   gAlreadyRunning = true;
00684 
00685   StartLockRootTimer();
00686 
00687   static int pport = port;
00688 #if 1
00689   TThread *thread = new TThread("NetDirectoryServer", socket_listener, &pport);
00690   thread->Run();
00691 #else
00692   LPDWORD lpThreadId = 0;
00693   CloseHandle(CreateThread(NULL, 1024, &root_socket_server, &pport, 0, lpThreadId));
00694 #endif
00695 }

Here is the call graph for this function:

Here is the caller graph for this function:

static TObject* TopLevel ( char *  path,
char **  opath 
) [static]

Definition at line 114 of file netDirectoryServer.cxx.

References FindTopLevelObject(), gExportNames, and gExports.

Referenced by FollowPath(), and root_server_thread().

00115 {
00116   if (0)
00117     printf("Extract top level object from [%s]\n", path);
00118 
00119   while (*path == '/')
00120     path++;
00121 
00122   char* s = strchr(path,'/');
00123   
00124   if (s)
00125     {
00126       *s = 0;
00127       *opath = s+1;
00128     }
00129   else
00130     {
00131       *opath = NULL;
00132     }
00133 
00134   TObject *obj = NULL;
00135 
00136   for (unsigned int i=0; i<gExports.size(); i++)
00137     {
00138       const char* ename = gExports[i].c_str();
00139       //printf("Compare [%s] and [%s]\n", path, ename);
00140       if (strcmp(path, ename) == 0)
00141         {
00142           const char* xname = gExportNames[ename].c_str();
00143           obj = FindTopLevelObject(xname);
00144           //printf("Lookup of [%s] returned %p\n", xname, obj);
00145           break;
00146         }
00147     }
00148 
00149   if (!obj)
00150     {
00151       printf("ERROR: Top level object \'%s\' not found in exports list\n", path);
00152       return NULL;
00153     }
00154 
00155   return obj;
00156 }

Here is the call graph for this function:

Here is the caller graph for this function:

void VerboseNetDirectoryServer ( bool  verbose  ) 

Definition at line 608 of file netDirectoryServer.cxx.

References gVerbose.

00609 {
00610   gVerbose = verbose;
00611   //gDebugLockRoot = verbose;
00612 }


Variable Documentation

bool gAlreadyRunning = false [static]

Definition at line 616 of file netDirectoryServer.cxx.

Referenced by StartNetDirectoryServer().

std::map<std::string,std::string> gExportNames [static]

Definition at line 55 of file netDirectoryServer.cxx.

Referenced by NetDirectoryExport(), root_server_thread(), and TopLevel().

std::deque<std::string> gExports [static]

Definition at line 54 of file netDirectoryServer.cxx.

Referenced by NetDirectoryExport(), root_server_thread(), and TopLevel().

bool gVerbose = false [static]

Generated on 12 Feb 2016 for ROOT Analyzer by  doxygen 1.6.1