00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <stdint.h>
00015 #include <assert.h>
00016
00017 #include "midasServer.h"
00018
00019
00020
00021 #include <TROOT.h>
00022 #include <TSemaphore.h>
00023 #include <TFolder.h>
00024 #include <TSocket.h>
00025 #include <TServerSocket.h>
00026 #include <TThread.h>
00027 #include <TMessage.h>
00028 #include <TObjString.h>
00029 #include <TObjArray.h>
00030 #include <TH1.h>
00031 #include <TCutG.h>
00032
00033 #include "RootLock.h"
00034
00035 static bool gVerbose = false;
00036
00037 void VerboseMidasServer(bool verbose)
00038 {
00039 fprintf(stderr, "VerboseMidasServer: change verbose level from %d to %d\n", gVerbose, verbose);
00040 gVerbose = verbose;
00041 }
00042
00043
00044
00045 #include <map>
00046 #include <string>
00047
00048
00049 #define XPOINTER_T uint32_t
00050
00051 static std::map<XPOINTER_T,std::string> gPointers;
00052 static std::map<std::string,XPOINTER_T> gRevPointers;
00053 static XPOINTER_T gLastPointer = 0;
00054
00055 TFolder *ReadFolderPointer(TSocket * fSocket)
00056 {
00057
00058 TMessage *m = 0;
00059 fSocket->Recv(m);
00060 XPOINTER_T p;
00061 *m >> p;
00062
00063 const char* name = gPointers[p].c_str();
00064
00065 if (gVerbose)
00066 printf("converted %d to \'%s\'\n", p, name);
00067
00068 TObject* obj = gROOT->FindObjectAny(name);
00069
00070 if (!obj)
00071 obj = gManaHistosFolder;
00072
00073 return (TFolder*) obj;
00074 }
00075
00076
00077
00078 void root_server_thread(void *arg)
00079
00080
00081
00082 {
00083 char request[256];
00084
00085 TSocket *sock = (TSocket *) arg;
00086 TMessage message(kMESS_OBJECT);
00087
00088 do {
00089
00090
00091 int rd = sock->Recv(request, sizeof(request));
00092 if (rd <= 0) {
00093
00094 sock->Close();
00095 delete sock;
00096 return;
00097 }
00098
00099 if (gVerbose)
00100 printf("Request %s\n", request);
00101
00102 if (strcmp(request, "GetListOfFolders") == 0) {
00103
00104 LockRootGuard lock;
00105
00106 TFolder *folder = ReadFolderPointer(sock);
00107 if (folder == NULL) {
00108 message.Reset(kMESS_OBJECT);
00109 message.WriteObject(NULL);
00110 lock.Unlock();
00111 sock->Send(message);
00112 continue;
00113 }
00114
00115 TObject *obj;
00116 TObjArray *names = new TObjArray(100);
00117
00118 TCollection *folders = folder->GetListOfFolders();
00119 TIterator *iterFolders = folders->MakeIterator();
00120 while ((obj = iterFolders->Next()) != NULL)
00121 names->Add(new TObjString(obj->GetName()));
00122
00123
00124 message.Reset(kMESS_OBJECT);
00125 message.WriteObject(names);
00126 sock->Send(message);
00127
00128 for (int i = 0; i < names->GetLast() + 1; i++)
00129 delete(TObjString *) names->At(i);
00130
00131 delete names;
00132
00133 } else if (strncmp(request, "FindObject", 10) == 0) {
00134
00135 LockRootGuard lock;
00136
00137 TFolder *folder = ReadFolderPointer(sock);
00138
00139
00140 TObject *obj;
00141 if (strncmp(request + 10, "Any", 3) == 0)
00142 obj = folder->FindObjectAny(request + 14);
00143 else
00144 obj = folder->FindObject(request + 11);
00145
00146
00147 if (!obj)
00148 sock->Send("Error");
00149 else {
00150 message.Reset(kMESS_OBJECT);
00151 message.WriteObject(obj);
00152
00153 lock.Unlock();
00154 sock->Send(message);
00155 }
00156
00157 } else if (strncmp(request, "FindFullPathName", 16) == 0) {
00158
00159 LockRootGuard lock;
00160
00161 TFolder *folder = ReadFolderPointer(sock);
00162
00163
00164 const char *path = folder->FindFullPathName(request + 17);
00165
00166
00167 if (!path) {
00168 sock->Send("Error");
00169 } else {
00170 TObjString *obj = new TObjString(path);
00171 message.Reset(kMESS_OBJECT);
00172 message.WriteObject(obj);
00173 lock.Unlock();
00174 sock->Send(message);
00175 delete obj;
00176 }
00177
00178 } else if (strncmp(request, "GetPointer", 10) == 0) {
00179
00180
00181 XPOINTER_T p = 0;
00182 TObject *obj = gROOT->FindObjectAny(request + 11);
00183
00184
00185 message.Reset(kMESS_ANY);
00186
00187 if (obj)
00188 {
00189 const char* name = obj->GetName();
00190 p = gRevPointers[name];
00191 if (p==0)
00192 {
00193 p = ++gLastPointer;
00194 gPointers[p] = name;
00195 gRevPointers[name] = p;
00196 }
00197
00198 if (gVerbose)
00199 printf("give %d for \'%s\'\n", p, name);
00200 }
00201
00202 message << p;
00203 sock->Send(message);
00204
00205 } else if (strncmp(request, "Command", 7) == 0) {
00206 char objName[100], method[100];
00207 sock->Recv(objName, sizeof(objName));
00208 sock->Recv(method, sizeof(method));
00209
00210 LockRootGuard lock;
00211
00212 TObject *object = gROOT->FindObjectAny(objName);
00213 if (object && object->InheritsFrom(TH1::Class())
00214 && strcmp(method, "Reset") == 0)
00215 static_cast < TH1 * >(object)->Reset();
00216
00217 } else if (strncmp(request, "SetCut", 6) == 0) {
00218
00219
00220 char name[256];
00221 sock->Recv(name, sizeof(name));
00222
00223 LockRootGuard lock;
00224
00225 TCutG *cut = (TCutG *) gManaHistosFolder->FindObjectAny(name);
00226
00227 TMessage *m = 0;
00228 sock->Recv(m);
00229 TCutG *newc = ((TCutG *) m->ReadObject(m->GetClass()));
00230
00231 if (cut) {
00232 fprintf(stderr, "root server thread: changing cut %s\n", newc->GetName());
00233 newc->TAttMarker::Copy(*cut);
00234 newc->TAttFill::Copy(*cut);
00235 newc->TAttLine::Copy(*cut);
00236 newc->TNamed::Copy(*cut);
00237 cut->Set(newc->GetN());
00238 for (int i = 0; i < cut->GetN(); ++i) {
00239 cut->SetPoint(i, newc->GetX()[i], newc->GetY()[i]);
00240 }
00241 } else {
00242 fprintf(stderr, "root server thread: ignoring receipt of unknown cut \'%s\'\n",
00243 newc->GetName());
00244 }
00245 delete newc;
00246
00247 } else {
00248 fprintf(stderr, "midasServer: Received unknown request \"%s\"\n", request);
00249 }
00250
00251 } while (1);
00252 }
00253
00254
00255
00256 void root_socket_server(void *arg)
00257 {
00258
00259
00260 int port;
00261
00262 port = *(int *) arg;
00263
00264 printf("MIDAS ROOT server listening on port %d...\n", port);
00265 TServerSocket *lsock = new TServerSocket(port, kTRUE);
00266
00267 do {
00268 TSocket *sock = lsock->Accept();
00269
00270 if (sock==NULL) {
00271 fprintf(stderr, "MIDAS ROOT server accept() error\n");
00272 break;
00273 }
00274
00275
00276
00277 TThread *thread = new TThread("Server", root_server_thread, (void*)sock);
00278 thread->Run();
00279 #if 0
00280 LPDWORD lpThreadId = 0;
00281 CloseHandle(CreateThread(NULL, 1024, &root_server_thread, sock, 0, lpThreadId));
00282 #endif
00283 } while (1);
00284 }
00285
00286
00287
00288 TFolder* gManaHistosFolder = NULL;
00289
00290 void StartMidasServer(int port)
00291 {
00292
00293 gManaHistosFolder = gROOT->GetRootFolder()->AddFolder("histos", "MIDAS Analyzer Histograms");
00294 gROOT->GetListOfBrowsables()->Add(gManaHistosFolder, "histos");
00295
00296 StartLockRootTimer();
00297
00298 static int pport = port;
00299
00300 TThread *thread = new TThread("server_loop", root_socket_server, (void*)&pport);
00301 thread->Run();
00302
00303 #if 0
00304 LPDWORD lpThreadId = 0;
00305 CloseHandle(CreateThread(NULL, 1024, &root_socket_server, &pport, 0, lpThreadId));
00306 #endif
00307 }
00308
00309