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