PTLib  Version 2.14.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
timer.h
Go to the documentation of this file.
1 /*
2  * timer.h
3  *
4  * Real time down counting time interval class.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 32010 $
30  * $Author: rjongbloed $
31  * $Date: 2014-05-31 14:52:42 +1000 (Sat, 31 May 2014) $
32  */
33 
34 #ifndef PTLIB_TIMER_H
35 #define PTLIB_TIMER_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 
42 #include <ptlib/notifier.h>
43 #include <ptlib/id_generator.h>
44 #include <ptclib/threadpool.h>
45 
46 #include <queue>
47 #include <set>
48 #include <map>
49 
50 
51 // To avoid ambiguous operator error we need a one for every integer variant
52 #define PTIMER_OPERATORS(cls) \
53  cls & operator=( int16_t rhs) { this->SetInterval(rhs); return *this; } \
54  cls & operator=(uint16_t rhs) { this->SetInterval(rhs); return *this; } \
55  cls & operator=( int32_t rhs) { this->SetInterval(rhs); return *this; } \
56  cls & operator=(uint32_t rhs) { this->SetInterval(rhs); return *this; } \
57  cls & operator=( int64_t rhs) { this->SetInterval(rhs); return *this; } \
58  cls & operator=(uint64_t rhs) { this->SetInterval(rhs); return *this; } \
59  cls & operator=(const PTimeInterval & rhs) { this->SetInterval(rhs.GetMilliSeconds()); return *this; } \
60 
61 
76 {
77  PCLASSINFO(PSimpleTimer, PTimeInterval);
78 
79  public:
86  long milliseconds = 0,
87  int seconds = 0,
88  int minutes = 0,
89  int hours = 0,
90  int days = 0
91  );
93  const PTimeInterval & time
94  );
96  const PSimpleTimer & timer
97  );
98 
106  DWORD milliseconds
107  );
109  const PTimeInterval & time
110  );
112  const PSimpleTimer & timer
113  );
115 
132  virtual void SetInterval(
133  PInt64 milliseconds = 0,
134  long seconds = 0,
135  long minutes = 0,
136  long hours = 0,
137  int days = 0
138  );
139 
142  void Stop();
143 
146  PTimeInterval GetElapsed() const;
147 
151  PTimeInterval GetRemaining() const;
152 
155  bool IsRunning() const;
156 
159  bool HasExpired() const;
160 
163  operator bool() const;
165 
166  protected:
168 };
169 
170 
196 class PTimer : public PTimeInterval
197 {
198  PCLASSINFO_WITH_CLONE(PTimer, PTimeInterval);
199 
200  public:
201 
209  PTimer(
210  long milliseconds = 0,
211  int seconds = 0,
212  int minutes = 0,
213  int hours = 0,
214  int days = 0
215  );
216  PTimer(
217  const PTimeInterval & time
218  );
219  PTimer(
220  const PTimer & timer
221  );
222 
229  PTimer & operator=(
230  const PTimer & timer
231  );
232 
234 
237  virtual ~PTimer();
239 
245  virtual void PrintOn(
246  ostream & strm
247  ) const;
249 
255  virtual void SetMilliSeconds(PInt64 msecs);
256 
261  void RunContinuous(
262  const PTimeInterval & time // New time interval for timer.
263  );
264 
274  void Stop(
275  bool wait = true
276  );
277 
284  PBoolean IsRunning() const;
285 
288  void Reset();
289 
292  PTimeInterval GetResetTime() const;
294 
309  virtual void OnTimeout();
310 
317  const PNotifier & GetNotifier() const;
318 
322  void SetNotifier(
323  const PNotifier & func // New notifier function for the timer.
324  );
326 
341  static PTimeInterval Tick();
342 
351  static unsigned Resolution();
353 
358  PInt64 GetMilliSeconds() const;
360 
361 
362  /* This class defines a list of <code>PTimer</code> objects. It is primarily used
363  internally by the library and the user should never create an instance of
364  it. The <code>PProcess</code> instance for the application maintains an instance
365  of all of the timers created so that it may decrements them at regular
366  intervals.
367  */
368  class List
369  {
370  public:
371  // Create a new timer list
372  List();
373 
374  /* Decrement all the created timers and dispatch to their callback
375  functions if they have expired. The <code>PTimer::Tick()</code> function
376  value is used to determine the time elapsed since the last call to
377  Process().
378 
379  The return value is the number of milliseconds until the next timer
380  needs to be dispatched. The function need not be called again for this
381  amount of time, though it can (and usually is).
382 
383  @return
384  maximum time interval before function should be called again.
385  */
387 
388  private:
389  bool OnTimeout(PIdGenerator::Handle handle);
390 
391  struct Timeout
392  {
393  PIdGenerator::Handle m_handle;
394  Timeout(PIdGenerator::Handle handle) : m_handle(handle) { }
395  virtual void Work();
396  };
397  PQueuedThreadPool<Timeout> m_threadPool;
398 
399  typedef std::map<PIdGenerator::Handle, PTimer *> TimerMap;
400  TimerMap m_timers;
401  PMutex m_timersMutex;
402 
403  friend class PTimer;
404  };
405 
406  static List * TimerList();
407 
408 
409  private:
410  void InternalStart(bool once, PTimeInterval resetTime); // Note, not "const PTimeInterval &" to avoid mutex issues
411 
412  // Member variables
413  PNotifier m_callback; // Callback function for expired timers.
414  bool m_oneshot; // Timer operates once then stops.
415  PIdGenerator::Handle m_handle;
416  bool m_running;
417  PTimeInterval m_absoluteTime;
418  PTimedMutex m_callbackMutex;
419 
420  friend class Emitter;
421 
422 // Include platform dependent part of class
423 #ifdef _WIN32
424 #include "msos/ptlib/timer.h"
425 #else
426 #include "unix/ptlib/timer.h"
427 #endif
428 };
429 
430 
453 template <
454  class Work_T,
455  class Pool_T = PQueuedThreadPool<Work_T>
456 >
457 class PPoolTimer : public PTimer
458 {
459  PCLASSINFO(PPoolTimer, PTimer);
460  protected:
461  Pool_T & m_pool;
462  public:
463  PPoolTimer(Pool_T & pool)
464  : m_pool(pool)
465  {
466  }
467 
468  virtual void OnTimeout()
469  {
470  Work_T * work = CreateWork();
471  if (work != NULL)
472  m_pool.AddWork(work, GetGroup(*work));
473  }
474 
475  virtual Work_T * CreateWork() = 0;
476  virtual const char * GetGroup(const Work_T & /*work*/) const { return NULL; }
477 
479 };
480 
481 
483 template <
484  class Work_T,
485  class Base_T = Work_T,
486  class Pool_T = PQueuedThreadPool<Base_T>
487 >
488 class PPoolTimerArg0 : public PPoolTimer<Base_T, Pool_T>
489 {
491  PCLASSINFO(PPoolTimerArg0, BaseClass);
492  public:
493  PPoolTimerArg0(Pool_T & pool)
494  : BaseClass(pool)
495  {
496  }
497 
498  virtual Work_T * CreateWork() { return new Work_T(); }
499 
501 };
502 
503 
505 template <
506  class Work_T,
507  typename Arg1,
508  class Base_T = Work_T,
509  class Pool_T = PQueuedThreadPool<Base_T>
510 >
511 class PPoolTimerArg1: public PPoolTimer<Base_T, Pool_T>
512 {
514  PCLASSINFO(PPoolTimerArg1, BaseClass);
515  protected:
516  Arg1 m_arg1;
517  public:
518  PPoolTimerArg1(Pool_T & pool, Arg1 arg1)
519  : BaseClass(pool)
520  , m_arg1(arg1)
521  {
522  }
523 
524  virtual Work_T * CreateWork() { return new Work_T(m_arg1); }
525 
527 };
528 
529 
531 template <
532  class Work_T,
533  typename Arg1,
534  typename Arg2,
535  class Base_T = Work_T,
536  class Pool_T = PQueuedThreadPool<Base_T>
537 >
538 class PPoolTimerArg2: public PPoolTimer<Base_T, Pool_T>
539 {
541  PCLASSINFO(PPoolTimerArg2, BaseClass);
542  protected:
543  Arg1 m_arg1;
544  Arg2 m_arg2;
545  public:
546  PPoolTimerArg2(Pool_T & pool, Arg1 arg1, Arg2 arg2)
547  : BaseClass(pool)
548  , m_arg1(arg1)
549  , m_arg2(arg2)
550  {
551  }
552 
553  virtual Work_T * CreateWork() { return new Work_T(m_arg1, m_arg2); }
554 
556 };
557 
558 
560 template <
561  class Work_T,
562  typename Arg1,
563  typename Arg2,
564  typename Arg3,
565  class Base_T = Work_T,
566  class Pool_T = PQueuedThreadPool<Base_T>
567 >
568 class PPoolTimerArg3: public PPoolTimer<Base_T, Pool_T>
569 {
571  PCLASSINFO(PPoolTimerArg3, BaseClass);
572  protected:
573  Arg1 m_arg1;
574  Arg2 m_arg2;
575  Arg3 m_arg3;
576  public:
577  PPoolTimerArg3(Pool_T & pool, Arg1 arg1, Arg2 arg2, Arg3 arg3)
578  : BaseClass(pool)
579  , m_arg1(arg1)
580  , m_arg2(arg2)
581  , m_arg3(arg3)
582  {
583  }
584 
585  virtual Work_T * CreateWork() { return new Work_T(m_arg1, m_arg2, m_arg3); }
586 
588 };
589 
590 
591 #endif // PTLIB_TIMER_H
592 
593 
594 // End Of File ///////////////////////////////////////////////////////////////