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:
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
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
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;
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
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
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()) {
191 return;
192 }
193 }
194
195 // Check now the deactivated list ...
197 while ((s = (TSocketHandler *) next1())) {
198 if (sock == s->GetSocket()) {
199 fDeActive->Remove(s);
200 fActive->Add(s);
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
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)
327
328 // Notify interrupts
329 if (fInterrupt) {
331 fReady = 0;
332 Info("Select","*** interrupt occured ***");
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)
358
359 // Notify interrupts
360 if (fInterrupt) {
362 fReady = 0;
363 Info("Select","*** interrupt occured ***");
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
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
386 } else if (ns > 1) {
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) {
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:533
#define h(i)
Definition RSha256.hxx:106
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
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#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:572
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual void SetInterest(Int_t mask)
Set interest mask to 'mask'.
void Remove() override
Remove file event handler from system file handler list.
void Add() override
Add file event handler to system file handler list.
A doubly linked list.
Definition TList.h:38
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:399
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:819
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:656
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:467
Bool_t fInterrupt
Definition TMonitor.h:48
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
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:1045
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
void Touch()
Definition TSocket.h:155
virtual void InnerLoop()
Inner event loop.
Definition TSystem.cxx:398
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition TSystem.cxx:469
virtual Int_t Select(TList *active, Long_t timeout)
Select on active file descriptors (called by TMonitor).
Definition TSystem.cxx:443
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
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
void Remove() override
Definition TTimer.h:86
TMarker m
Definition textangle.C:8