• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3638

11 Mar 2025 12:59PM UTC coverage: 3.066% (-18.3%) from 21.409%
#3638

push

travis-ci

web-flow
Merge pull request #30118 from taosdata/wl30

udpate ci workflow

5914 of 287117 branches covered (2.06%)

Branch coverage included in aggregate %.

11588 of 283747 relevant lines covered (4.08%)

142.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.9
/source/os/src/osTimer.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define ALLOW_FORBID_FUNC
17
#define _DEFAULT_SOURCE
18
#include "os.h"
19

20
#ifdef WINDOWS
21
#include <Mmsystem.h>
22
#include <Windows.h>
23
#include <stdint.h>
24
#include <stdio.h>
25

26
#pragma warning(disable : 4244)
27

28
typedef void (*win_timer_f)(int signo);
29

30
void WINAPI taosWinOnTimer(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dwl, DWORD_PTR dw2) {
31
  win_timer_f callback = *((win_timer_f *)&dwUser);
32
  if (callback != NULL) {
33
    callback(0);
34
  }
35
}
36

37
static MMRESULT timerId;
38

39
#elif defined(_TD_DARWIN_64)
40

41
#include <sys/event.h>
42
#include <sys/syscall.h>
43
#include <unistd.h>
44

45
static void (*timer_callback)(int);
46
static int          timer_ms = 0;
47
static TdThread     timer_thread;
48
static int          timer_kq = -1;
49
static volatile int timer_stop = 0;
50

