ROOTANA
midasServer.cxx
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: mana.c
4  Created by: Stefan Ritt
5 
6  Contents: The system part of the MIDAS analyzer. Has to be
7  linked with analyze.c to form a complete analyzer
8 
9  $Id$
10 
11 \********************************************************************/
12 
13 #include <stdio.h>
14 #include <stdint.h>
15 #include <assert.h>
16 
17 #include "midasServer.h"
18 
19 /*==== ROOT socket histo server ====================================*/
20 
21 #include <TROOT.h>
22 #include <TSemaphore.h>
23 #include <TFolder.h>
24 #include <TSocket.h>
25 #include <TServerSocket.h>
26 #include <TThread.h>
27 #include <TMessage.h>
28 #include <TObjString.h>
29 #include <TObjArray.h>
30 #include <TH1.h>
31 #include <TCutG.h>
32 
33 #include "RootLock.h"
34 
35 static bool gVerbose = false;
36 
37 void VerboseMidasServer(bool verbose)
38 {
39  fprintf(stderr, "VerboseMidasServer: change verbose level from %d to %d\n", gVerbose, verbose);
40  gVerbose = verbose;
41 }
42 
43 /*------------------------------------------------------------------*/
44 
45 #include <map>
46 #include <string>
47 
48 //#define XPOINTER_T uint64_t
49 #define XPOINTER_T uint32_t
50 
51 static std::map<XPOINTER_T,std::string> gPointers;
52 static std::map<std::string,XPOINTER_T> gRevPointers;
54 
55 TFolder *ReadFolderPointer(TSocket * fSocket)
56 {
57  //read pointer to current folder
58  TMessage *m = 0;
59  fSocket->Recv(m);
60  XPOINTER_T p;
61  *m >> p;
62 
63  const char* name = gPointers[p].c_str();
64 
65  if (gVerbose)
66  printf("converted %d to \'%s\'\n", p, name);
67 
68  TObject* obj = gROOT->FindObjectAny(name);
69 
70  if (!obj)
71  obj = gManaHistosFolder;
72 
73  return (TFolder*) obj;
74 }
75 
76 /*------------------------------------------------------------------*/
77 
78 void root_server_thread(void *arg)
79 /*
80  Serve histograms over TCP/IP socket link
81 */
82 {
83  char request[256];
84 
85  TSocket *sock = (TSocket *) arg;
86  TMessage message(kMESS_OBJECT);
87 
88  do {
89 
90  /* close connection if client has disconnected */
91  int rd = sock->Recv(request, sizeof(request));
92  if (rd <= 0) {
93  // printf("Closed connection to %s\n", sock->GetInetAddress().GetHostName());
94  sock->Close();
95  delete sock;
96  return;
97  }
98 
99  if (gVerbose)
100  printf("Request %s\n", request);
101 
102  if (strcmp(request, "GetListOfFolders") == 0) {
103 
104  LockRootGuard lock;
105 
106  TFolder *folder = ReadFolderPointer(sock);
107  if (folder == NULL) {
108  message.Reset(kMESS_OBJECT);
109  message.WriteObject(NULL);
110  lock.Unlock();
111  sock->Send(message);
112  continue;
113  }
114  //get folder names
115  TObject *obj;
116  TObjArray *names = new TObjArray(100);
117 
118  TCollection *folders = folder->GetListOfFolders();
119  TIterator *iterFolders = folders->MakeIterator();
120  while ((obj = iterFolders->Next()) != NULL)
121  names->Add(new TObjString(obj->GetName()));
122 
123  //write folder names
124  message.Reset(kMESS_OBJECT);
125  message.WriteObject(names);
126  sock->Send(message);
127 
128  for (int i = 0; i < names->GetLast() + 1; i++)
129  delete(TObjString *) names->At(i);
130 
131  delete names;
132 
133  } else if (strncmp(request, "FindObject", 10) == 0) {
134 
135  LockRootGuard lock;
136 
137  TFolder *folder = ReadFolderPointer(sock);
138 
139  //get object
140  TObject *obj;
141  if (strncmp(request + 10, "Any", 3) == 0)
142  obj = folder->FindObjectAny(request + 14);
143  else
144  obj = folder->FindObject(request + 11);
145 
146  //write object
147  if (!obj)
148  sock->Send("Error");
149  else {
150  message.Reset(kMESS_OBJECT);
151  message.WriteObject(obj);
152 
153  lock.Unlock();
154  sock->Send(message);
155  }
156 
157  } else if (strncmp(request, "FindFullPathName", 16) == 0) {
158 
159  LockRootGuard lock;
160 
161  TFolder *folder = ReadFolderPointer(sock);
162 
163  //find path
164  const char *path = folder->FindFullPathName(request + 17);
165 
166  //write path
167  if (!path) {
168  sock->Send("Error");
169  } else {
170  TObjString *obj = new TObjString(path);
171  message.Reset(kMESS_OBJECT);
172  message.WriteObject(obj);
173  lock.Unlock();
174  sock->Send(message);
175  delete obj;
176  }
177 
178  } else if (strncmp(request, "GetPointer", 10) == 0) {
179 
180  //find object
181  XPOINTER_T p = 0;
182  TObject *obj = gROOT->FindObjectAny(request + 11);
183 
184  //write pointer
185  message.Reset(kMESS_ANY);
186 
187  if (obj)
188  {
189  const char* name = obj->GetName();
190  p = gRevPointers[name];
191  if (p==0)
192  {
193  p = ++gLastPointer;
194  gPointers[p] = name;
195  gRevPointers[name] = p;
196  }
197 
198  if (gVerbose)
199  printf("give %d for \'%s\'\n", p, name);
200  }
201 
202  message << p;
203  sock->Send(message);
204 
205  } else if (strncmp(request, "Command", 7) == 0) {
206  char objName[100], method[100];
207  sock->Recv(objName, sizeof(objName));
208  sock->Recv(method, sizeof(method));
209 
210  LockRootGuard lock;
211 
212  TObject *object = gROOT->FindObjectAny(objName);
213  if (object && object->InheritsFrom(TH1::Class())
214  && strcmp(method, "Reset") == 0)
215  static_cast < TH1 * >(object)->Reset();
216 
217  } else if (strncmp(request, "SetCut", 6) == 0) {
218 
219  //read new settings for a cut
220  char name[256];
221  sock->Recv(name, sizeof(name));
222 
223  LockRootGuard lock;
224 
225  TCutG *cut = (TCutG *) gManaHistosFolder->FindObjectAny(name);
226 
227  TMessage *m = 0;
228  sock->Recv(m);
229  TCutG *newc = ((TCutG *) m->ReadObject(m->GetClass()));
230 
231  if (cut) {
232  fprintf(stderr, "root server thread: changing cut %s\n", newc->GetName());
233  newc->TAttMarker::Copy(*cut);
234  newc->TAttFill::Copy(*cut);
235  newc->TAttLine::Copy(*cut);
236  newc->TNamed::Copy(*cut);
237  cut->Set(newc->GetN());
238  for (int i = 0; i < cut->GetN(); ++i) {
239  cut->SetPoint(i, newc->GetX()[i], newc->GetY()[i]);
240  }
241  } else {
242  fprintf(stderr, "root server thread: ignoring receipt of unknown cut \'%s\'\n",
243  newc->GetName());
244  }
245  delete newc;
246 
247  } else {
248  fprintf(stderr, "midasServer: Received unknown request \"%s\"\n", request);
249  }
250 
251  } while (1);
252 }
253 
254 /*------------------------------------------------------------------*/
255 
256 void root_socket_server(void *arg)
257 {
258 // Server loop listening for incoming network connections on specified port.
259 // Starts a searver_thread for each connection.
260  int port;
261 
262  port = *(int *) arg;
263 
264  printf("MIDAS ROOT server listening on port %d...\n", port);
265  TServerSocket *lsock = new TServerSocket(port, kTRUE);
266 
267  do {
268  TSocket *sock = lsock->Accept();
269 
270  if (sock==NULL) {
271  fprintf(stderr, "MIDAS ROOT server accept() error\n");
272  break;
273  }
274 
275  // printf("Established connection to %s\n", sock->GetInetAddress().GetHostName());
276 
277  TThread *thread = new TThread("Server", root_server_thread, (void*)sock);
278  thread->Run();
279 #if 0
280  LPDWORD lpThreadId = 0;
281  CloseHandle(CreateThread(NULL, 1024, &root_server_thread, sock, 0, lpThreadId));
282 #endif
283  } while (1);
284 }
285 
286 /*------------------------------------------------------------------*/
287 
288 TFolder* gManaHistosFolder = NULL;
289 
290 void StartMidasServer(int port)
291 {
292  /* create the folder for analyzer histograms */
293  gManaHistosFolder = gROOT->GetRootFolder()->AddFolder("histos", "MIDAS Analyzer Histograms");
294  gROOT->GetListOfBrowsables()->Add(gManaHistosFolder, "histos");
295 
297 
298  static int pport = port;
299 
300  TThread *thread = new TThread("server_loop", root_socket_server, (void*)&pport);
301  thread->Run();
302 
303 #if 0
304  LPDWORD lpThreadId = 0;
305  CloseHandle(CreateThread(NULL, 1024, &root_socket_server, &pport, 0, lpThreadId));
306 #endif
307 }
308 
309 // end
void StartLockRootTimer(int period_msec=100)
Definition: RootLock.cxx:115
static std::map< XPOINTER_T, std::string > gPointers
Definition: midasServer.cxx:51
void VerboseMidasServer(bool verbose)
Definition: midasServer.cxx:37
#define XPOINTER_T
Definition: midasServer.cxx:49
static std::map< std::string, XPOINTER_T > gRevPointers
Definition: midasServer.cxx:52
TFolder * ReadFolderPointer(TSocket *fSocket)
Definition: midasServer.cxx:55
static bool gVerbose
Definition: midasServer.cxx:35
TFolder * gManaHistosFolder
static XPOINTER_T gLastPointer
Definition: midasServer.cxx:53
void root_socket_server(void *arg)
void StartMidasServer(int port)
void root_server_thread(void *arg)
Definition: midasServer.cxx:78
void Unlock()
Definition: RootLock.cxx:53