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

taosdata / TDengine / #5034

24 Apr 2026 11:25AM UTC coverage: 73.058%. Remained the same
#5034

push

travis-ci

web-flow
merge: from main to 3.0 branch #35224

merge: from main to 3.0 branch[manual-only]

1336 of 1975 new or added lines in 48 files covered. (67.65%)

14149 existing lines in 164 files now uncovered.

275896 of 377640 relevant lines covered (73.06%)

132944440.29 hits per line

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

81.28
/source/os/src/osSemaphore.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
#include "pthread.h"
20
#include "tdef.h"
21

22
#ifdef WINDOWS
23

24
/*
25
 * windows implementation
26
 */
27

28
#include <windows.h>
29

30
bool taosCheckPthreadValid(TdThread thread) { return thread.p != NULL; }
31

32
void taosResetPthread(TdThread* thread) {
33
  if (thread != NULL) {
34
    thread->p = NULL;
35
  }
36
}
37

38
int64_t taosGetPthreadId(TdThread thread) {
39
#ifdef PTW32_VERSION
40
  return pthread_getw32threadid_np(thread);
41
#else
42
  return (int64_t)thread;
43
#endif
44
}
45

46
int64_t taosGetSelfPthreadId() { return GetCurrentThreadId(); }
47

48
bool taosComparePthread(TdThread first, TdThread second) { return first.p == second.p; }
49

50
int32_t taosGetPId() { return GetCurrentProcessId(); }
51

52
int32_t taosGetAppName(char* name, int32_t* len) {
53
  OS_PARAM_CHECK(name);
54
  char filepath[1024] = {0};
55

56
  if (GetModuleFileName(NULL, filepath, MAX_PATH) == 0) {
57
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
58
    return terrno;
59
  }
60
  char* sub = strrchr(filepath, '.');
61
  if (sub != NULL) {
62
    *sub = '\0';
63
  }
64
  char* end = strrchr(filepath, TD_DIRSEP[0]);
65
  if (end == NULL) {
66
    end = filepath;
67
  } else {
68
    end += 1;
69
  }
70

71
  tstrncpy(name, end, TSDB_APP_NAME_LEN);
72

73
  if (len != NULL) {
74
    *len = (int32_t)strlen(end);
75
  }
76

77
  return 0;
78
}
79

80
int32_t taosGetPIdByName(const char* name, int32_t* pPId) { return -1;}
81

82
int32_t tsem_wait(tsem_t* sem) {
83
  OS_PARAM_CHECK(sem);
84
  OS_PARAM_CHECK(*sem);
85
  DWORD ret = WaitForSingleObject(*sem, INFINITE);
86
  if (ret == WAIT_OBJECT_0) {
87
    return 0;
88
  } else {
89
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
90
  }
91
}
92

93
int32_t tsem_timewait(tsem_t* sem, int64_t timeout_ms) {
94
  OS_PARAM_CHECK(sem);
95
  OS_PARAM_CHECK(*sem);
96
  DWORD result = WaitForSingleObject(*sem, timeout_ms);
97
  if (result == WAIT_OBJECT_0) {
98
    return 0;  // Semaphore acquired
99
  } else if (result == WAIT_TIMEOUT) {
100
    return TSDB_CODE_TIMEOUT_ERROR;  // Timeout reached
101
  } else {
102
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
103
  }
104
}
105

106
// Inter-process sharing is not currently supported. The pshared parameter is invalid.
107
int32_t tsem_init(tsem_t* sem, int pshared, unsigned int value) {
108
  OS_PARAM_CHECK(sem);
109
  *sem = CreateSemaphore(NULL, value, LONG_MAX, NULL);
110
  return (*sem != NULL) ? 0 : TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
111
}
112

113
int32_t tsem_post(tsem_t* sem) {
114
  OS_PARAM_CHECK(sem);
115
  OS_PARAM_CHECK(*sem);
116
  if (ReleaseSemaphore(*sem, 1, NULL)) return 0;
117
  return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
118
}
119