51
static void* timer_routine(void* arg) {
52
  (void)arg;
53
  setThreadName("timer");
54

55
  int             r = 0;
56
  struct timespec to = {0};
57
  to.tv_sec = timer_ms / 1000;
58
  to.tv_nsec = (timer_ms % 1000) * 1000000;
59
  while (!timer_stop) {
60
    struct kevent64_s kev[10] = {0};
61
    r = kevent64(timer_kq, NULL, 0, kev, sizeof(kev) / sizeof(kev[0]), 0, &to);
62
    if (r != 0) {
63
      fprintf(stderr, "==%s[%d]%s()==kevent64 failed\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__);
64
      abort();
65
    }
66
    timer_callback(SIGALRM);  // just mock
67
  }
68

69
  return NULL;
70
}
71

72
void taos_block_sigalrm(void) {
73
  // we don't know if there's any specific API for SIGALRM to deliver to specific thread
74
  // this implementation relies on kqueue rather than SIGALRM
75
}
76

77
#else
78
#include <sys/syscall.h>
79
#include <unistd.h>
80

81
static void taosDeleteTimer(void *tharg) {
×
82
  timer_t *pTimer = tharg;
×
83
  TAOS_SKIP_ERROR(timer_delete(*pTimer));
×
84
}
×
85

86
static TdThread      timerThread;
87
static timer_t       timerId;
88
static volatile bool stopTimer = false;
89

90
#pragma GCC diagnostic push
91
#pragma GCC diagnostic ignored "-Wstringop-overflow"
92
static void *taosProcessAlarmSignal(void *tharg) {
4✔
93
  // Block the signal
94
  sigset_t sigset;
95
  (void)sigemptyset(&sigset);
4✔
96
  (void)sigaddset(&sigset, SIGALRM);
4✔
97
  (void)sigprocmask(SIG_BLOCK, &sigset, NULL);
4✔
98
  void (*callback)(int) = tharg;
4✔
99

100
  struct sigevent sevent = {{0}};
4✔
101

102
  setThreadName("tmr");
4✔
103

104
#ifdef _ALPINE
105
  sevent.sigev_notify = SIGEV_THREAD_ID;
106
  sevent.sigev_notify_thread_id = syscall(__NR_gettid);
107
#else
108
  sevent.sigev_notify = SIGEV_THREAD_ID;
4✔
109
  sevent._sigev_un._tid = syscall(__NR_gettid);
4✔
110
#endif
111

112
  sevent.sigev_signo = SIGALRM;
4✔
113

114
  if (timer_create(CLOCK_REALTIME, &sevent, &timerId) == -1) {
4!
115
    terrno = TAOS_SYSTEM_ERROR(errno);
×
116
    return NULL;
×
117
  }
118

119
  taosThreadCleanupPush(taosDeleteTimer, &timerId);
4!
120

121
  do {
122
    struct itimerspec ts;
123
    ts.it_value.tv_sec = 0;
4✔
124
    ts.it_value.tv_nsec = 1000000 * MSECONDS_PER_TICK;
4✔
125
    ts.it_interval.tv_sec = 0;
4✔
126
    ts.it_interval.tv_nsec = 1000000 * MSECONDS_PER_TICK;
4✔
127

128
    if (-1 == timer_settime(timerId, 0, &ts, NULL)) {
4!
129
      terrno = TAOS_SYSTEM_ERROR(errno);
×
130
      break;
×
131
    }
132

133
    int     signo;
134
    int32_t code = 0;
4✔
135
    while (!stopTimer) {
96,337!
136
      code = sigwait(&sigset, &signo);
96,337✔
137
      if (code) {
96,333!
138
        terrno = TAOS_SYSTEM_ERROR(code);
×
139
        continue;
×
140
      }
141
      /* //printf("Signal handling: number %d ......\n", signo); */
142
      callback(0);
96,333✔
143
    }
144
  } while (0);
145

146
  taosThreadCleanupPop(1);
×
147

148
  return NULL;
×
149
}
150
#pragma GCC diagnostic pop
151
#endif
152

153
int taosInitTimer(void (*callback)(int), int ms) {
4✔
154
#ifdef WINDOWS
155
  DWORD_PTR param = *((int64_t *)&callback);
156

157
  timerId = timeSetEvent(ms, 1, (LPTIMECALLBACK)taosWinOnTimer, param, TIME_PERIODIC);
158
  if (timerId == 0) {
159
    return -1;
160
  }
161
  return 0;
162
#elif defined(_TD_DARWIN_64)
163
  int r = 0;
164
  timer_kq = -1;
165
  timer_stop = 0;
166
  timer_ms = ms;
167
  timer_callback = callback;
168

169
  timer_kq = kqueue();
170
  if (timer_kq == -1) {
171
    fprintf(stderr, "==%s[%d]%s()==failed to create timer kq\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__);
172
    // since no caller of this func checks the return value for the moment
173
    abort();
174
  }
175

176
  r = taosThreadCreate(&timer_thread, NULL, timer_routine, NULL);
177
  if (r) {
178
    fprintf(stderr, "==%s[%d]%s()==failed to create timer thread\n", taosDirEntryBaseName(__FILE__), __LINE__,
179
            __func__);
180
    // since no caller of this func checks the return value for the moment
181
    abort();
182
  }
183
  return 0;
184
#else
185
  stopTimer = false;
4✔
186
  TdThreadAttr tattr;
187
  (void)taosThreadAttrInit(&tattr);
4✔
188
  int code = taosThreadCreate(&timerThread, &tattr, taosProcessAlarmSignal, callback);
4✔
189
  (void)taosThreadAttrDestroy(&tattr);
4✔
190
  if (code != 0) {
4!
191
    // printf("failed to create timer thread");
192
    return TAOS_SYSTEM_ERROR(code);
×
193
  }
194

195
  return 0;
4✔
196
#endif
197
}
198

199
void taosUninitTimer() {
×
200
#ifdef WINDOWS
201
  timeKillEvent(timerId);
202
#elif defined(_TD_DARWIN_64)
203
  int r = 0;
204
  timer_stop = 1;
205
  r = taosThreadJoin(timer_thread, NULL);
206
  if (r) {
207
    fprintf(stderr, "==%s[%d]%s()==failed to join timer thread\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__);
208
    // since no caller of this func checks the return value for the moment
209
    abort();
210
  }
211
  close(timer_kq);
212
  timer_kq = -1;
213
#else
214
  stopTimer = true;
×
215

216
  // printf("join timer thread:0x%08" PRIx64, taosGetPthreadId(timerThread));
217
  (void)taosThreadJoin(timerThread, NULL);
×
218
#endif
219
}
×
220

221
int64_t taosGetMonotonicMs() {
96,459✔
222
#if 0  
223
  return getMonotonicUs() / 1000;
224
#else
225
  return taosGetTimestampMs();
96,459✔
226
#endif
227
}
228

229
const char *taosMonotonicInit() {
16✔
230
#if 0
231
  return monotonicInit();
232
#else
233
  return NULL;
16✔
234
#endif
235
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc