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
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
97 Remove(); // one shot only
98 return kTRUE;
99}
100//------------------------------------------------------------------------------
101
102
104
105////////////////////////////////////////////////////////////////////////////////
106/// Create a monitor object. If mainloop is true the monitoring will be
107/// done in the main event loop.
108
110{
112
113 fActive = new TList;
114 fDeActive = new TList;
115 fMainLoop = mainloop;
117 fReady = 0;
118}
119
120////////////////////////////////////////////////////////////////////////////////
121/// Copy constructor
122
124{
125 TSocketHandler *sh = 0;
126 // Active list
127 fActive = new TList;
128 TIter nxa(m.fActive);
129 while ((sh = (TSocketHandler *)nxa())) {
130 Int_t mask = 0;
131 if (sh->HasReadInterest()) mask |= 0x1;
132 if (sh->HasWriteInterest()) mask |= 0x2;
133 fActive->Add(new TSocketHandler(this, sh->GetSocket(), mask, m.fMainLoop));
134 }
135 // Deactive list
136 fDeActive = new TList;
137 TIter nxd(m.fDeActive);
138 while ((sh = (TSocketHandler *)nxd())) {
139 Int_t mask = 0;
140 if (sh->HasReadInterest()) mask |= 0x1;
141 if (sh->HasWriteInterest()) mask |= 0x2;
142 fDeActive->Add(new TSocketHandler(this, sh->GetSocket(), mask, m.fMainLoop));
143 }
144 // Other members
145 fMainLoop = m.fMainLoop;
146 fInterrupt = m.fInterrupt;
147 fReady = 0;
148}
149
150////////////////////////////////////////////////////////////////////////////////
151/// Cleanup the monitor object. Does not delete sockets being monitored.
152
154{
155 fActive->Delete();
157
158 fDeActive->Delete();
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Add socket to the monitor's active list. If interest=kRead then we
164/// want to monitor the socket for read readiness, if interest=kWrite
165/// then we monitor the socket for write readiness, if interest=kRead|kWrite
166/// then we monitor both read and write readiness.
167
168void TMonitor::Add(TSocket *sock, Int_t interest)
169{
170 fActive->Add(new TSocketHandler(this, sock, interest, fMainLoop));
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Set interest mask for socket sock to interest. If the socket is not
175/// in the active list move it or add it there.
176/// If interest=kRead then we want to monitor the socket for read readiness,
177/// if interest=kWrite then we monitor the socket for write readiness,
178/// if interest=kRead|kWrite then we monitor both read and write readiness.
179
181{
182 TSocketHandler *s = 0;
183
184 if (!interest)
185 interest = kRead;
186
187 // Check first the activated list ...
188 TIter next(fActive);
189 while ((s = (TSocketHandler *) next())) {
190 if (sock == s->GetSocket()) {
191 s->SetInterest(interest);
192 return;
193 }
194 }
195
196 // Check now the deactivated list ...
197 TIter next1(fDeActive);
198 while ((s = (TSocketHandler *) next1())) {
199 if (sock == s->GetSocket()) {
200 fDeActive->Remove(s);
201 fActive->Add(s);
202 s->SetInterest(interest);
203 return;
204 }
205 }
206
207 // The socket is not in our lists: just add it
208 fActive->Add(new TSocketHandler(this, sock, interest, fMainLoop));
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Remove a socket from the monitor.
213
215{
216 TIter next(fActive);
218
219 while ((s = (TSocketHandler *) next())) {
220 if (sock == s->GetSocket()) {
221 fActive->Remove(s);
222 delete s;
223 return;
224 }
225 }
226
227 TIter next1(fDeActive);
228
229 while ((s = (TSocketHandler *) next1())) {
230 if (sock == s->GetSocket()) {
231 fDeActive->Remove(s);
232 delete s;
233 return;
234 }
235 }
236}
237
238////////////////////////////////////////////////////////////////////////////////
239/// Remove all sockets from the monitor.
240
242{
243 fActive->Delete();
244 fDeActive->Delete();
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Activate a de-activated socket.
249
251{
252 TIter next(fDeActive);
254
255 while ((s = (TSocketHandler *) next())) {
256 if (sock == s->GetSocket()) {
257 fDeActive->Remove(s);
258 fActive->Add(s);
259 s->Add();
260 return;
261 }
262 }
263}
264
265////////////////////////////////////////////////////////////////////////////////
266/// Activate all de-activated sockets.
267
269{
270 TIter next(fDeActive);
272
273 while ((s = (TSocketHandler *) next())) {
274 fActive->Add(s);
275 s->Add();
276 }
277 fDeActive->Clear();
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// De-activate a socket.
283
285{
286 TIter next(fActive);
288
289 while ((s = (TSocketHandler *) next())) {
290 if (sock == s->GetSocket()) {
291 fActive->Remove(s);
292 fDeActive->Add(s);
293 s->Remove();
294 return;
295 }
296 }
297}
298
299////////////////////////////////////////////////////////////////////////////////
300/// De-activate all activated sockets.
301
303{
304 TIter next(fActive);
306
307 while ((s = (TSocketHandler *) next())) {
308 fDeActive->Add(s);
309 s->Remove();
310 }
311 fActive->Clear();
313}
314
315////////////////////////////////////////////////////////////////////////////////
316/// Return pointer to socket for which an event is waiting.
317/// Select can be interrupt by a call to Interrupt() (e.g. connected with a
318/// Ctrl-C handler); a call to ResetInterrupt() before Select() is advisable
319/// in such a case.
320/// Return 0 in case of error.
321
323{
324 fReady = 0;
325
326 while (!fReady && !fInterrupt)
328
329 // Notify interrupts
330 if (fInterrupt) {
332 fReady = 0;
333 Info("Select","*** interrupt occured ***");
334 }
335
336 return fReady;
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// Return pointer to socket for which an event is waiting.
341/// Wait a maximum of timeout milliseconds.
342/// If return is due to timeout it returns (TSocket *)-1.
343/// Select() can be interrupt by a call to Interrupt() (e.g. connected with a
344/// Ctrl-C handler); a call to ResetInterrupt() before Select() is advisable
345/// in such a case.
346/// Return 0 in case of any other error situation.
347
349{
350 if (timeout < 0)
351 return TMonitor::Select();
352
353 fReady = 0;
354
355 TTimeOutTimer t(this, timeout);
356
357 while (!fReady && !fInterrupt)
359
360 // Notify interrupts
361 if (fInterrupt) {
363 fReady = 0;
364 Info("Select","*** interrupt occured ***");
365 }
366
367 return fReady;
368}
369
370////////////////////////////////////////////////////////////////////////////////
371/// Return numbers of sockets that are ready for reading or writing.
372/// Wait a maximum of timeout milliseconds.
373/// Return 0 if timed-out. Return < 0 in case of error.
374/// If rdready and/or wrready are not 0, the lists of sockets with
375/// something to read and/or write are also returned.
376
377Int_t TMonitor::Select(TList *rdready, TList *wrready, Long_t timeout)
378{
379 Int_t nr = -2;
380
381 TSocketHandler *h = 0;
382 Int_t ns = fActive->GetSize();
383 if (ns == 1) {
384 // Avoid additional loops inside
386 nr = gSystem->Select((TFileHandler *)h, timeout);
387 } else if (ns > 1) {
388 nr = gSystem->Select(fActive, timeout);
389 }
390
391 if (nr > 0 && (rdready || wrready)) {
392 // Clear the lists
393 if (rdready)
394 rdready->Clear();
395 if (wrready)
396 wrready->Clear();
397 // Got a file descriptor
398 if (!h) {
399 TIter next(fActive);
400 while ((h = (TSocketHandler *)next())) {
401 if (rdready && h->IsReadReady())
402 rdready->Add(h->GetSocket());
403 if (wrready && h->IsWriteReady())
404 wrready->Add(h->GetSocket());
405 }
406 } else {
407 if (rdready && h->IsReadReady())
408 rdready->Add(h->GetSocket());
409 if (wrready && h->IsWriteReady())
410 wrready->Add(h->GetSocket());
411 }
412 }
413
414 return nr;
415}
416
417////////////////////////////////////////////////////////////////////////////////
418/// Called by TSocketHandler::Notify() to signal which socket is ready
419/// to be read or written. User should not call this routine. The ready
420/// socket will be returned via the Select() user function.
421/// The Ready(TSocket *sock) signal is emitted.
422
424{
425 fReady = sock;
426 Ready(fReady);
427}
428
429////////////////////////////////////////////////////////////////////////////////
430/// Return number of sockets in the active list. If timeout > 0, remove from
431/// the list those sockets which did not have any activity since timeout
432/// millisecs. If timeout = 0, then reset activity timestamp on all active
433/// sockets. This time out is typically used if GetActive() is used to see
434/// how many remotes still need to send something. If they pass the timeout
435/// they will be skipped and GetActive() will return 0 and the loop can be
436/// exited.
437
439{
440 if (timeout >= 0) {
441 TIter next(fActive);
443 if (timeout > 0) {
444 TTimeStamp now;
445 while ((s = (TSocketHandler *) next())) {
446 TSocket *xs = s->GetSocket();
447 TTimeStamp ts = xs->GetLastUsage();
448 Long_t dt = (Long_t)(now.GetSec() - ts.GetSec()) * 1000 +
449 (Long_t)(now.GetNanoSec() - ts.GetNanoSec()) / 1000000 ;
450 if (dt > timeout) {
451 Info("GetActive", "socket: %p: %s:%d did not show any activity"
452 " during the last %ld millisecs: deactivating",
453 xs, xs->GetInetAddress().GetHostName(),
454 xs->GetInetAddress().GetPort(), timeout);
455 fActive->Remove(s);
456 fDeActive->Add(s);
457 s->Remove();
458 }
459 }
460 } else if (timeout == 0) {
461 // Reset time stamps
462 while ((s = (TSocketHandler *) next())) {
463 s->GetSocket()->Touch();
464 }
465 }
466 }
467 return fActive->GetSize();
468}
469
470////////////////////////////////////////////////////////////////////////////////
471/// Return number of sockets in the de-active list.
472
474{
475 return fDeActive->GetSize();
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Check if socket 's' is in the active list. Avoids the duplication
480/// of active list via TMonitor::GetListOfActives().
481
483{
484 TIter next(fActive);
485 while (TSocketHandler *h = (TSocketHandler*) next())
486 if (sock == h->GetSocket())
487 return kTRUE;
488
489 // Not found
490 return kFALSE;
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Returns a list with all active sockets. This list must be deleted
495/// by the user. DO NOT call Delete() on this list as it will delete
496/// the sockets that are still being used by the monitor.
497
499{
500 TList *list = new TList;
501
502 TIter next(fActive);
503
504 while (TSocketHandler *h = (TSocketHandler*) next())
505 list->Add(h->GetSocket());
506
507 return list;
508}
509
510////////////////////////////////////////////////////////////////////////////////
511/// Returns a list with all de-active sockets. This list must be deleted
512/// by the user. DO NOT call Delete() on this list as it will delete
513/// the sockets that are still being used by the monitor.
514
516{
517 TList *list = new TList;
518
519 TIter next(fDeActive);
520
521 while (TSocketHandler *h = (TSocketHandler*) next())
522 list->Add(h->GetSocket());
523
524 return list;
525}
526
527////////////////////////////////////////////////////////////////////////////////
528/// Emit signal when some socket is ready
529
531{
532 Emit("Ready(TSocket*)", (Longptr_t)sock);
533}
#define SafeDelete(p)
Definition RConfig.hxx:533
#define h(i)
Definition RSha256.hxx:106
long Longptr_t
Definition RtypesCore.h:75
long Long_t
Definition RtypesCore.h:54
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
#define ClassImp(name)
Definition Rtypes.h:382
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
R__EXTERN TSystem * gSystem
Definition TSystem.h:561
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
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:400
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:820
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:657
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
Bool_t fInterrupt
Definition TMonitor.h:48
virtual void Ready(TSocket *sock)
Emit signal when some socket is ready.
Definition TMonitor.cxx:530
void SetReady(TSocket *sock)
Called by TSocketHandler::Notify() to signal which socket is ready to be read or written.
Definition TMonitor.cxx:423
virtual void SetInterest(TSocket *sock, Int_t interest=kRead)
Set interest mask for socket sock to interest.
Definition TMonitor.cxx:180
TList * fDeActive
Definition TMonitor.h:45
virtual void RemoveAll()
Remove all sockets from the monitor.
Definition TMonitor.cxx:241
virtual void ActivateAll()
Activate all de-activated sockets.
Definition TMonitor.cxx:268
TSocket * Select()
Return pointer to socket for which an event is waiting.
Definition TMonitor.cxx:322
friend class TSocketHandler
Definition TMonitor.h:38
virtual void Activate(TSocket *sock)
Activate a de-activated socket.
Definition TMonitor.cxx:250
virtual void Add(TSocket *sock, Int_t interest=kRead)
Add socket to the monitor's active list.
Definition TMonitor.cxx:168
Int_t GetActive(Long_t timeout=-1) const
Return number of sockets in the active list.
Definition TMonitor.cxx:438
TMonitor(Bool_t mainloop=kTRUE)
Create a monitor object.
Definition TMonitor.cxx:109
TList * fActive
Definition TMonitor.h:44
virtual ~TMonitor()
Cleanup the monitor object. Does not delete sockets being monitored.
Definition TMonitor.cxx:153
virtual void DeActivateAll()
De-activate all activated sockets.
Definition TMonitor.cxx:302
TSocket * fReady
Definition TMonitor.h:46
virtual void DeActivate(TSocket *sock)
De-activate a socket.
Definition TMonitor.cxx:284
TList * GetListOfActives() const
Returns a list with all active sockets.
Definition TMonitor.cxx:498
TList * GetListOfDeActives() const
Returns a list with all de-active sockets.
Definition TMonitor.cxx:515
virtual void Remove(TSocket *sock)
Remove a socket from the monitor.
Definition TMonitor.cxx:214
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:482
Int_t GetDeActive() const
Return number of sockets in the de-active list.
Definition TMonitor.cxx:473
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:967
This is the ROOT implementation of the Qt object communication mechanism (see also http://www....
Definition TQObject.h:48
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
TTimeStamp GetLastUsage()
Definition TSocket.h:129
void Touch()
Definition TSocket.h:157
TInetAddress GetInetAddress() const
Definition TSocket.h:113
virtual void InnerLoop()
Inner event loop.
Definition TSystem.cxx:400
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:471
virtual Int_t Select(TList *active, Long_t timeout)
Select on active file descriptors (called by TMonitor).
Definition TSystem.cxx:445
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
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
void Remove() override
Definition TTimer.h:86
TMarker m
Definition textangle.C:8