120
int32_t tsem_destroy(tsem_t* sem) {
121
  OS_PARAM_CHECK(sem);
122
  OS_PARAM_CHECK(*sem);
123
  if (CloseHandle(*sem)) return 0;
124
  return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
125
}
126

127
#elif defined(_TD_DARWIN_64)
128

129
#include <libproc.h>
130

131
int32_t tsem_init(tsem_t *psem, int flags, unsigned int count) {
132
  OS_PARAM_CHECK(psem);
133
  *psem = dispatch_semaphore_create(count);
134
  if (*psem == NULL) return TAOS_SYSTEM_ERROR(ERRNO);
135
  return 0;
136
}
137

138
int32_t tsem_destroy(tsem_t *psem) {
139
  if (psem == NULL || *psem == NULL) return TSDB_CODE_INVALID_PARA;
140
  dispatch_release(*psem);
141
  *psem = NULL;
142
  return 0;
143
}
144

145
int32_t tsem_post(tsem_t *psem) {
146
  if (psem == NULL || *psem == NULL) return TSDB_CODE_INVALID_PARA;
147
  (void)dispatch_semaphore_signal(*psem);
148
  return 0;
149
}
150

151
int32_t tsem_wait(tsem_t *psem) {
152
  if (psem == NULL || *psem == NULL) return TSDB_CODE_INVALID_PARA;
153
  dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER);
154
  return 0;
155
}
156

157
int32_t tsem_timewait(tsem_t *psem, int64_t milis) {
158
  if (psem == NULL || *psem == NULL) return TSDB_CODE_INVALID_PARA;
159
  dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(milis * USEC_PER_SEC));
160
  if (dispatch_semaphore_wait(*psem, time) == 0) {
161
    return 0;
162
  } else {
163
    return TSDB_CODE_TIMEOUT_ERROR;
164
  }
165
}
166

167
bool taosCheckPthreadValid(TdThread thread) { return thread != 0; }
168

169
int64_t taosGetSelfPthreadId() {
170
  TdThread thread = taosThreadSelf();
171
  return (int64_t)thread;
172
}
173

174
int64_t taosGetPthreadId(TdThread thread) { return (int64_t)thread; }
175

176
void taosResetPthread(TdThread *thread) {
177
  if (thread) {
178
    *thread = NULL;
179
  }
180
}
181

182
bool taosComparePthread(TdThread first, TdThread second) { return taosThreadEqual(first, second) ? true : false; }
183

184
int32_t taosGetPId() { return (int32_t)getpid(); }
185

186
int32_t taosGetAppName(char *name, int32_t *len) {
187
  OS_PARAM_CHECK(name);
188
  char buf[PATH_MAX + 1];
189
  buf[0] = '\0';
190
  proc_name(getpid(), buf, sizeof(buf) - 1);
191
  buf[PATH_MAX] = '\0';
192
  size_t n = strlen(buf);
193
  if (len) *len = n;
194
  if (name) tstrncpy(name, buf, TSDB_APP_NAME_LEN);
195
  return 0;
196
}
197

198
int32_t taosGetPIdByName(const char* name, int32_t* pPId) {return -1;}
199

200
#else
201

202
/*
203
 * linux implementation
204
 */
205
#ifndef TD_ASTRA
206
#include <sys/syscall.h>
207
#endif
208
#include <unistd.h>
209

210
bool taosCheckPthreadValid(TdThread thread) { return thread != 0; }
344,055,324✔
211

212
int64_t taosGetSelfPthreadId() {
2,147,483,647✔
213
  static __thread int64_t id = 0;
214
  if (id != 0) return id;
2,147,483,647✔
215
#ifndef TD_ASTRA
216
  id = syscall(SYS_gettid);
270,732,825✔
217
#else
218
  id = (int64_t) taosThreadSelf();
219
#endif
220
  return id;
346,683,622✔
221
}
222

223
int64_t taosGetPthreadId(TdThread thread) { return (int64_t)thread; }
50,234,281✔
224
void    taosResetPthread(TdThread* thread) {
796✔
225
  if (thread) {
796✔
226
    *thread = 0;
594✔
227
  }
228
}
796✔
229
bool    taosComparePthread(TdThread first, TdThread second) { return first == second; }
594✔
230

