BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlmt_timereventscheduler.h
Go to the documentation of this file.
1/// @file bdlmt_timereventscheduler.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlmt_timereventscheduler.h -*-C++-*-
8#ifndef INCLUDED_BDLMT_TIMEREVENTSCHEDULER
9#define INCLUDED_BDLMT_TIMEREVENTSCHEDULER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlmt_timereventscheduler bdlmt_timereventscheduler
15/// @brief Provide a thread-safe recurring and non-recurring event scheduler.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlmt
19/// @{
20/// @addtogroup bdlmt_timereventscheduler
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlmt_timereventscheduler-purpose"> Purpose</a>
25/// * <a href="#bdlmt_timereventscheduler-classes"> Classes </a>
26/// * <a href="#bdlmt_timereventscheduler-metrics"> Metrics </a>
27/// * <a href="#bdlmt_timereventscheduler-description"> Description </a>
28/// * <a href="#bdlmt_timereventscheduler-comparison-to-bdlmt-eventscheduler"> Comparison to bdlmt::EventScheduler </a>
29/// * <a href="#bdlmt_timereventscheduler-order-of-execution-of-events"> Order of Execution of Events </a>
30/// * <a href="#bdlmt_timereventscheduler-the-dispatcher-thread-and-the-dispatcher-functor"> The Dispatcher Thread and the Dispatcher Functor </a>
31/// * <a href="#bdlmt_timereventscheduler-thread-safety"> Thread Safety </a>
32/// * <a href="#bdlmt_timereventscheduler-supported-clock-types"> Supported Clock-Types </a>
33/// * <a href="#bdlmt_timereventscheduler-event-clock-substitution"> Event Clock Substitution </a>
34/// * <a href="#bdlmt_timereventscheduler-thread-name-for-dispatcher-thread"> Thread Name for Dispatcher Thread </a>
35/// * <a href="#bdlmt_timereventscheduler-usage"> Usage </a>
36/// * <a href="#bdlmt_timereventscheduler-example-1-basic-usage"> Example 1: Basic Usage </a>
37/// * <a href="#bdlmt_timereventscheduler-example-2-using-the-test-time-source"> Example 2: Using the Test Time Source </a>
38///
39/// # Purpose {#bdlmt_timereventscheduler-purpose}
40/// Provide a thread-safe recurring and non-recurring event scheduler.
41///
42/// # Classes {#bdlmt_timereventscheduler-classes}
43///
44/// - bdlmt::TimerEventScheduler: thread-safe event scheduler
45///
46/// # Metrics {#bdlmt_timereventscheduler-metrics}
47///
48///
49/// * `bde.startlag`
50/// > seconds of delay in starting the next event (may be 0.0)
51///
52/// Associated Metric Attributes:
53/// * object type name: "bdlmt.timereventscheduler"
54/// * object type abbreviation: "tes"
55///
56/// @see bdlmt_eventscheduler, bdlcc_timequeue
57///
58/// # Description {#bdlmt_timereventscheduler-description}
59/// This component provides a thread-safe event scheduler,
60/// `bdlmt::TimerEventScheduler`. It provides methods to schedule and cancel
61/// recurring and non-recurring events. (A recurring event is also referred to
62/// as a clock). The callbacks are processed by a separate thread (called the
63/// dispatcher thread). By default the callbacks are executed in the dispatcher
64/// thread, but this behavior can be altered by providing a dispatcher functor
65/// at the creation time (see the section "The dispatcher thread and the
66/// dispatcher functor"). Use this component for implementing timeouts,
67/// deferred executions, calendars and reminders, and recurring tasks, among
68/// other time-bound behaviors.
69///
70/// The number of active events permitted by the timer-event scheduler defaults
71/// to an implementation defined constant, and in any case no more than 2**24 -
72/// 1. Note that if the scheduled event goes into infinite loop, and the
73/// default displatcher is used, the event scheduler may get into live lock.
74///
75/// ## Comparison to bdlmt::EventScheduler {#bdlmt_timereventscheduler-comparison-to-bdlmt-eventscheduler}
76///
77///
78/// This class has been made mostly obsolete by the newer
79/// @ref bdlmt_eventscheduler , which addresses two main disadvantages of this
80/// component: 1) @ref bdlmt_timereventscheduler can only manage a finite number of
81/// events -- this limit is in the millions, but @ref bdlmt_eventscheduler has no
82/// such limit; and 2) accessing the queue of a `bdlmt::TimerEventScheduler` is
83/// inefficient when there is a large number of managed events (since adding or
84/// removing an event involves a linear search); @ref bdlmt_eventscheduler has a
85/// more sophisticated queue that can be accessed in constant or worst-case
86/// log(n) time. The advantage this component provides over
87/// @ref bdlmt_eventscheduler is that it provides light-weight handles to events in
88/// the queue, while @ref bdlmt_eventscheduler provides more heavy-weight
89/// reference-counted handles that must be released.
90///
91/// ## Order of Execution of Events {#bdlmt_timereventscheduler-order-of-execution-of-events}
92///
93///
94/// It is intended that recurring and non-recurring events are processed as
95/// close as possible to their respective time values. Delays and unfairness in
96/// thread contention can sometimes delay execution, but this component
97/// guarantees that (1) events are processed in increasing time order, and (2)
98/// are never processed sooner than their corresponding time (but could be
99/// processed arbitrarily long afterward, if the dispatcher thread has not been
100/// able to gain control in the meantime, due to thread contention or to a long
101/// event).
102///
103/// Note that it is possible to schedule events in a scheduler that has not been
104/// started yet. When starting a scheduler, scheduled events whose times have
105/// already passed will be dispatched as soon as possible after the start time,
106/// still in order of their corresponding time.
107///
108/// The only exception to those guarantees are when an event `e1` at time `T`
109/// say, is already pending while another event `e2` is scheduled at a time <=
110/// `T`. Then the dispatcher will complete the execution of `e1` before
111/// dispatching `e2`.
112///
113/// ## The Dispatcher Thread and the Dispatcher Functor {#bdlmt_timereventscheduler-the-dispatcher-thread-and-the-dispatcher-functor}
114///
115///
116/// Between calls to `start` and `stop`, the scheduler creates a separate thread
117/// (called the *dispatcher thread*) to process all the callbacks. The
118/// dispatcher thread executes the callbacks by passing them to the dispatcher
119/// functor (optionally specified at creation time). The default dispatcher
120/// functor simply invokes the passed callback, effectively executing it in the
121/// dispatcher thread. Users can alter this behavior by defining their own
122/// dispatcher functor (for example in order to use a thread pool or a separate
123/// thread to run the callbacks). In that case, the user-supplied functor will
124/// still be run in the dispatcher thread, different from the scheduler thread.
125///
126/// ## Thread Safety {#bdlmt_timereventscheduler-thread-safety}
127///
128///
129/// The `bdlmt::TimerEventScheduler` class is both *fully thread-safe* (i.e.,
130/// all non-creator methods can correctly execute concurrently), and is
131/// *thread-enabled* (i.e., the classes does not function correctly in a
132/// non-multi-threading environment). See @ref bsldoc_glossary for complete
133/// definitions of *fully thread-safe* and *thread-enabled*.
134///
135/// ## Supported Clock-Types {#bdlmt_timereventscheduler-supported-clock-types}
136///
137///
138/// The component `bsls::SystemClockType` supplies the enumeration indicating
139/// the system clock on which times supplied to other methods should be based.
140/// If the clock type indicated at construction is
141/// `bsls::SystemClockType::e_REALTIME`, time should be expressed as an absolute
142/// offset since 00:00:00 UTC, January 1, 1970 (which matches the epoch used in
143/// `bdlt::SystemTime::now(bsls::SystemClockType::e_REALTIME)`. If the clock
144/// type indicated at construction is `bsls::SystemClockType::e_MONOTONIC`, time
145/// should be expressed as an absolute offset since the epoch of this clock
146/// (which matches the epoch used in
147/// `bdlt::SystemTime::now(bsls::SystemClockType::e_MONOTONIC)`.
148///
149/// The current epoch time for a particular `bdlmt::TimerEventScheduler`
150/// instance according to the correct clock is available via the
151/// `bdlmt::TimerEventScheduler::now` accessor.
152///
153/// ## Event Clock Substitution {#bdlmt_timereventscheduler-event-clock-substitution}
154///
155///
156/// For testing purposes, a class `bdlmt::TimerEventSchedulerTestTimeSource` is
157/// provided to allow manual manipulation of the system-time observed by a
158/// `bdlmt::TimerEventScheduler`. A test driver that interacts with a
159/// `bdlmt::TimerEventScheduler` can use a
160/// `bdlmt::TimerEventSchedulerTestTimeSource` object to control when scheduled
161/// events are triggered, allowing more reliable tests.
162///
163/// A `bdlmt::TimerEventSchedulerTestTimeSource` can be constructed for any
164/// existing `bdlmt::TimerEventScheduler` object that has not been started and
165/// has not had any events scheduled. When the
166/// `bdlmt::TimerEventSchedulerTestTimeSource` is constructed, it will replace
167/// the clock of the `bdlmt::TimerEventScheduler` to which it is attached. The
168/// internal clock of the `bdlmt::TimerEventSchedulerTestTimeSource` will be
169/// initialized with an arbitrary value on construction, and will advance only
170/// when explicitly instructed to do so by a call to
171/// `bdlt::TimerEventSchedulerTestTimeSource::advanceTime`. The current value
172/// of the internal clock can be accessed by calling
173/// `bdlt::TimerEventSchedulerTestTimeSource::now`, or
174/// `bdlmt::TimerEventScheduler::now` on the instance supplied to the
175/// `bdlmt::TimerEventSchedulerTestTimeSource`.
176///
177/// Note that the initial value of
178/// `bdlt::TimerEventSchedulerTestTimeSource::now` is intentionally not
179/// synchronized with `bdlt::SystemTime::now`. All test events scheduled for a
180/// `bdlmt::TimerEventScheduler` that is instrumented with a
181/// `bdlt::TimerEventSchedulerTestTimeSource` should be scheduled in terms of an
182/// offset from whatever arbitrary time is reported by
183/// `bdlt::TimerEventSchedulerTestTimeSource`. See Example 3 below for an
184/// illustration of how this is done.
185///
186/// ## Thread Name for Dispatcher Thread {#bdlmt_timereventscheduler-thread-name-for-dispatcher-thread}
187///
188///
189/// To facilitate debugging, users can provide a thread name as the `threadName`
190/// attribute of the `bslmt::ThreadAttributes` argument passed to the `start`
191/// method, that will be used for the dispatcher thread. The thread name should
192/// not be used programmatically, but will appear in debugging tools on
193/// platforms that support naming threads to help users identify the source and
194/// purpose of a thread. If no `ThreadAttributes` object is passed, or if the
195/// `threadName` attribute is not set, the default value "bdl.TimerEvent" will
196/// be used.
197///
198/// ## Usage {#bdlmt_timereventscheduler-usage}
199///
200///
201/// This section illustrates intended use of this component.
202///
203/// ### Example 1: Basic Usage {#bdlmt_timereventscheduler-example-1-basic-usage}
204///
205///
206/// The following example shows how to use a `bdlmt::TimerEventScheduler` to
207/// implement a timeout mechanism in a server. `my_Session` maintains several
208/// connections. It closes a connection if the data for it does not arrive
209/// before a timeout (specified at the server creation time).
210///
211/// @code
212/// /// This class encapsulates the data and state associated with a
213/// /// connection and provides a method `processData` to process the
214/// /// incoming data for the connection.
215/// class my_Session{
216/// public:
217///
218/// /// Process the specified `data` of the specified `length`.
219/// int processData(void *data, int length);
220/// };
221///
222/// /// This class implements a server maintaining several connections.
223/// /// A connection is closed if the data for it does not arrive
224/// /// before a timeout (specified at the server creation time).
225/// class my_Server {
226///
227/// struct Connection {
228/// bdlmt::TimerEventScheduler::Handle d_timerId; // handle for timeout
229/// // event
230///
231/// my_Session *d_session_p; // session for this
232/// // connection
233/// };
234///
235/// bsl::vector<Connection*> d_connections; // maintained connections
236/// bdlmt::TimerEventScheduler d_scheduler; // timeout event scheduler
237/// bsls::TimeInterval d_ioTimeout; // time out
238///
239/// /// Add the specified 'connection' to this server and schedule
240/// /// the timeout event that closes this connection if the data
241/// /// for this connection does not arrive before the timeout.
242/// void newConnection(Connection *connection);
243///
244/// /// Close the specified `connection` and remove it from this server.
245/// void closeConnection(Connection *connection);
246///
247/// /// Return if the specified `connection` has already timed-out.
248/// /// If not, cancel the existing timeout event for the `connection`,
249/// /// process the specified `data` of the specified `length` and
250/// /// schedule a new timeout event that closes the `connection` if
251/// /// the data does not arrive before the timeout.
252/// void dataAvailable(Connection *connection, void *data, int length);
253///
254/// public:
255///
256/// /// Construct a `my_Server` object with a timeout value of
257/// /// `ioTimeout` seconds. Optionally specify a `allocator` used to
258/// /// supply memory. If `allocator` is 0, the currently installed
259/// /// default allocator is used.
260/// my_Server(const bsls::TimeInterval& ioTimeout,
261/// bslma::Allocator *allocator = 0);
262///
263/// /// Perform the required clean-up and destroy this object.
264/// ~my_Server();
265/// };
266///
267/// my_Server::my_Server(const bsls::TimeInterval& ioTimeout,
268/// bslma::Allocator *allocator)
269/// : d_connections(allocator)
270/// , d_scheduler(allocator)
271/// , d_ioTimeout(ioTimeout)
272/// {
273/// // logic to start monitoring the arriving connections or data
274///
275/// d_scheduler.start();
276/// }
277///
278/// my_Server::~my_Server()
279/// {
280/// // logic to clean up
281///
282/// d_scheduler.stop();
283/// }
284///
285/// void my_Server::newConnection(my_Server::Connection *connection)
286/// {
287/// // logic to add 'connection' to the 'd_connections'
288///
289/// // setup the timeout for data arrival
290/// connection->d_timerId = d_scheduler.scheduleEvent(
291/// d_scheduler.now() + d_ioTimeout,
292/// bdlf::BindUtil::bind(&my_Server::closeConnection, this, connection));
293/// }
294///
295/// void my_Server::closeConnection(my_Server::Connection *connection)
296/// {
297/// // logic to close the 'connection' and remove it from 'd_ioTimeout'
298/// }
299///
300/// void my_Server::dataAvailable(my_Server::Connection *connection,
301/// void *data,
302/// int length)
303/// {
304/// // If connection has already timed out and closed, simply return.
305/// if (d_scheduler.cancelEvent(connection->d_timerId)) {
306/// return; // RETURN
307/// }
308///
309/// // process the data
310/// connection->d_session_p->processData(data, length);
311///
312/// // setup the timeout for data arrival
313/// connection->d_timerId = d_scheduler.scheduleEvent(
314/// d_scheduler.now() + d_ioTimeout,
315/// bdlf::BindUtil::bind(&my_Server::closeConnection, this, connection));
316/// }
317/// @endcode
318///
319/// ### Example 2: Using the Test Time Source {#bdlmt_timereventscheduler-example-2-using-the-test-time-source}
320///
321///
322/// For testing purposes, the class `bdlmt::TimerEventSchedulerTestTimeSource`
323/// is provided to allow a test to manipulate the system-time observed by a
324/// `bdlmt::TimeEventScheduler` in order to control when events are triggered.
325/// After a scheduler is constructed, a
326/// `bdlmt::TimerEventSchedulerTestTimeSource` object can be created atop the
327/// scheduler. A test can then use the test time-source to advance the
328/// scheduler's observed system-time in order to dispatch events in a manner
329/// coordinated by the test. Note that a
330/// `bdlmt::TimerEventSchedulerTestTimeSource` **must** be created on an
331/// event-scheduler before any events are scheduled, or the event-scheduler is
332/// started.
333///
334/// This example shows how the clock may be altered:
335///
336/// @code
337/// void myCallbackFunction() {
338/// puts("Event triggered!");
339/// }
340///
341/// void testCase() {
342/// // Construct the scheduler
343/// bdlmt::TimerEventScheduler scheduler;
344///
345/// // Construct the time-source.
346/// // Install the time-source in the scheduler.
347/// bdlmt::TimerEventSchedulerTestTimeSource timeSource(&scheduler);
348///
349/// // Retrieve the initial time held in the time-source.
350/// bsls::TimeInterval initialAbsoluteTime = timeSource.now();
351///
352/// // Schedule a single-run event at a 35s offset.
353/// scheduler.scheduleEvent(initialAbsoluteTime + 35,
354/// bsl::function<void()()>(&myCallbackFunction));
355///
356/// // Schedule a 30s recurring event.
357/// scheduler.startClock(bsls::TimeInterval(30),
358/// bsl::function<void()()>(&myCallbackFunction));
359///
360/// // Start the dispatcher thread.
361/// scheduler.start();
362///
363/// // Advance the time by 40 seconds so that each
364/// // event will run once.
365/// timeSource.advanceTime(bsls::TimeInterval(40));
366///
367/// // The line "Event triggered!" should now have
368/// // been printed to the console twice.
369///
370/// scheduler.stop();
371/// }
372/// @endcode
373///
374/// Note that this feature should be used only for testing purposes, never in
375/// production code.
376/// @}
377/** @} */
378/** @} */
379
380/** @addtogroup bdl
381 * @{
382 */
383/** @addtogroup bdlmt
384 * @{
385 */
386/** @addtogroup bdlmt_timereventscheduler
387 * @{
388 */
389
390#include <bdlscm_version.h>
391
392#include <bdlcc_objectcatalog.h>
393#include <bdlcc_timequeue.h>
394
395#include <bdlm_metricsregistry.h>
396
397#include <bdlma_concurrentpool.h>
398
399#include <bslma_allocator.h>
401
403
404#include <bslmt_condition.h>
405#include <bslmt_mutex.h>
407#include <bslmt_threadutil.h>
408
409#include <bsls_atomic.h>
410#include <bsls_systemclocktype.h>
411#include <bsls_timeinterval.h>
412
413#include <bsl_functional.h>
414#include <bsl_memory.h>
415#include <bsl_string.h>
416#include <bsl_vector.h>
417
418
419namespace bdlmt {
420
421struct TimerEventSchedulerDispatcher;
422class TimerEventSchedulerTestTimeSource_Data;
423
424 // =========================
425 // class TimerEventScheduler
426 // =========================
427
428/// This class provides a thread-safe event scheduler. `scheduleEvent`
429/// schedules a non-recurring event, returning a handle of type
430/// `TimerEventScheduler::Handle`, which can be used to cancel the scheduled
431/// event by invoking `cancelEvent`. Similarly, `startClock` schedules a
432/// recurring event, returning a handle of type
433/// `TimerEventScheduler::Handle`, which can be used to cancel the clock by
434/// invoking `cancelClock`. `cancelAllEvents` cancels all the registered
435/// events and `cancelAllClocks` cancels all the registered clocks. The
436/// callbacks are processed by a separate thread (called dispatcher thread).
437/// By default the callbacks are executed in the dispatcher thread, but this
438/// behavior can be altered by providing a dispatcher functor at the
439/// creation time (see the section "The dispatcher thread and the dispatcher
440/// functor"). `start` must be invoked to start dispatching the callbacks.
441/// `stop` stops the dispatching of the callbacks without removing the
442/// pending events.
443///
444/// See @ref bdlmt_timereventscheduler
446
447 private:
448 // PRIVATE TYPES
449
450 /// This structure encapsulates the data associated with a clock.
451 ///
452 /// See @ref bdlmt_timereventscheduler
453 struct ClockData {
454
455 bsl::function<void()> d_callback; // associated callback
456
457 bsls::TimeInterval d_periodicInterval; // associated periodic
458 // interval
459
460 bsls::AtomicBool d_isCancelled; // tracks if the associated
461 // clock has been cancelled
462
463 bsls::AtomicInt d_handle; // handle for clock
464 // callback
465
466 // TRAITS
468
469 // CREATORS
470 ClockData(const bsl::function<void()>& callback,
471 const bsls::TimeInterval& interval,
472 bslma::Allocator *basicAllocator = 0)
473 : d_callback(bsl::allocator_arg_t(),
474 bsl::allocator<bsl::function<void()> >(basicAllocator),
475 callback)
476 , d_periodicInterval(interval)
477 , d_isCancelled(false)
478 , d_handle(0)
479 {
480 }
481
482 ClockData(const ClockData& original,
483 bslma::Allocator *basicAllocator = 0)
484 : d_callback(bsl::allocator_arg_t(),
485 bsl::allocator<bsl::function<void()> >(basicAllocator),
486 original.d_callback)
487 , d_periodicInterval(original.d_periodicInterval)
488 , d_isCancelled(original.d_isCancelled.load())
489 , d_handle(original.d_handle.load())
490 {
491 }
492 };
493
494 typedef bsl::shared_ptr<ClockData> ClockDataPtr;
500
501 public:
502 // TYPES
503
504 /// Defines a type alias for a handle that identifies a scheduled clock
505 /// or event.
506 typedef int Handle;
507
508 /// Defines a type alias for the dispatcher functor type.
509 typedef bsl::function<void(const bsl::function<void()>&)> Dispatcher;
510
511 /// Defines a type alias for a user-supplied key for identifying events.
513
514 // CONSTANTS
515 enum {
516 e_INVALID_HANDLE = -1 // value of an invalid event or clock handle
517#ifndef BDE_OMIT_INTERNAL_DEPRECATED
520#endif // BDE_OMIT_INTERNAL_DEPRECATED
521 };
522
523 private:
524 // PRIVATE CLASS DATA
525 static const char s_defaultThreadName[16]; // Thread name to use when none
526 // is specified.
527
528 // PRIVATE DATA
529 bslma::Allocator *d_allocator_p; // memory allocator (held)
530
531 CurrentTimeFunctor
532 d_currentTimeFunctor; // when called, returns the current
533 // time the scheduler should use
534 // for the event timeline
535
537 d_clockDataAllocator; // pool for `ClockData` objects
538
539 EventTimeQueue d_eventTimeQueue; // time queue for non recurring
540 // events
541
542 ClockTimeQueue d_clockTimeQueue; // time queue for clock events
543
545 d_clocks; // catalog of clocks
546
547 bslmt::Mutex d_dispatcherMutex; // serialize starting/stopping
548 // dispatcher thread. Note that if
549 // `d_dispatcherMutex` and
550 // `d_mutex` are to both be locked,
551 // the lock on `d_dispatcherMutex`
552 // must be acquired first.
553
554 mutable bslmt::Mutex
555 d_mutex; // mutex used to control access to
556 // this timer event scheduler
557
558 bslmt::Condition d_condition; // condition variable used to
559 // control access to this timer
560 // event scheduler
561
562 Dispatcher d_dispatcherFunctor; // functor used to dispatch events
563
564 bsls::AtomicInt64 d_dispatcherId; // id of the dispatcher thread
565
567 d_dispatcherThread; // handle of the dispatcher thread
568
569 bsls::AtomicInt d_running; // indicates if the timer event
570 // scheduler is running
571
572 bsls::AtomicInt d_iterations; // dispatcher cycle iteration
573 // number
574
576 d_pendingClockItems; // array of pending clock callbacks;
577 // not synchronized by 'd_mutex'
578 // because it is only accessed
579 // from the dispatcher thread
580
582 d_pendingEventItems; // array of pending event callbacks
583
584 int d_currentEventIndex; // index (in the array
585 // `d_pendingEventItems`) of the
586 // current event callback being
587 // processed by dispatcher thread
588
589 bsls::AtomicInt d_numEvents; // the number of events currently
590 // registered and/or pending
591 // dispatch (current callback is
592 // NOT counted)
593
594 bsls::AtomicInt d_numClocks; // number of clocks currently
595 // registered
596
598 d_clockType; // clock type used
599
600 const bsl::string d_eventSchedulerName; // name of this scheduler
601
602 bsls::AtomicInt64 d_cachedClockMicroseconds;
603 // microseconds from epoch of next
604 // cached clock
605
606 bsls::AtomicInt64 d_cachedEventMicroseconds;
607 // microseconds from epoch of next
608 // cached event
609
610 bsls::AtomicInt64 d_cachedNowMicroseconds;
611 // microseconds from epoch of
612 // most recent "now"
613
615 d_startLagHandle; // start lag handle
616
617 private:
618 // NOT IMPLEMENTED
620 TimerEventScheduler& operator=(const TimerEventScheduler&);
621
622 // FRIENDS
625
626 private:
627 // PRIVATE MANIPULATORS
628
629 /// Initialize this event scheduler using the stored attributes and the
630 /// specified `metricsRegistry` and `eventSchedulerName`. If
631 /// `metricsRegistry` is 0, `bdlm::MetricsRegistry::singleton()` is used.
632 void initialize(bdlm::MetricsRegistry *metricsRegistry,
633 const bsl::string_view& eventSchedulerName);
634
635 /// Repeatedly wake up dispatcher thread until it noticeably starts
636 /// running.
637 void yieldToDispatcher();
638
639 public:
640 // TRAITS
643
644 // CREATORS
645
646 /// Construct an event scheduler using the default dispatcher functor
647 /// (see the "The dispatcher thread and the dispatcher functor" section
648 /// in component-level doc) and use the realtime clock epoch for all
649 /// time intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ). Optionally specify a
650 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
651 ///
652 /// \note Note that the maximal
653 /// number of scheduled non-recurring events and recurring events defaults
654 /// to an implementation defined constant.
655 explicit TimerEventScheduler(bslma::Allocator *basicAllocator = 0);
656
657 /// Construct an event scheduler using the default dispatcher functor
658 /// (see the "The dispatcher thread and the dispatcher functor" section
659 /// in component-level doc), use the realtime clock epoch for all time
660 /// intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ), the specified
661 /// `eventSchedulerName` to be used to identify this event scheduler, and
662 /// the specified `metricsRegistry` to be used for reporting metrics. If
663 /// `metricsRegistry` is 0, `bdlm::MetricsRegistry::singleton()` is used.
664 /// Optionally specify a `basicAllocator` used to supply memory. If
665 /// `basicAllocator` is 0, the currently installed default allocator is used.
666 ///
667 /// \note Note that the maximal number of scheduled non-recurring events
668 /// and recurring events defaults to an implementation defined constant.
669 explicit TimerEventScheduler(const bsl::string_view& eventSchedulerName,
670 bdlm::MetricsRegistry *metricsRegistry,
671 bslma::Allocator *basicAllocator = 0);
672
673 /// Construct an event scheduler using the default dispatcher functor
674 /// (see the "The dispatcher thread and the dispatcher functor" section
675 /// in component-level doc) and use the specified `clockType` to
676 /// indicate the epoch used for all time intervals (see
677 /// @ref bdlmt_timereventscheduler-supported-clock-types ). Optionally specify a `basicAllocator`
678 /// used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
679 ///
680 /// \note Note that the maximal number of
681 /// scheduled non-recurring events and recurring events defaults to an
682 /// implementation defined constant.
685 bslma::Allocator *basicAllocator = 0);
686
687 /// Construct an event scheduler using the default dispatcher functor (see
688 /// the "The dispatcher thread and the dispatcher functor" section in
689 /// component-level doc), use the specified `clockType` to indicate the
690 /// epoch used for all time intervals (see []#(Supported Clock-Types)), the
691 /// specified `eventSchedulerName` to be used to identify this event
692 /// scheduler, and the specified `metricsRegistry` to be used for reporting
693 /// metrics. If `metricsRegistry` is 0,
694 /// `bdlm::MetricsRegistry::singleton()` is used. Optionally specify a
695 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
696 ///
697 /// \note Note that the maximal
698 /// number of scheduled non-recurring events and recurring events defaults
699 /// to an implementation defined constant.
702 const bsl::string_view& eventSchedulerName,
703 bdlm::MetricsRegistry *metricsRegistry,
704 bslma::Allocator *basicAllocator = 0);
705
706 /// Construct an event scheduler using the specified `dispatcherFunctor`
707 /// (see "The dispatcher thread and the dispatcher functor" section in
708 /// component-level doc) and use the realtime clock epoch for all time
709 /// intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ). Optionally specify a
710 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
711 ///
712 /// \note Note that the maximal
713 /// number of scheduled non-recurring events and recurring events defaults
714 /// to an implementation defined constant.
715 explicit TimerEventScheduler(const Dispatcher& dispatcherFunctor,
716 bslma::Allocator *basicAllocator = 0);
717
718 /// Construct an event scheduler using the specified `dispatcherFunctor`
719 /// (see "The dispatcher thread and the dispatcher functor" section in
720 /// component-level doc), use the realtime clock epoch for all time
721 /// intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ), the specified
722 /// `eventSchedulerName` to be used to identify this event scheduler, and
723 /// the specified `metricsRegistry` to be used for reporting metrics. If
724 /// `metricsRegistry` is 0, `bdlm::MetricsRegistry::singleton()` is used.
725 /// Optionally specify a `basicAllocator` used to supply memory. If
726 /// `basicAllocator` is 0, the currently installed default allocator is used.
727 ///
728 /// \note Note that the maximal number of scheduled non-recurring events
729 /// and recurring events defaults to an implementation defined constant.
730 explicit TimerEventScheduler(const Dispatcher& dispatcherFunctor,
731 const bsl::string_view& eventSchedulerName,
732 bdlm::MetricsRegistry *metricsRegistry,
733 bslma::Allocator *basicAllocator = 0);
734
735 /// Construct an event scheduler using the specified `dispatcherFunctor`
736 /// (see "The dispatcher thread and the dispatcher functor" section in
737 /// component-level doc) and use the specified `clockType` to indicate the
738 /// epoch used for all time intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ).
739 /// Optionally specify a `basicAllocator` used to supply memory. If
740 /// `basicAllocator` is 0, the currently installed default allocator is used.
741 ///
742 /// \note Note that the maximal number of scheduled non-recurring events
743 /// and recurring events defaults to an implementation defined constant.
745 const Dispatcher& dispatcherFunctor,
747 bslma::Allocator *basicAllocator = 0);
748
749 /// Construct an event scheduler using the specified `dispatcherFunctor`
750 /// (see "The dispatcher thread and the dispatcher functor" section in
751 /// component-level doc), use the specified `clockType` to indicate the
752 /// epoch used for all time intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ), the
753 /// specified `eventSchedulerName` to be used to identify this event
754 /// scheduler, and the specified `metricsRegistry` to be used for reporting
755 /// metrics. If `metricsRegistry` is 0,
756 /// `bdlm::MetricsRegistry::singleton()` is used. Optionally specify a
757 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
758 ///
759 /// \note Note that the maximal
760 /// number of scheduled non-recurring events and recurring events defaults
761 /// to an implementation defined constant.
763 const Dispatcher& dispatcherFunctor,
765 const bsl::string_view& eventSchedulerName,
766 bdlm::MetricsRegistry *metricsRegistry,
767 bslma::Allocator *basicAllocator = 0);
768
769 /// Construct a timer event scheduler using the default dispatcher functor
770 /// (see the "The dispatcher thread and the dispatcher functor" section in
771 /// component level doc) that has the capability to concurrently schedule
772 /// *at* *least* the specified `numEvents` and `numClocks` and use the
773 /// realtime clock epoch for all time intervals (see
774 /// @ref bdlmt_timereventscheduler-supported-clock-types ). Optionally specify a `basicAllocator`
775 /// used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
776 ///
777 /// \pre The behavior is undefined unless
778 /// `0 <= numEvents < 2**24` and `0 <= numClocks < 2**24`.
780 int numClocks,
781 bslma::Allocator *basicAllocator = 0);
782
783 /// Construct a timer event scheduler using the default dispatcher
784 /// functor (see the "The dispatcher thread and the dispatcher functor"
785 /// section in component level doc) that has the capability to
786 /// concurrently schedule *at* *least* the specified `numEvents` and
787 /// `numClocks`, use the realtime clock epoch for all time intervals
788 /// (see @ref bdlmt_timereventscheduler-supported-clock-types ), the specified `eventSchedulerName` to
789 /// be used to identify this event scheduler, and the specified
790 /// `metricsRegistry` to be used for reporting metrics. If
791 /// `metricsRegistry` is 0, `bdlm::MetricsRegistry::singleton()` is used.
792 /// Optionally specify a `basicAllocator` used to supply memory. If
793 /// `basicAllocator` is 0, the currently installed default allocator is used.
794 ///
795 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and
796 /// `0 <= numClocks < 2**24`.
798 int numClocks,
799 const bsl::string_view& eventSchedulerName,
800 bdlm::MetricsRegistry *metricsRegistry,
801 bslma::Allocator *basicAllocator = 0);
802
803 /// Construct a timer event scheduler using the default dispatcher functor
804 /// (see the "The dispatcher thread and the dispatcher functor" section in
805 /// component level doc) that has the capability to concurrently schedule
806 /// *at* *least* the specified `numEvents` and `numClocks` and use the
807 /// specified `clockType` to indicate the epoch used for all time intervals
808 /// (see @ref bdlmt_timereventscheduler-supported-clock-types ). Optionally specify a
809 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
810 /// currently installed default allocator is used.
811 ///
812 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and `0 <= numClocks < 2**24`.
814 int numClocks,
816 bslma::Allocator *basicAllocator = 0);
817
818 /// Construct a timer event scheduler using the default dispatcher functor
819 /// (see the "The dispatcher thread and the dispatcher functor" section in
820 /// component level doc) that has the capability to concurrently schedule
821 /// *at* *least* the specified `numEvents` and `numClocks`, use the
822 /// specified `clockType` to indicate the epoch used for all time intervals
823 /// (see @ref bdlmt_timereventscheduler-supported-clock-types in the component documentation), the
824 /// specified `eventSchedulerName` to be used to identify this event
825 /// scheduler, and the specified `metricsRegistry` to be used for reporting
826 /// metrics. If `metricsRegistry` is 0,
827 /// `bdlm::MetricsRegistry::singleton()` is used. Optionally specify a
828 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
829 /// currently installed default allocator is used.
830 ///
831 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and `0 <= numClocks < 2**24`.
833 int numClocks,
835 const bsl::string_view& eventSchedulerName,
836 bdlm::MetricsRegistry *metricsRegistry,
837 bslma::Allocator *basicAllocator = 0);
838
839 /// Construct a timer event scheduler using the specified
840 /// `dispatcherFunctor` (see "The dispatcher thread and the dispatcher
841 /// functor" section in component level doc) that has the capability to
842 /// concurrently schedule *at* *least* the specified `numEvents` and
843 /// `numClocks` and use the realtime clock epoch for all time intervals
844 /// (see @ref bdlmt_timereventscheduler-supported-clock-types ). Optionally specify a
845 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
846 /// currently installed default allocator is used.
847 ///
848 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and `0 <= numClocks < 2**24`.
850 int numClocks,
851 const Dispatcher& dispatcherFunctor,
852 bslma::Allocator *basicAllocator = 0);
853
854 /// Construct a timer event scheduler using the specified
855 /// `dispatcherFunctor` (see "The dispatcher thread and the dispatcher
856 /// functor" section in component level doc) that has the capability to
857 /// concurrently schedule **at least** the specified `numEvents` and
858 /// `numClocks`, use the realtime clock epoch for all time intervals (see
859 /// @ref bdlmt_timereventscheduler-supported-clock-types ), the specified `eventSchedulerName` to be
860 /// used to identify this event scheduler, and the specified
861 /// `metricsRegistry` to be used for reporting metrics. If
862 /// `metricsRegistry` is 0, `bdlm::MetricsRegistry::singleton()` is used.
863 /// Optionally specify a `basicAllocator` used to supply memory. If
864 /// `basicAllocator` is 0, the currently installed default allocator is used.
865 ///
866 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and
867 /// `0 <= numClocks < 2**24`.
869 int numClocks,
870 const Dispatcher& dispatcherFunctor,
871 const bsl::string_view& eventSchedulerName,
872 bdlm::MetricsRegistry *metricsRegistry,
873 bslma::Allocator *basicAllocator = 0);
874
875 /// Construct a timer event scheduler using the specified
876 /// `dispatcherFunctor` (see "The dispatcher thread and the dispatcher
877 /// functor" section in component level doc) that has the capability to
878 /// concurrently schedule **at least** the specified `numEvents` and
879 /// `numClocks` and use the specified `clockType` to indicate the epoch
880 /// used for all time intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ).
881 /// Optionally specify a `basicAllocator` used to supply memory. If
882 /// `basicAllocator` is 0, the currently installed default allocator is used.
883 ///
884 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and
885 /// `0 <= numClocks < 2**24`.
887 int numClocks,
888 const Dispatcher& dispatcherFunctor,
890 bslma::Allocator *basicAllocator = 0);
891
892 /// Construct a timer event scheduler using the specified
893 /// `dispatcherFunctor` (see "The dispatcher thread and the dispatcher
894 /// functor" section in component level doc) that has the capability to
895 /// concurrently schedule **at least** the specified `numEvents` and
896 /// `numClocks`, use the specified `clockType` to indicate the epoch
897 /// used for all time intervals (see @ref bdlmt_timereventscheduler-supported-clock-types ), the
898 /// specified `eventSchedulerName` to be used to identify this event
899 /// scheduler, and the specified `metricsRegistry` to be used for reporting
900 /// metrics. If `metricsRegistry` is 0,
901 /// `bdlm::MetricsRegistry::singleton()` is used. Optionally specify a
902 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
903 /// currently installed default allocator is used.
904 ///
905 /// \pre The behavior is undefined unless `0 <= numEvents < 2**24` and `0 <= numClocks < 2**24`.
907 int numClocks,
908 const Dispatcher& dispatcherFunctor,
910 const bsl::string_view& eventSchedulerName,
911 bdlm::MetricsRegistry *metricsRegistry,
912 bslma::Allocator *basicAllocator = 0);
913
914 /// Stop this scheduler, discard all the unprocessed events and destroy
915 /// this object.
917
918 // MANIPULATORS
919
920 /// Begin dispatching events on this scheduler using default attributes
921 /// for the dispatcher thread. Return 0 on success, and a nonzero value
922 /// otherwise. If another thread is currently executing `stop`, wait
923 /// until the dispatcher thread stops before starting a new one. If
924 /// this scheduler has already started (and is not currently being
925 /// stopped by another thread) then this invocation has no effect and 0
926 /// is returned. The created thread will use the `eventSchedulerName`
927 /// supplied at construction if it is not empty, otherwise "bdl.TimerEvent".
928 ///
929 /// \pre The behavior is undefined if this method is invoked
930 /// in the dispatcher thread (i.e., in a job executed by this scheduler).
931 ///
932 /// \note Note that any event whose time has already passed is pending and
933 /// will be dispatched immediately.
934 int start();
935
936 /// Begin dispatching events on this scheduler using the specified
937 /// `threadAttributes` for the dispatcher thread (except that the
938 /// DETACHED attribute is ignored). Return 0 on success, and a nonzero
939 /// value otherwise. If another thread is currently executing `stop`,
940 /// wait until the dispatcher thread stops before starting a new one.
941 /// If this scheduler has already started (and is not currently being
942 /// stopped by another thread) then this invocation has no effect and 0
943 /// is returned. The created thread will use the name
944 /// `threadAttributes.getThreadName()` if it is not empty, otherwise
945 /// `eventSchedulerName` supplied at construction if it is not empty, otherwise "bdl.TimerEvent".
946 ///
947 /// \pre The behavior is undefined if this method
948 /// is invoked in the dispatcher thread (i.e., in a job executed by this scheduler).
949 ///
950 /// \note Note that any event whose time has already passed is
951 /// pending and will be dispatched immediately.
952 int start(const bslmt::ThreadAttributes& threadAttributes);
953
954 /// End the dispatching of events on this scheduler (but do not remove any
955 /// pending events), and wait for any (one) currently executing event to
956 /// complete. If the scheduler is already stopped then this method has no
957 /// effect. This scheduler can be restarted by invoking `start`.
958 ///
959 /// \pre The behavior is undefined if this method is invoked from the dispatcher
960 /// thread.
961 void stop();
962
963 /// Schedule the specified `callback` to be dispatched at the specified
964 /// `time`. On success, return a handle that can be used to cancel the
965 /// `callback` (by invoking `cancelEvent`), or return `e_INVALID_HANDLE` if
966 /// scheduling this event would exceed the maximum number of scheduled
967 /// events for this object (see constructor). Optionally specify `key` to
968 /// uniquely identify the event. The `time` is an absolute time
969 /// represented as an interval from some epoch, which is detemined by the
970 /// clock indicated at construction (see @ref bdlmt_timereventscheduler-supported-clock-types ).
972 const bsl::function<void()>& callback,
973 const EventKey& key = EventKey(0));
974
975 /// Reschedule the event having the specified `handle` at the specified
976 /// `newTime`. Optionally use the specified `key` to uniquely identify the
977 /// event. If the optionally specified `wait` is true, then ensure that
978 /// the event having the `handle` (if it is valid) is either successfully
979 /// rescheduled or dispatched before the call returns. Return 0 on
980 /// successful reschedule, and a non-zero value if the `handle` is invalid
981 /// *or* if the event has already been dispatched *or* if the event has not
982 /// yet been dispatched but will soon be dispatched. If this method is
983 /// being invoked from the dispatcher thread then the `wait` is ignored to
984 /// avoid deadlock. The `newTime` is an absolute time represented as an
985 /// interval from some epoch, which is detemined by the clock indicated at
986 /// construction (see @ref bdlmt_timereventscheduler-supported-clock-types ).
987 int rescheduleEvent(Handle handle,
988 const bsls::TimeInterval& newTime,
989 bool wait = false);
991 const EventKey& key,
992 const bsls::TimeInterval& newTime,
993 bool wait = false);
994
995 /// Cancel the event having the specified `handle`. Optionally use the
996 /// specified `key` to uniquely identify the event. If the optionally
997 /// specified `wait` is true, then ensure that the dispatcher thread has
998 /// resumed execution before returning. Return 0 on successful
999 /// cancellation, and a non-zero value if the `handle` is invalid *or* if
1000 /// it is too late to cancel the event. If this method is being invoked
1001 /// from the dispatcher thread then the `wait` is ignored to avoid
1002 /// deadlock.
1003 int cancelEvent(Handle handle, bool wait = false);
1004 int cancelEvent(Handle handle, const EventKey& key, bool wait = false);
1005
1006 /// Cancel all the events. If the optionally specified `wait` is true,
1007 /// then ensure any event still in this scheduler is either cancelled or
1008 /// has been dispatched before this call returns. If this method is being
1009 /// invoked from the dispatcher thread then the `wait` is ignored to avoid
1010 /// deadlock.
1011 void cancelAllEvents(bool wait = false);
1012
1013 /// Schedule a recurring event that invokes the specified `callback` at
1014 /// every specified `interval`, starting at the optionally specified
1015 /// `startTime`. On success, return a handle that can be use to cancel the
1016 /// clock (by invoking `cancelClock`), or return `e_INVALID_HANDLE` if
1017 /// scheduling this event would exceed the maximum number of scheduled
1018 /// events for this object (see constructor). If no start time is
1019 /// specified, it is assumed to be the `interval` time from now. The
1020 /// `startTime` is an absolute time represented as an interval from some
1021 /// epoch, which is detemined by the clock indicated at construction (see
1022 /// @ref bdlmt_timereventscheduler-supported-clock-types ).
1024 const bsls::TimeInterval& interval,
1025 const bsl::function<void()>& callback,
1026 const bsls::TimeInterval& startTime = bsls::TimeInterval(0));
1027
1028 /// Cancel the clock having the specified `handle`. If the optionally
1029 /// specified `wait` is true, then ensure that any scheduled event for the
1030 /// clock having `handle` is either cancelled or has been dispatched before
1031 /// this call returns. Return 0 on success, and a non-zero value if the
1032 /// `handle` is invalid. If this method is being invoked from the
1033 /// dispatcher thread, then the `wait` is ignored to avoid deadlock.
1034 int cancelClock(Handle handle, bool wait = false);
1035
1036 /// Cancel all clocks. If the optionally specified `wait` is true, then
1037 /// ensure that any clock event still in this scheduler is either cancelled
1038 /// or has been dispatched before this call returns. If this method is
1039 /// being invoked from the dispatcher thread, then the `wait` is ignored to
1040 /// avoid deadlock.
1041 void cancelAllClocks(bool wait = false);
1042
1043 // ACCESSORS
1044
1045 /// Return the value of the clock type that this object was created with.
1047
1048 /// Return the current epoch time, an absolute time represented as an
1049 /// interval from some epoch, which is determined by the clock indicated at
1050 /// construction (see @ref bdlmt_timereventscheduler-supported-clock-types ).
1051 bsls::TimeInterval now() const;
1052
1053 /// Return a *snapshot* of the number of registered clocks with this
1054 /// scheduler.
1055 int numClocks() const;
1056
1057 /// Return a *snapshot* of the number of pending events and events being
1058 /// dispatched in this scheduler.
1059 int numEvents() const;
1060
1061 /// Return the earliest scheduled starting time of the pending events and
1062 /// clocks registered with this scheduler. If there are no pending events
1063 /// or clocks, return `INT64_MAX` microseconds.
1065};
1066
1067 // =======================================
1068 // class TimerEventSchedulerTestTimeSource
1069 // =======================================
1070
1071/// This class provides a means to change the clock that is used by a given
1072/// event-scheduler to determine when events should be triggered. Constructing
1073/// a `TimerEventSchedulerTestTimeSource` alters the behavior of the supplied
1074/// event-scheduler. After a test time-source is created, the underlying
1075/// scheduler will run events according to a discrete timeline, whose
1076/// successive values are determined by calls to `advanceTime` on the test
1077/// time-source, and can be retrieved by calling `now` on that test time-source.
1078///
1079/// \note Note that the "system-time" held by a test time-source *does*
1080/// *not* correspond to the current system time. Test writers must use caution
1081/// when scheduling absolute-time events so that they are scheduled relative to
1082/// the test time-source's value for `now`.
1083///
1084/// See @ref bdlmt_timereventscheduler
1086
1087 private:
1088 // DATA
1090 d_data_p; // shared pointer to the state whose
1091 // lifetime must be as long as
1092 // `*this` and `*d_scheduler_p`
1093
1094 TimerEventScheduler *d_scheduler_p; // pointer to the scheduler that we
1095 // are augmenting
1096
1097 public:
1098 // CREATORS
1099
1100 /// Construct a test time-source object that will control the "system-time"
1101 /// observed by the specified `scheduler`. Initialize `now` to be an arbitrary time value.
1102 ///
1103 /// \pre The behavior is undefined if any methods have
1104 /// previously been called on `scheduler`.
1105 explicit
1107
1108 // MANIPULATORS
1109
1110 /// Advance this object's current-time value by the specified `amount` of
1111 /// time, and notify the scheduler that the time has changed. Return the updated current-time value.
1112 ///
1113 /// \pre The behavior is undefined unless `amount`
1114 /// represents a positive time interval, and `now + amount` is within the
1115 /// range that can be represented with a `bsls::TimeInterval`.
1117
1118 // ACCESSORS
1119
1120 /// Return this object's current-time value. Upon construction, this
1121 /// method will return an arbitrary value. Subsequent calls to
1122 /// `advanceTime` will adjust the arbitrary value forward.
1124};
1125
1126// ============================================================================
1127// INLINE DEFINITIONS
1128// ============================================================================
1129
1130 // -------------------
1131 // TimerEventScheduler
1132 // -------------------
1133
1134// MANIPULATORS
1135inline
1137 bool wait)
1138{
1139 return cancelEvent(handle, EventKey(0), wait);
1140}
1141
1142inline
1144 const bsls::TimeInterval& newTime,
1145 bool wait)
1146{
1147 return rescheduleEvent(handle, EventKey(0), newTime, wait);
1148}
1149
1150// ACCESSORS
1151inline
1153{
1154 return d_clockType;
1155}
1156
1157inline
1159{
1160 return d_currentTimeFunctor();
1161}
1162
1163inline
1165{
1166 return d_numClocks;
1167}
1168
1169inline
1171{
1172 return d_numEvents;
1173}
1174
1175} // close package namespace
1176
1177
1178#endif
1179
1180// ----------------------------------------------------------------------------
1181// Copyright 2024 Bloomberg Finance L.P.
1182//
1183// Licensed under the Apache License, Version 2.0 (the "License");
1184// you may not use this file except in compliance with the License.
1185// You may obtain a copy of the License at
1186//
1187// http://www.apache.org/licenses/LICENSE-2.0
1188//
1189// Unless required by applicable law or agreed to in writing, software
1190// distributed under the License is distributed on an "AS IS" BASIS,
1191// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1192// See the License for the specific language governing permissions and
1193// limitations under the License.
1194// ----------------------------- END-OF-FILE ----------------------------------
1195
1196/** @} */
1197/** @} */
1198/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition bdlcc_objectcatalog.h:410
Definition bdlcc_timequeue.h:1193
Definition bdlcc_timequeue.h:759
Definition bdlcc_timequeue.h:734
Definition bdlm_metricsregistry.h:306
Definition bdlm_metricsregistry.h:197
Definition bdlma_concurrentpool.h:332
Definition bdlmt_timereventscheduler.h:1085
TimerEventSchedulerTestTimeSource(TimerEventScheduler *scheduler)
bsls::TimeInterval now() const
bsls::TimeInterval advanceTime(bsls::TimeInterval amount)
Definition bdlmt_timereventscheduler.h:445
int Handle
Definition bdlmt_timereventscheduler.h:506
int rescheduleEvent(Handle handle, const bsls::TimeInterval &newTime, bool wait=false)
Definition bdlmt_timereventscheduler.h:1143
TimerEventScheduler(bsls::SystemClockType::Enum clockType, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(bsls::SystemClockType::Enum clockType, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(int numEvents, int numClocks, const Dispatcher &dispatcherFunctor, bsls::SystemClockType::Enum clockType, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(int numEvents, int numClocks, const Dispatcher &dispatcherFunctor, bslma::Allocator *basicAllocator=0)
bsls::SystemClockType::Enum clockType() const
Return the value of the clock type that this object was created with.
Definition bdlmt_timereventscheduler.h:1152
int numClocks() const
Definition bdlmt_timereventscheduler.h:1164
void cancelAllClocks(bool wait=false)
int numEvents() const
Definition bdlmt_timereventscheduler.h:1170
TimerEventScheduler(int numEvents, int numClocks, bsls::SystemClockType::Enum clockType, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
@ BCEP_INVALID_HANDLE
Definition bdlmt_timereventscheduler.h:518
@ e_INVALID_HANDLE
Definition bdlmt_timereventscheduler.h:516
@ INVALID_HANDLE
Definition bdlmt_timereventscheduler.h:519
TimerEventScheduler(const Dispatcher &dispatcherFunctor, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(int numEvents, int numClocks, bslma::Allocator *basicAllocator=0)
Handle startClock(const bsls::TimeInterval &interval, const bsl::function< void()> &callback, const bsls::TimeInterval &startTime=bsls::TimeInterval(0))
TimerEventScheduler(int numEvents, int numClocks, const Dispatcher &dispatcherFunctor, bsls::SystemClockType::Enum clockType, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(const Dispatcher &dispatcherFunctor, bsls::SystemClockType::Enum clockType, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
void cancelAllEvents(bool wait=false)
bsls::TimeInterval nextPendingEventTime() const
bdlcc::TimeQueue< bsl::function< void()> >::Key EventKey
Defines a type alias for a user-supplied key for identifying events.
Definition bdlmt_timereventscheduler.h:512
int rescheduleEvent(Handle handle, const EventKey &key, const bsls::TimeInterval &newTime, bool wait=false)
bsls::TimeInterval now() const
Definition bdlmt_timereventscheduler.h:1158
Handle scheduleEvent(const bsls::TimeInterval &time, const bsl::function< void()> &callback, const EventKey &key=EventKey(0))
bsl::function< void(const bsl::function< void()> &)> Dispatcher
Defines a type alias for the dispatcher functor type.
Definition bdlmt_timereventscheduler.h:509
TimerEventScheduler(int numEvents, int numClocks, const Dispatcher &dispatcherFunctor, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(int numEvents, int numClocks, const bsl::string_view &eventSchedulerName, bdlm::MetricsRegistry *metricsRegistry, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(bslma::Allocator *basicAllocator=0)
BSLMF_NESTED_TRAIT_DECLARATION(TimerEventScheduler, bslma::UsesBslmaAllocator)
TimerEventScheduler(const Dispatcher &dispatcherFunctor, bslma::Allocator *basicAllocator=0)
TimerEventScheduler(const Dispatcher &dispatcherFunctor, bsls::SystemClockType::Enum clockType, bslma::Allocator *basicAllocator=0)
int cancelEvent(Handle handle, const EventKey &key, bool wait=false)
int cancelClock(Handle handle, bool wait=false)
int start(const bslmt::ThreadAttributes &threadAttributes)
int cancelEvent(Handle handle, bool wait=false)
Definition bdlmt_timereventscheduler.h:1136
friend struct TimerEventSchedulerDispatcher
Definition bdlmt_timereventscheduler.h:623
TimerEventScheduler(int numEvents, int numClocks, bsls::SystemClockType::Enum clockType, bslma::Allocator *basicAllocator=0)
Definition bslma_bslallocator.h:588
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
Forward declaration.
Definition bslstl_function.h:946
Definition bslstl_sharedptr.h:1838
Definition bslstl_vector.h:1120
Definition bslma_allocator.h:545
Definition bslmt_condition.h:220
Definition bslmt_mutex.h:317
Definition bslmt_threadattributes.h:361
Definition bsls_atomic.h:1490
Definition bsls_atomic.h:896
Definition bsls_atomic.h:744
Definition bsls_timeinterval.h:307
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlmt_eventscheduler.h:550
Definition bslmf_allocatorargt.h:433
Definition bslma_usesbslmaallocator.h:344
Imp::Handle Handle
Definition bslmt_threadutil.h:389
Enum
Definition bsls_systemclocktype.h:119