summaryrefslogtreecommitdiffstats
path: root/xpcom/threads/nsITimer.idl
blob: 5d20c315b40ab3edbd25e3718ff5e21a7107c363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"
#include  "nsINamed.idl"

interface nsIObserver;
interface nsIEventTarget;

%{C++
#include "mozilla/MemoryReporting.h"
#include "mozilla/TimeStamp.h"
#include <functional>

/**
 * The signature of the timer callback function passed to initWithFuncCallback.
 * This is the function that will get called when the timer expires if the
 * timer is initialized via initWithFuncCallback.
 *
 * @param aTimer the timer which has expired
 * @param aClosure opaque parameter passed to initWithFuncCallback
 */
class nsITimer;
typedef void (*nsTimerCallbackFunc) (nsITimer *aTimer, void *aClosure);
%}

native MallocSizeOf(mozilla::MallocSizeOf);
native nsTimerCallbackFunc(nsTimerCallbackFunc);
[ref] native TimeDuration(mozilla::TimeDuration);

/**
 * The callback interface for timers.
 */
interface nsITimer;

[function, scriptable, uuid(a796816d-7d47-4348-9ab8-c7aeb3216a7d)]
interface nsITimerCallback : nsISupports
{
  /**
   * @param aTimer the timer which has expired
   */
  void notify(in nsITimer timer);
};

%{C++
// Two timer deadlines must differ by less than half the PRIntervalTime domain.
#define DELAY_INTERVAL_LIMIT    PR_BIT(8 * sizeof(PRIntervalTime) - 1)
%}

/**
 * nsITimer instances must be initialized by calling one of the "init" methods
 * documented below.  You may also re-initialize (using one of the init()
 * methods) an existing instance to avoid the overhead of destroying and
 * creating a timer.  It is not necessary to cancel the timer in that case.
 *
 * By default a timer will fire on the thread that created it.  Set the .target
 * attribute to fire on a different thread.  Once you have set a timer's .target
 * and called one of its init functions, any further interactions with the timer
 * (calling cancel(), changing member fields, etc) should only be done by the
 * target thread, or races may occur with bad results like timers firing after
 * they've been canceled, and/or not firing after re-initiatization.
 */
[scriptable, builtinclass, uuid(3de4b105-363c-482c-a409-baac83a01bfc)]
interface nsITimer : nsISupports
{
  /* Timer types */

  /**
   * Type of a timer that fires once only.
   */
  const short TYPE_ONE_SHOT = 0;

  /**
   * After firing, a TYPE_REPEATING_SLACK timer is stopped and not restarted
   * until its callback completes.  Specified timer period will be at least
   * the time between when processing for last firing the callback completes
   * and when the next firing occurs.
   *
   * This is the preferable repeating type for most situations.
   */
  const short TYPE_REPEATING_SLACK = 1;

  /**
   * TYPE_REPEATING_PRECISE is just a synonym for
   * TYPE_REPEATING_PRECISE_CAN_SKIP. They used to be distinct, but the old
   * TYPE_REPEATING_PRECISE kind was similar to TYPE_REPEATING_PRECISE_CAN_SKIP
   * while also being less useful. So the distinction was removed.
   */
  const short TYPE_REPEATING_PRECISE = 2;

  /**
   * A TYPE_REPEATING_PRECISE_CAN_SKIP repeating timer aims to have constant
   * period between firings.  The processing time for each timer callback will
   * not influence the timer period.  If the callback finishes after the next
   * firing(s) should have happened (either because the callback took a long
   * time, or the callback was called extremely late), that firing(s) is
   * skipped, but the following sequence of firing times will not be altered.
   * This timer type guarantees that it will not queue up new events to fire
   * the callback until the previous callback event finishes firing.  This is
   * the only non-slack timer available.
   */
  const short TYPE_REPEATING_PRECISE_CAN_SKIP = 3;

  /**
   * Same as TYPE_REPEATING_SLACK with the exception that idle events
   * won't yield to timers with this type.  Use this when you want an
   * idle callback to be scheduled to run even though this timer is
   * about to fire.
   */
  const short TYPE_REPEATING_SLACK_LOW_PRIORITY = 4;

  /**
   * Same as TYPE_ONE_SHOT with the exception that idle events won't
   * yield to timers with this type.  Use this when you want an idle
   * callback to be scheduled to run even though this timer is about
   * to fire.
   */
  const short TYPE_ONE_SHOT_LOW_PRIORITY = 5;

