Coverage Report

Created: 2026-07-30 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmlibuv/src/timer.c
Line
Count
Source
1
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
 * Permission is hereby granted, free of charge, to any person obtaining a copy
3
 * of this software and associated documentation files (the "Software"), to
4
 * deal in the Software without restriction, including without limitation the
5
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6
 * sell copies of the Software, and to permit persons to whom the Software is
7
 * furnished to do so, subject to the following conditions:
8
 *
9
 * The above copyright notice and this permission notice shall be included in
10
 * all copies or substantial portions of the Software.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18
 * IN THE SOFTWARE.
19
 */
20
21
#include "uv.h"
22
#include "uv-common.h"
23
#include "heap-inl.h"
24
25
#include <limits.h>
26
27
28
0
static struct heap *timer_heap(const uv_loop_t* loop) {
29
#ifdef _WIN32
30
  return (struct heap*) loop->timer_heap;
31
#else
32
0
  return (struct heap*) &loop->timer_heap;
33
0
#endif
34
0
}
35
36
37
static int timer_less_than(const struct heap_node* ha,
38
0
                           const struct heap_node* hb) {
39
0
  const uv_timer_t* a;
40
0
  const uv_timer_t* b;
41
42
0
  a = container_of(ha, uv_timer_t, node.heap);
43
0
  b = container_of(hb, uv_timer_t, node.heap);
44
45
0
  if (a->timeout < b->timeout)
46
0
    return 1;
47
0
  if (b->timeout < a->timeout)
48
0
    return 0;
49
50
  /* Compare start_id when both have the same timeout. start_id is
51
   * allocated with loop->timer_counter in uv_timer_start().
52
   */
53
0
  return a->start_id < b->start_id;
54
0
}
55
56
57
0
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
58
0
  uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
59
0
  handle->timer_cb = NULL;
60
0
  handle->timeout = 0;
61
0
  handle->repeat = 0;
62
0
  uv__queue_init(&handle->node.queue);
63
0
  return 0;
64
0
}
65
66
67
int uv_timer_start(uv_timer_t* handle,
68
                   uv_timer_cb cb,
69
                   uint64_t timeout,
70
0
                   uint64_t repeat) {
71
0
  uint64_t clamped_timeout;
72
73
0
  if (uv__is_closing(handle) || cb == NULL)
74
0
    return UV_EINVAL;
75
76
0
  uv_timer_stop(handle);
77
78
0
  clamped_timeout = handle->loop->time + timeout;
79
0
  if (clamped_timeout < timeout)
80
0
    clamped_timeout = (uint64_t) -1;
81
82
0
  handle->timer_cb = cb;
83
0
  handle->timeout = clamped_timeout;
84
0
  handle->repeat = repeat;
85
  /* start_id is the second index to be compared in timer_less_than() */
86
0
  handle->start_id = handle->loop->timer_counter++;
87
88
0
  heap_insert(timer_heap(handle->loop),
89
0
              (struct heap_node*) &handle->node.heap,
90
0
              timer_less_than);
91
0
  uv__handle_start(handle);
92
93
0
  return 0;
94
0
}
95
96
97
0
int uv_timer_stop(uv_timer_t* handle) {
98
0
  if (uv__is_active(handle)) {
99
0
    heap_remove(timer_heap(handle->loop),
100
0
                (struct heap_node*) &handle->node.heap,
101
0
                timer_less_than);
102
0
    uv__handle_stop(handle);
103
0
  } else {
104
0
    uv__queue_remove(&handle->node.queue);
105
0
  }
106
107
0
  uv__queue_init(&handle->node.queue);
108
0
  return 0;
109
0
}
110
111
112
0
int uv_timer_again(uv_timer_t* handle) {
113
0
  if (handle->timer_cb == NULL)
114
0
    return UV_EINVAL;
115
116
0
  if (handle->repeat) {
117
0
    uv_timer_stop(handle);
118
0
    uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
119
0
  }
120
121
0
  return 0;
122
0
}
123
124
125
0
void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
126
0
  handle->repeat = repeat;
127
0
}
128
129
130
0
uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
131
0
  return handle->repeat;
132
0
}
133
134
135
0
uint64_t uv_timer_get_due_in(const uv_timer_t* handle) {
136
0
  if (handle->loop->time >= handle->timeout)
137
0
    return 0;
138
139
0
  return handle->timeout - handle->loop->time;
140
0
}
141
142
143
0
int uv__next_timeout(const uv_loop_t* loop) {
144
0
  const struct heap_node* heap_node;
145
0
  const uv_timer_t* handle;
146
0
  uint64_t diff;
147
148
0
  heap_node = heap_min(timer_heap(loop));
149
0
  if (heap_node == NULL)
150
0
    return -1; /* block indefinitely */
151
152
0
  handle = container_of(heap_node, uv_timer_t, node.heap);
153
0
  if (handle->timeout <= loop->time)
154
0
    return 0;
155
156
0
  diff = handle->timeout - loop->time;
157
0
  if (diff > INT_MAX)
158
0
    diff = INT_MAX;
159
160
0
  return (int) diff;
161
0
}
162
163
164
0
void uv__run_timers(uv_loop_t* loop) {
165
0
  struct heap_node* heap_node;
166
0
  uv_timer_t* handle;
167
0
  struct uv__queue* queue_node;
168
0
  struct uv__queue ready_queue;
169
170
0
  uv__queue_init(&ready_queue);
171
172
0
  for (;;) {
173
0
    heap_node = heap_min(timer_heap(loop));
174
0
    if (heap_node == NULL)
175
0
      break;
176
177
0
    handle = container_of(heap_node, uv_timer_t, node.heap);
178
0
    if (handle->timeout > loop->time)
179
0
      break;
180
181
0
    uv_timer_stop(handle);
182
0
    uv__queue_insert_tail(&ready_queue, &handle->node.queue);
183
0
  }
184
185
0
  while (!uv__queue_empty(&ready_queue)) {
186
0
    queue_node = uv__queue_head(&ready_queue);
187
0
    uv__queue_remove(queue_node);
188
0
    uv__queue_init(queue_node);
189
0
    handle = container_of(queue_node, uv_timer_t, node.queue);
190
191
0
    uv_timer_again(handle);
192
0
    handle->timer_cb(handle);
193
0
  }
194
0
}
195
196
197
0
void uv__timer_close(uv_timer_t* handle) {
198
0
  uv_timer_stop(handle);
199
0
}