231
int32_t taosGetPId() {
2,147,483,647✔
232
  static int32_t pid;
233
  if (pid != 0) return pid;
2,147,483,647✔
234
#ifndef TD_ASTRA
235
  pid = getpid();
2,167,740✔
236
#else
237
  pid = (int32_t)taosThreadSelf(); // TD_ASTRA_TODO
238
#endif
239
  return pid;
2,220,233✔
240
}
241

242
int32_t taosGetAppName(char* name, int32_t* len) {
33,350,339✔
243
#ifndef TD_ASTRA
244
  OS_PARAM_CHECK(name);
33,350,339✔
245
  const char* self = "/proc/self/exe";
33,350,137✔
246
  char        path[PATH_MAX] = {0};
33,350,137✔
247

248
  if (-1 == readlink(self, path, PATH_MAX)) {
33,350,137✔
249
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
250
    return terrno;
×
251
  }
252

253
  path[PATH_MAX - 1] = 0;
33,350,137✔
254
  char* end = strrchr(path, '/');
33,350,137✔
255
  if (end == NULL) {
33,350,137✔
256
    end = path;
×
257
  } else {
258
    ++end;
33,350,137✔
259
  }
260

261
  tstrncpy(name, end, TSDB_APP_NAME_LEN);
33,350,137✔
262
#else
263
  tstrncpy(name, "tdastra", TSDB_APP_NAME_LEN); // TD_ASTRA_TODO
264
#endif
265
  if (len != NULL) {
33,350,137✔
266
    *len = strlen(name);
196✔
267
  }
268

269
  return 0;
33,350,137✔
270
}
271

272
int32_t taosGetPIdByName(const char* name, int32_t* pPId) {
992✔
273
#ifndef TD_ASTRA
274
  OS_PARAM_CHECK(name);
992✔
275
  OS_PARAM_CHECK(pPId);
790✔
276
  DIR*           dir = NULL;
588✔
277
  struct dirent* ptr = NULL;
588✔
278
  FILE*          fp = NULL;
588✔
279
  char           filepath[512];
×
280
  char           bufx[50];
×
281
  char           buf[1024] = {0};
588✔
282

283
  *pPId = -1;
588✔
284
  dir = opendir("/proc");
588✔
285
  if (dir == NULL) {
588✔
286
    return TAOS_SYSTEM_ERROR(ERRNO);
×
287
  }
288

289
  while ((ptr = readdir(dir)) != NULL) {
47,040✔
290
    if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
46,452✔
291
      continue;
1,176✔
292
    }
293

294
    if (DT_DIR != ptr->d_type) {
45,276✔
295
      continue;
29,400✔
296
    }
297

298
    int32_t ret = snprintf(filepath, tListLen(filepath), "/proc/%s/status", ptr->d_name);
15,876✔
299
    if (ret == -1) {
15,876✔
300
      continue;
×
301
    }
302

303
    fp = fopen(filepath, "r");
15,876✔
304
    if (NULL != fp) {
15,876✔
305
      if (fgets(buf, tListLen(buf) - 1, fp) == NULL) {
9,996✔
306
        TAOS_UNUSED(fclose(fp));
×
307
        continue;
×
308
      }
309

310
      ret = sscanf(buf, "%*s %s", bufx);
9,996✔
311
      if (!strcmp(bufx, name)) {
9,996✔
312
        char* end = NULL;
196✔
313
        *pPId = taosStr2Int32(ptr->d_name, &end, 10);
196✔
314
      }
315
      TAOS_UNUSED(fclose(fp));
9,996✔
316
    }
317
  }
318

319
  TAOS_UNUSED(closedir(dir));
588✔
320

321
  if ((*pPId) == -1) {
588✔
322
    return TAOS_SYSTEM_ERROR(ESRCH);
392✔
323
  } else {
324
    return TSDB_CODE_SUCCESS;
196✔
325
  }
326
#else
327
  return TSDB_CODE_APP_ERROR;
328
#endif
329
}
330