  /**
   * Initialize a timer that will fire after the said delay.
   * A user must keep a reference to this timer till it is
   * is no longer needed or has been cancelled.
   *
   * @param aObserver   the callback object that observes the
   *                    ``timer-callback'' topic with the subject being
   *                    the timer itself when the timer fires:
   *
   *                    observe(nsISupports aSubject, => nsITimer
   *                            string aTopic,        => ``timer-callback''
   *                            wstring data          =>  null
   *
   * @param aDelayInMs  delay in milliseconds for timer to fire
   * @param aType       timer type per TYPE* consts defined above
   */
  void init(in nsIObserver aObserver, in unsigned long aDelayInMs,
            in unsigned long aType);


  /**
   * Initialize a timer to fire after the given millisecond interval.
   * This version takes a callback object.
   *
   * @param aFunc       nsITimerCallback interface to call when timer expires
   * @param aDelayInMs  The millisecond interval
   * @param aType       Timer type per TYPE* consts defined above
   */
  void initWithCallback(in nsITimerCallback aCallback,
                        in unsigned long aDelayInMs,
                        in unsigned long aType);

  /**
   * Initialize a timer to fire after the high resolution TimeDuration.
   * This version takes a callback object.
   *
   * @param aFunc      nsITimerCallback interface to call when timer expires
   * @param aDelay     The high resolution interval
   * @param aType      Timer type per TYPE* consts defined above
   */
  [noscript] void initHighResolutionWithCallback(in nsITimerCallback aCallback,
                                                 [const] in TimeDuration aDelay,
                                                 in unsigned long aType);

  /**
   * Cancel the timer.  This method works on all types, not just on repeating
   * timers -- you might want to cancel a TYPE_ONE_SHOT timer, and even reuse
   * it by re-initializing it (to avoid object destruction and creation costs
   * by conserving one timer instance).
   */
  void cancel();

  /**
   * Like initWithFuncCallback, but also takes a name for the timer; the name
   * will be used when timer profiling is enabled via the "TimerFirings" log
   * module.
   *
   * @param aFunc      The function to invoke
   * @param aClosure   An opaque pointer to pass to that function
   * @param aDelay     The millisecond interval
   * @param aType      Timer type per TYPE* consts defined above
   * @param aName      The timer's name
   */
  [noscript] void initWithNamedFuncCallback(in nsTimerCallbackFunc aCallback,
                                            in voidPtr aClosure,
                                            in unsigned long aDelay,
                                            in unsigned long aType,
                                            in string aName);

  /**
   * Initialize a timer to fire after the high resolution TimeDuration.
   * This version takes a named function callback.
   *
   * @param aFunc      The function to invoke
   * @param aClosure   An opaque pointer to pass to that function
   * @param aDelay     The high resolution interval
   * @param aType      Timer type per TYPE* consts defined above
   * @param aName      The timer's name
   */
  [noscript] void initHighResolutionWithNamedFuncCallback(
                      in nsTimerCallbackFunc aCallback,
                      in voidPtr aClosure,
                      [const] in TimeDuration aDelay,
                      in unsigned long aType,
                      in string aName);

  /**
   * The millisecond delay of the timeout.
   *
   * NOTE: Re-setting the delay on a one-shot timer that has already fired
   * doesn't restart the timer. Call one of the init() methods to restart
   * a one-shot timer.
   */
  attribute unsigned long delay;

  /**
   * The timer type - one of the above TYPE_* constants.
   */
  attribute unsigned long type;

  /**
   * The opaque pointer pass to initWithFuncCallback.
   */
  [noscript] readonly attribute voidPtr closure;

  /**
   * The nsITimerCallback object passed to initWithCallback.
   */
  readonly attribute nsITimerCallback callback;

  /**
   * The nsIEventTarget where the callback will be dispatched. Note that this
   * target may only be set before the call to one of the init methods above.
   *
   * By default the target is the thread that created the timer.
   */
  attribute nsIEventTarget target;

  readonly attribute ACString name;

  /**
   * The number of microseconds this nsITimer implementation can possibly
   * fire early.
   */
  [noscript] readonly attribute unsigned long allowedEarlyFiringMicroseconds;

  [notxpcom, nostdcall] size_t sizeOfIncludingThis(in MallocSizeOf aMallocSizeOf);
};

