Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TMonitor.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: Fons Rademakers 09/01/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// TMonitor //
15// //
16// This class monitors activity on a number of network sockets. //
17// The actual monitoring is done by TSystem::DispatchOneEvent(). //
18// Typical usage: create a TMonitor object. Register a number of //
19// TSocket objects and call TMonitor::Select(). Select() returns the //
20// socket object which has data waiting. TSocket objects can be added, //
21// removed, (temporary) enabled or disabled. //
22// //
23//////////////////////////////////////////////////////////////////////////
24
25#include "TMonitor.h"
26#include "TSocket.h"
27#include "TList.h"
28#include "TSystem.h"
29#include "TSysEvtHandler.h"
30#include "TTimer.h"
31#include "TError.h"
32
33
34//---- Socket event handler ----------------------------------------------------
35//
36// This utility class is only used by TMonitor.
37//
38
40private:
41 TMonitor *fMonitor; //monitor to which this handler belongs
42 TSocket *fSocket; //socket being handled
43
44public:
45 TSocketHandler(TMonitor *m, TSocket *s, Int_t interest, Bool_t mainloop = kTRUE);
46 Bool_t Notify() override;
47 Bool_t ReadNotify() override { return Notify(); }
48 Bool_t WriteNotify() override { return Notify(); }
49 TSocket *GetSocket() const { return fSocket; }
50};
51
53 Int_t interest, Bool_t mainloop)
54 : TFileHandler(s->GetDescriptor(), interest)
55{
56 //constructor
57 fMonitor = m;
58 fSocket = s;
59
60 if (mainloop)
61 Add();
62}
63
65{
66 //notifier
67 fMonitor->SetReady(fSocket);
68 return kTRUE;
69}
70
71//---- Timeout timer -----------------------------------------------------------
72//
73// This utility class is only used via TMonitor::Select(Int_t timeout)
74//
75
76class TTimeOutTimer : public TTimer {
77private:
78 TMonitor *fMonitor; //monitor to which this timer belongs
79
80public:
82 Bool_t Notify() override;
83};
84
86 : TTimer(ms, kTRUE)
87{
88 //constructor
89 fMonitor = m;
90 gSystem->AddTimer(this);
91}
92
94{
95 //notifier
96 fMonitor->SetReady((TSocket *)-1);
97 Remove(); // one shot only
98 return kTRUE;
99}
100//------------------------------------------------------------------------------
101
102
103
104////////////////////////////////////////////////////////////////////////////////
105/// Create a monitor object. If mainloop is true the monitoring will be
106/// done in the main event loop.
107
109{
111
112 fActive = new TList;
113 fDeActive = new TList;
114 fMainLoop = mainloop;
116 fReady = 0;
117}
118
119////////////////////////////////////////////////////////////////////////////////
120/// Copy constructor
121
123{
124 TSocketHandler *sh = 0;
125 // Active list
126 fActive = new TList;
127 TIter nxa(m.fActive);
128 while ((sh = (TSocketHandler *)nxa())) {
129 Int_t mask = 0;
130 if (sh->HasReadInterest()) mask |= 0x1;
131 if (sh->HasWriteInterest()) mask |= 0x2;
132 fActive->Add(new TSocketHandler(this, sh->GetSocket(), mask, m.fMainLoop));
133 }
134 // Deactive list
135 fDeActive = new TList;
136 TIter nxd(m.fDeActive);
137 while ((sh = (TSocketHandler *)nxd())) {
138 Int_t mask = 0;
139 if (sh->HasReadInterest()) mask |= 0x1;
140 if (sh->HasWriteInterest()) mask |= 0x2;
141 fDeActive->Add(new TSocketHandler(this, sh->GetSocket(), mask, m.fMainLoop));
142 }
143 // Other members
144 fMainLoop = m.fMainLoop;
145 fInterrupt = m.fInterrupt;
146 fReady = 0;
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// Cleanup the monitor object. Does not delete sockets being monitored.
151
153{
154 fActive->Delete();
156
157 fDeActive->Delete();
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Add socket to the monitor's active list. If interest=kRead then we
163/// want to monitor the socket for read readiness, if interest=kWrite
164/// then we monitor the socket for write readiness, if interest=kRead|kWrite
165/// then we monitor both read and write readiness.
166
167void TMonitor::Add(TSocket *sock, Int_t interest)
168{
169 fActive->Add(new TSocketHandler(this, sock, interest, fMainLoop));
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Set interest mask for socket sock to interest. If the socket is not
174/// in the active list move it or add it there.
175/// If interest=kRead then we want to monitor the socket for read readiness,
176/// if interest=kWrite then we monitor the socket for write readiness,
177/// if interest=kRead|kWrite then we monitor both read and write readiness.
178
180{
181 TSocketHandler *s = 0;
182
183 if (!interest)
184 interest = kRead;
185
186 // Check first the activated list ...
187 TIter next(fActive);
188 while ((s = (TSocketHandler *) next())) {
189 if (sock == s->GetSocket()) {
190 s->SetInterest(interest);
191 return;
192 }
193 }
194
195 // Check now the deactivated list ...
196 TIter next1(fDeActive);
197 while ((s = (TSocketHandler *) next1())) {
198 if (sock == s->GetSocket()) {
199 fDeActive->Remove(s);
200 fActive->Add(s);
201 s->SetInterest(interest);
202 return;
203 }
204 }
205
206 // The socket is not in our lists: just add it
207 fActive->Add(new TSocketHandler(this, sock, interest, fMainLoop));
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Remove a socket from the monitor.
212
214{
215 TIter next(fActive);
217
218 while ((s = (TSocketHandler *) next())) {
219 if (sock == s->GetSocket()) {
220 fActive->Remove(s);
221 delete s;
222 return;
223 }
224 }
225
226 TIter next1(fDeActive);
227
228 while ((s = (TSocketHandler *) next1())) {
229 if (sock == s->GetSocket()) {
230 fDeActive->Remove(s);
231 delete s;
232 return;
233 }
234 }
235}
236
237////////////////////////////////////////////////////////////////////////////////
238/// Remove all sockets from the monitor.
239
241{
242 fActive->Delete();
243 fDeActive->Delete();
244}
245
246////////////////////////////////////////////////////////////////////////////////
247/// Activate a de-activated socket.
248
250{
251 TIter next(fDeActive);
253
254 while ((s = (TSocketHandler *) next())) {
255 if (sock == s->GetSocket()) {
256 fDeActive->Remove(s);
257 fActive->Add(s);
258 s->Add();
259 return;
260 }
261 }
262}
263
264////////////////////////////////////////////////////////////////////////////////
265/// Activate all de-activated sockets.
266
268{
269 TIter next(fDeActive);
271
272 while ((s = (TSocketHandler *) next())) {
273 fActive->Add(s);
274 s->Add();
275 }
276 fDeActive->Clear();
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// De-activate a socket.
282
284{
285 TIter next(fActive);
287
288 while ((s = (TSocketHandler *) next())) {
289 if (sock == s->GetSocket()) {
290 fActive->Remove(s);
291 fDeActive->Add(s);
292 s->Remove();
293 return;
294 }
295 }
296}
297
298////////////////////////////////////////////////////////////////////////////////
299/// De-activate all activated sockets.
300
302{
303 TIter next(fActive);
305
306 while ((s = (TSocketHandler *) next())) {
307 fDeActive->Add(s);
308 s->Remove();
309 }
310 fActive->Clear();
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Return pointer to socket for which an event is waiting.
316/// Select can be interrupt by a call to Interrupt() (e.g. connected with a
317/// Ctrl-C handler); a call to ResetInterrupt() before Select() is advisable
318/// in such a case.
319/// Return 0 in case of error.
320
322{
323 fReady = 0;
324
325 while (!fReady && !fInterrupt)
326 gSystem->InnerLoop();
327
328 // Notify interrupts
329 if (fInterrupt) {
331 fReady = 0;
332 Info("Select","*** interrupt occurred ***");
333 }
334
335 return fReady;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Return pointer to socket for which an event is waiting.
340/// Wait a maximum of timeout milliseconds.
341/// If return is due to timeout it returns (TSocket *)-1.
342/// Select() can be interrupt by a call to Interrupt() (e.g. connected with a
343/// Ctrl-C handler); a call to ResetInterrupt() before Select() is advisable
344/// in such a case.
345/// Return 0 in case of any other error situation.
346
348{
349 if (timeout < 0)
350 return TMonitor::Select();
351
352 fReady = 0;
353
354 TTimeOutTimer t(this, timeout);
355
356 while (!fReady && !fInterrupt)
357 gSystem->InnerLoop();
358
359 // Notify interrupts
360 if (fInterrupt) {
362 fReady = 0;
363 Info("Select","*** interrupt occurred ***");
364 }
365
366 return fReady;
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Return numbers of sockets that are ready for reading or writing.
371/// Wait a maximum of timeout milliseconds.
372/// Return 0 if timed-out. Return < 0 in case of error.
373/// If rdready and/or wrready are not 0, the lists of sockets with
374/// something to read and/or write are also returned.
375
376Int_t TMonitor::Select(TList *rdready, TList *wrready, Long_t timeout)
377{
378 Int_t nr = -2;
379
380 TSocketHandler *h = 0;
381 Int_t ns = fActive->GetSize();
382 if (ns == 1) {
383 // Avoid additional loops inside
384 h = (TSocketHandler *)fActive->First();
385 nr = gSystem->Select((TFileHandler *)h, timeout);
386 } else if (ns > 1) {
387 nr = gSystem->Select(fActive, timeout);
388 }
389
390 if (nr > 0 && (rdready || wrready)) {
391 // Clear the lists
392 if (rdready)
393 rdready->Clear();
394 if (wrready)
395 wrready->Clear();
396 // Got a file descriptor
397 if (!h) {
398 TIter next(fActive);
399 while ((h = (TSocketHandler *)next())) {
400 if (rdready && h->IsReadReady())
401 rdready->Add(h->GetSocket());
402 if (wrready && h->IsWriteReady())
403 wrready->Add(h->GetSocket());
404 }
405 } else {
406 if (rdready && h->IsReadReady())
407 rdready->Add(h->GetSocket());
408 if (wrready && h->IsWriteReady())
409 wrready->Add(h->GetSocket());
410 }
411 }
412
413 return nr;
414}
415
416////////////////////////////////////////////////////////////////////////////////
417/// Called by TSocketHandler::Notify() to signal which socket is ready
418/// to be read or written. User should not call this routine. The ready
419/// socket will be returned via the Select() user function.
420/// The Ready(TSocket *sock) signal is emitted.
421
423{
424 fReady = sock;
425 Ready(fReady);
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Return number of sockets in the active list. If timeout > 0, remove from
430/// the list those sockets which did not have any activity since timeout
431/// millisecs. If timeout = 0, then reset activity timestamp on all active
432/// sockets. This time out is typically used if GetActive() is used to see
433/// how many remotes still need to send something. If they pass the timeout
434/// they will be skipped and GetActive() will return 0 and the loop can be
435/// exited.
436
438{
439 if (timeout >= 0) {
440 TIter next(fActive);
442 if (timeout > 0) {
443 TTimeStamp now;
444 while ((s = (TSocketHandler *) next())) {
445 TSocket *xs = s->GetSocket();
446 TTimeStamp ts = xs->GetLastUsage();
447 Long_t dt = (Long_t)(now.GetSec() - ts.GetSec()) * 1000 +
448 (Long_t)(now.GetNanoSec() - ts.GetNanoSec()) / 1000000 ;
449 if (dt > timeout) {
450 Info("GetActive", "socket: %p: %s:%d did not show any activity"
451 " during the last %ld millisecs: deactivating",
452 xs, xs->GetInetAddress().GetHostName(),
453 xs->GetInetAddress().GetPort(), timeout);
454 fActive->Remove(s);
455 fDeActive->Add(s);
456 s->Remove();
457 }
458 }
459 } else if (timeout == 0) {
460 // Reset time stamps
461 while ((s = (TSocketHandler *) next())) {
462 s->GetSocket()->Touch();
463 }
464 }
465 }
466 return fActive->GetSize();
467}
468
469////////////////////////////////////////////////////////////////////////////////
470/// Return number of sockets in the de-active list.
471
473{
474 return fDeActive->GetSize();
475}
476
477////////////////////////////////////////////////////////////////////////////////
478/// Check if socket 's' is in the active list. Avoids the duplication
479/// of active list via TMonitor::GetListOfActives().
480
482{
483 TIter next(fActive);
484 while (TSocketHandler *h = (TSocketHandler*) next())
485 if (sock == h->GetSocket())
486 return kTRUE;
487
488 // Not found
489 return kFALSE;
490}
491
492////////////////////////////////////////////////////////////////////////////////
493/// Returns a list with all active sockets. This list must be deleted
494/// by the user. DO NOT call Delete() on this list as it will delete
495/// the sockets that are still being used by the monitor.
496
498{
499 TList *list = new TList;
500
501 TIter next(fActive);
502
503 while (TSocketHandler *h = (TSocketHandler*) next())
504 list->Add(h->GetSocket());
505
506 return list;
507}
508
509////////////////////////////////////////////////////////////////////////////////
510/// Returns a list with all de-active sockets. This list must be deleted
511/// by the user. DO NOT call Delete() on this list as it will delete
512/// the sockets that are still being used by the monitor.
513
515{
516 TList *list = new TList;
517
518 TIter next(fDeActive);
519
520 while (TSocketHandler *h = (TSocketHandler*) next())
521 list->Add(h->GetSocket());
522
523 return list;
524}
525
526////////////////////////////////////////////////////////////////////////////////
527/// Emit signal when some socket is ready
528
530{
531 Emit("Ready(TSocket*)", (Longptr_t)sock);
532}
#define SafeDelete(p)
Definition RConfig.hxx:525
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
long Longptr_t
Integer large enough to hold a pointer (platform-dependent).
Definition RtypesCore.h:89
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
externTSystem * gSystem
Definition TSystem.h:582
virtual void SetInterest(Int_t mask)
Set interest mask to 'mask'.
virtual Bool_t HasReadInterest()
True if handler is interested in read events.
void Remove() override
Remove file event handler from system file handler list.
virtual Bool_t HasWriteInterest()
True if handler is interested in write events.
void Add() override
Add file event handler to system file handler list.
Int_t GetPort() const
const char * GetHostName() const
A doubly linked list.
Definition TList.h:38
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:532
void Add(TObject *obj) override
Definition TList.h:81
Bool_t fInterrupt
Definition TMonitor.h:48
friend class TTimeOutTimer
Definition TMonitor.h:39
virtual void Ready(TSocket *sock)
Emit signal when some socket is ready.
Definition TMonitor.cxx:529
void SetReady(TSocket *sock)
Called by TSocketHandler::Notify() to signal which socket is ready to be read or written.
Definition TMonitor.cxx:422
virtual void SetInterest(TSocket *sock, Int_t interest=kRead)
Set interest mask for socket sock to interest.
Definition TMonitor.cxx:179
TList * fDeActive
Definition TMonitor.h:45
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition TMonitor.cxx:240
virtual void ActivateAll()
Activate all de-activated sockets.
Definition TMonitor.cxx:267
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition TMonitor.cxx:321
friend class TSocketHandler
Definition TMonitor.h:38
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition TMonitor.cxx:249
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition TMonitor.cxx:167
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition TMonitor.cxx:437
TMonitor(Bool_t mainloop=kTRUE)
Create a monitor object.
Definition TMonitor.cxx:108
TList * fActive
Definition TMonitor.h:44
virtual ~TMonitor()
Cleanup the monitor object. Does not delete sockets being monitored.
Definition TMonitor.cxx:152
virtual void DeActivateAll()
De-activate all activated sockets.
Definition TMonitor.cxx:301
TSocket * fReady
Definition TMonitor.h:46
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition TMonitor.cxx:283
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition TMonitor.cxx:497
TList * GetListOfDeActives() const
Returns a list with all de-active sockets.
Definition TMonitor.cxx:514
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition TMonitor.cxx:213
Bool_t fMainLoop
Definition TMonitor.h:47
Bool_t IsActive(TSocket *s) const
Check if socket 's' is in the active list.
Definition TMonitor.cxx:481
Int_t GetDeActive() const
Return number of sockets in the de-active list.
Definition TMonitor.cxx:472
TObject()
TObject constructor.
Definition TObject.h:259
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1072
TQObject(const TQObject &)=delete
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition TQObject.h:164
Bool_t ReadNotify() override
Notify when something can be read from the descriptor associated with this handler.
Definition TMonitor.cxx:47
TSocketHandler(TMonitor *m, TSocket *s, Int_t interest, Bool_t mainloop=kTRUE)
Definition TMonitor.cxx:52
TSocket * GetSocket() const
Definition TMonitor.cxx:49
Bool_t Notify() override
Notify when event occurred on descriptor associated with this handler.
Definition TMonitor.cxx:64
TMonitor * fMonitor
Definition TMonitor.cxx:41
Bool_t WriteNotify() override
Notify when something can be written to the descriptor associated with this handler.
Definition TMonitor.cxx:48
TSocket * fSocket
Definition TMonitor.cxx:42
This class implements client sockets.
Definition TSocket.h:39
TTimeStamp GetLastUsage()
Definition TSocket.h:129
void Touch()
Definition TSocket.h:155
TInetAddress GetInetAddress() const
Definition TSocket.h:114
TMonitor * fMonitor
Definition TMonitor.cxx:78
TTimeOutTimer(TMonitor *m, Long_t ms)
Definition TMonitor.cxx:85
Bool_t Notify() override
This method must be overridden to handle object notification (the base implementation is no-op).
Definition TMonitor.cxx:93
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition TTimeStamp.h:45
time_t GetSec() const
Definition TTimeStamp.h:109
Int_t GetNanoSec() const
Definition TTimeStamp.h:110
void Remove() override
Definition TTimer.h:86
TTimer(const TTimer &)=delete
TMarker m
Definition textangle.C:8