331
int32_t tsem_init(tsem_t* psem, int flags, unsigned int count) {
2,147,483,647✔
332
  if (sem_init(psem, flags, count) == 0) {
2,147,483,647✔
333
    return 0;
2,147,483,647✔
334
  } else {
335
    return terrno = TAOS_SYSTEM_ERROR(ERRNO);
36✔
336
  }
337
}
338

339
int32_t tsem_timewait(tsem_t* sem, int64_t ms) {
19,796,986✔
340
  OS_PARAM_CHECK(sem);
19,796,986✔
341
  int ret = 0;
19,796,784✔
342

343
  struct timespec ts = {0};
19,796,784✔
344

345
  if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
19,796,784✔
346
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
347
    return terrno;
×
348
  }
349

350
  ts.tv_nsec += ms * 1000000;
19,796,784✔
351
  ts.tv_sec += ts.tv_nsec / 1000000000;
19,796,784✔
352
  ts.tv_nsec %= 1000000000;
19,796,784✔
353

354
  while ((ret = sem_timedwait(sem, &ts)) == -1) {
19,796,784✔
355
    if (ERRNO == EINTR) {
976✔
356
      continue;
×
357
    } else if (ERRNO == ETIMEDOUT) {
976✔
358
      return TSDB_CODE_TIMEOUT_ERROR;
976✔
359
    } else {
360
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
361
      return terrno;
×
362
    }
363
  }
364

365
  return 0;
19,795,808✔
366
}
367

368
int32_t tsem_wait(tsem_t* sem) {
2,147,483,647✔
369
  OS_PARAM_CHECK(sem);
2,147,483,647✔
370
  int ret = 0;
2,147,483,647✔
371
  do {
372
    ret = sem_wait(sem);
2,147,483,647✔
373
  } while (-1 == ret && ERRNO == EINTR);
2,147,483,647✔
374

375
  if (-1 == ret) {
2,147,483,647✔
376
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
377
    return terrno;
×
378
  }
379

380
  return ret;
2,147,483,647✔
381
}
382

383
int tsem2_init(tsem2_t* sem, int pshared, unsigned int value) {
79,635,577✔
384
  OS_PARAM_CHECK(sem);
79,635,577✔
385
  int ret = taosThreadMutexInit(&sem->mutex, NULL);
79,635,375✔
386
  if (ret != 0) return ret;
79,635,334✔
387

388
  ret = taosThreadCondAttrInit(&sem->attr);
79,635,334✔
389
  if (ret != 0) {
79,633,519✔
390
    (void)taosThreadMutexDestroy(&sem->mutex);
×
391
    return ret;
×
392
  }
393

394
  ret = taosThreadCondAttrSetclock(&sem->attr, CLOCK_MONOTONIC);
79,633,519✔
395
  if (ret != 0) {
79,633,572✔
396
    (void)taosThreadMutexDestroy(&sem->mutex);
×
397
    (void)taosThreadCondAttrDestroy(&sem->attr);
×
398
    return ret;
×
399
  }
400

401
  ret = taosThreadCondInit(&sem->cond, &sem->attr);
79,633,572✔
402
  if (ret != 0) {
79,632,485✔
UNCOV
403
    (void)taosThreadMutexDestroy(&sem->mutex);
×
404
    (void)taosThreadCondAttrDestroy(&sem->attr);
×
405
    return ret;
×
406
  }
407

408
  sem->count = value;
79,632,485✔
409

410
  return 0;
79,633,449✔
411
}
412

413
int32_t tsem_post(tsem_t* psem) {
2,147,483,647✔
414
  OS_PARAM_CHECK(psem);
2,147,483,647✔
415
  if (sem_post(psem) == 0) {
2,147,483,647✔
416
    return 0;
2,147,483,647✔
417
  } else {
418
    return TAOS_SYSTEM_ERROR(ERRNO);
206,835✔
419
  }
420
}
421

422
int32_t tsem_destroy(tsem_t* sem) {
2,147,483,647✔
423
  OS_PARAM_CHECK(sem);
2,147,483,647✔
424
  if (sem_destroy(sem) == 0) {
2,147,483,647✔
425
    return 0;
2,147,483,647✔
426
  } else {
427
    return TAOS_SYSTEM_ERROR(ERRNO);
299✔
428
  }
429
}
430