%{C++
#include "nsCOMPtr.h"

already_AddRefed<nsITimer> NS_NewTimer();

already_AddRefed<nsITimer> NS_NewTimer(nsIEventTarget* aTarget);

nsresult
NS_NewTimerWithObserver(nsITimer** aTimer,
                        nsIObserver* aObserver,
                        uint32_t aDelay,
                        uint32_t aType,
                        nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithObserver(nsIObserver* aObserver,
                        uint32_t aDelay,
                        uint32_t aType,
                        nsIEventTarget* aTarget = nullptr);

nsresult
NS_NewTimerWithCallback(nsITimer** aTimer,
                        nsITimerCallback* aCallback,
                        uint32_t aDelay,
                        uint32_t aType,
                        nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithCallback(nsITimerCallback* aCallback,
                        uint32_t aDelay,
                        uint32_t aType,
                        nsIEventTarget* aTarget = nullptr);

nsresult
NS_NewTimerWithCallback(nsITimer** aTimer,
                        nsITimerCallback* aCallback,
                        const mozilla::TimeDuration& aDelay,
                        uint32_t aType,
                        nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithCallback(nsITimerCallback* aCallback,
                        const mozilla::TimeDuration& aDelay,
                        uint32_t aType,
                        nsIEventTarget* aTarget = nullptr);

nsresult
NS_NewTimerWithCallback(nsITimer** aTimer,
                        std::function<void(nsITimer*)>&& aCallback,
                        uint32_t aDelay,
                        uint32_t aType,
                        const char* aNameString,
                        nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithCallback(std::function<void(nsITimer*)>&& aCallback,
                        uint32_t aDelay,
                        uint32_t aType,
                        const char* aNameString,
                        nsIEventTarget* aTarget = nullptr);

nsresult
NS_NewTimerWithCallback(nsITimer** aTimer,
                        std::function<void(nsITimer*)>&& aCallback,
                        const mozilla::TimeDuration& aDelay,
                        uint32_t aType,
                        const char* aNameString,
                        nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithCallback(std::function<void(nsITimer*)>&& aCallback,
                        const mozilla::TimeDuration& aDelay,
                        uint32_t aType,
                        const char* aNameString,
                        nsIEventTarget* aTarget = nullptr);

nsresult
NS_NewTimerWithFuncCallback(nsITimer** aTimer,
                            nsTimerCallbackFunc aCallback,
                            void* aClosure,
                            uint32_t aDelay,
                            uint32_t aType,
                            const char* aNameString,
                            nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithFuncCallback(nsTimerCallbackFunc aCallback,
                            void* aClosure,
                            uint32_t aDelay,
                            uint32_t aType,
                            const char* aNameString,
                            nsIEventTarget* aTarget = nullptr);

nsresult
NS_NewTimerWithFuncCallback(nsITimer** aTimer,
                            nsTimerCallbackFunc aCallback,
                            void* aClosure,
                            const mozilla::TimeDuration& aDelay,
                            uint32_t aType,
                            const char* aNameString,
                            nsIEventTarget* aTarget = nullptr);
mozilla::Result<nsCOMPtr<nsITimer>, nsresult>
NS_NewTimerWithFuncCallback(nsTimerCallbackFunc aCallback,
                            void* aClosure,
                            const mozilla::TimeDuration& aDelay,
                            uint32_t aType,
                            const char* aNameString,
                            nsIEventTarget* aTarget = nullptr);

#define NS_TIMER_CALLBACK_TOPIC "timer-callback"

#ifndef RELEASE_OR_BETA
#undef NS_DECL_NSITIMERCALLBACK
#define NS_DECL_NSITIMERCALLBACK                                        \
  NS_IMETHOD Notify(nsITimer *timer) override;                          \
  inline void _ensure_GetName_exists(void) {                            \
    static_assert(std::is_convertible<decltype(this), nsINamed*>::value, \
                  "nsITimerCallback implementations must also implement nsINamed");     \
  }
#endif
%}

[scriptable, builtinclass, uuid(5482506d-1d21-4d08-b01c-95c87e1295ad)]
interface nsITimerManager : nsISupports
{
  /**
   * Returns a read-only list of nsITimer objects, implementing only the name,
   * delay and type attribute getters.
   * This is meant to be used for tests, to verify that no timer is leftover
   * at the end of a test. */
  Array<nsITimer> getTimers();
};