#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"
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 THREADRETURN |
Definition at line 20 of file netDirectoryServer.cxx.
Referenced by root_server_thread(), socket_listener(), xroot_server_thread(), and xsocket_listener().
#define THREADTYPE void |
Definition at line 21 of file netDirectoryServer.cxx.
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
void VerboseNetDirectoryServer | ( | bool | verbose | ) |
Definition at line 608 of file netDirectoryServer.cxx.
References gVerbose.
00609 { 00610 gVerbose = verbose; 00611 //gDebugLockRoot = verbose; 00612 }
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] |
Definition at line 52 of file netDirectoryServer.cxx.
Referenced by NetDirectoryExport(), ResetObject(), root_server_thread(), socket_listener(), and VerboseNetDirectoryServer().