431
int tsem2_post(tsem2_t* sem) {
454,136,805✔
432
  OS_PARAM_CHECK(sem);
454,136,805✔
433
  int32_t code = taosThreadMutexLock(&sem->mutex);
454,136,603✔
434
  if (code) {
454,140,235✔
435
    return code;
×
436
  }
437

438
  sem->count++;
454,140,235✔
439
  code = taosThreadCondSignal(&sem->cond);
454,140,607✔
440
  if (code) {
454,140,235✔
441
    return code;
×
442
  }
443

444
  code = taosThreadMutexUnlock(&sem->mutex);
454,140,235✔
445
  if (code) {
454,140,235✔
446
    return code;
×
447
  }
448

449
  return 0;
454,140,235✔
450
}
451

452
int tsem2_destroy(tsem2_t* sem) {
79,632,004✔
453
  OS_PARAM_CHECK(sem);
79,632,004✔
454
  (void)taosThreadMutexDestroy(&sem->mutex);
79,631,802✔
455
  (void)taosThreadCondDestroy(&sem->cond);
79,631,802✔
456
  (void)taosThreadCondAttrDestroy(&sem->attr);
79,631,802✔
457

458
  return 0;
79,631,802✔
459
}
460

461
int32_t tsem2_wait(tsem2_t* sem) {
40,959,790✔
462
  OS_PARAM_CHECK(sem);
40,959,790✔
463
  int32_t code = taosThreadMutexLock(&sem->mutex);
40,959,588✔
464
  if (code) {
40,959,588✔
465
    return code;
×
466
  }
467

468
  while (sem->count <= 0) {
47,365,287✔
469
    int ret = taosThreadCondWait(&sem->cond, &sem->mutex);
6,405,699✔
470
    if (0 == ret) {
6,405,699✔
471
      continue;
6,405,699✔
472
    } else {
473
      (void)taosThreadMutexUnlock(&sem->mutex);
×
474
      return ret;
×
475
    }
476
  }
477
  sem->count--;
40,959,588✔
478

479
  code = taosThreadMutexUnlock(&sem->mutex);
40,959,588✔
480
  if (code) {
40,959,588✔
481
    return code;
×
482
  }
483

484
  return 0;
40,959,588✔
485
}
486

487
int32_t tsem2_timewait(tsem2_t* sem, int64_t ms) {
1,025,578,654✔
488
  OS_PARAM_CHECK(sem);
1,025,578,654✔
489
  int32_t code = 0;
1,025,578,452✔
490

491
  code = taosThreadMutexLock(&sem->mutex);
1,025,578,452✔
492
  if (code) {
1,025,577,374✔
493
    return code;
×
494
  }
495

496
  if (sem->count <= 0) {
1,025,577,374✔
497
    struct timespec ts = {0};
845,497,229✔
498
    if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
845,497,617✔
499
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
500
      (void)taosThreadMutexUnlock(&sem->mutex);
×
501
      terrno = code;
×
502
      return code;
10,229,535✔
503
    }
504

505
    ts.tv_sec += ms / 1000;
845,497,869✔
506
    ts.tv_nsec += (ms % 1000) * 1000000;
845,497,869✔
507
    ts.tv_sec += ts.tv_nsec / 1000000000;
845,497,869✔
508
    ts.tv_nsec %= 1000000000;
845,497,869✔
509

510
    while (sem->count <= 0) {
1,097,621,151✔
511
      code = taosThreadCondTimedWait(&sem->cond, &sem->mutex, &ts);
845,497,302✔
512
      if (code != 0) {
845,490,914✔
513
        (void)taosThreadMutexUnlock(&sem->mutex);
593,367,632✔
514
        return code;
593,370,331✔
515
      }
516
    }
517
  }
518

519
  sem->count--;
432,206,450✔
520
  
521
  code = taosThreadMutexUnlock(&sem->mutex);
432,209,357✔
522
  return code;
432,208,277✔
523
}
524

525
#endif
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