Rizin
unix-like reverse engineering framework and cli tools
thread.c File Reference
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include "uv.h"
#include "internal.h"

Go to the source code of this file.

Classes

struct  thread_ctx
 

Functions

static void uv__once_inner (uv_once_t *guard, void(*callback)(void))
 
void uv_once (uv_once_t *guard, void(*callback)(void))
 
 STATIC_ASSERT (sizeof(uv_thread_t)<=sizeof(void *))
 
static void uv__init_current_thread_key (void)
 
static UINT __stdcall uv__thread_start (void *arg)
 
int uv_thread_create (uv_thread_t *tid, void(*entry)(void *arg), void *arg)
 
int uv_thread_create_ex (uv_thread_t *tid, const uv_thread_options_t *params, void(*entry)(void *arg), void *arg)
 
uv_thread_t uv_thread_self (void)
 
int uv_thread_join (uv_thread_t *tid)
 
int uv_thread_equal (const uv_thread_t *t1, const uv_thread_t *t2)
 
int uv_mutex_init (uv_mutex_t *mutex)
 
int uv_mutex_init_recursive (uv_mutex_t *mutex)
 
void uv_mutex_destroy (uv_mutex_t *mutex)
 
void uv_mutex_lock (uv_mutex_t *mutex)
 
int uv_mutex_trylock (uv_mutex_t *mutex)
 
void uv_mutex_unlock (uv_mutex_t *mutex)
 
int uv_rwlock_init (uv_rwlock_t *rwlock)
 
void uv_rwlock_destroy (uv_rwlock_t *rwlock)
 
void uv_rwlock_rdlock (uv_rwlock_t *rwlock)
 
int uv_rwlock_tryrdlock (uv_rwlock_t *rwlock)
 
void uv_rwlock_rdunlock (uv_rwlock_t *rwlock)
 
void uv_rwlock_wrlock (uv_rwlock_t *rwlock)
 
int uv_rwlock_trywrlock (uv_rwlock_t *rwlock)
 
void uv_rwlock_wrunlock (uv_rwlock_t *rwlock)
 
int uv_sem_init (uv_sem_t *sem, unsigned int value)
 
void uv_sem_destroy (uv_sem_t *sem)
 
void uv_sem_post (uv_sem_t *sem)
 
void uv_sem_wait (uv_sem_t *sem)
 
int uv_sem_trywait (uv_sem_t *sem)
 
int uv_cond_init (uv_cond_t *cond)
 
void uv_cond_destroy (uv_cond_t *cond)
 
void uv_cond_signal (uv_cond_t *cond)
 
void uv_cond_broadcast (uv_cond_t *cond)
 
void uv_cond_wait (uv_cond_t *cond, uv_mutex_t *mutex)
 
int uv_cond_timedwait (uv_cond_t *cond, uv_mutex_t *mutex, uint64_t timeout)
 
int uv_barrier_init (uv_barrier_t *barrier, unsigned int count)
 
void uv_barrier_destroy (uv_barrier_t *barrier)
 
int uv_barrier_wait (uv_barrier_t *barrier)
 
int uv_key_create (uv_key_t *key)
 
void uv_key_delete (uv_key_t *key)
 
void * uv_key_get (uv_key_t *key)
 
void uv_key_set (uv_key_t *key, void *value)
 

Variables

static uv_key_t uv__current_thread_key
 
static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT
 

Function Documentation

◆ STATIC_ASSERT()

STATIC_ASSERT ( sizeof(uv_thread_t)<=sizeof(void *)  )

◆ uv__init_current_thread_key()

static void uv__init_current_thread_key ( void  )
static

Definition at line 84 of file thread.c.

84  {
86  abort();
87 }
int uv_key_create(uv_key_t *key)
Definition: thread.c:823
static uv_key_t uv__current_thread_key
Definition: thread.c:80

References uv__current_thread_key, and uv_key_create().

Referenced by uv__thread_start(), and uv_thread_self().

◆ uv__once_inner()

static void uv__once_inner ( uv_once_t guard,
void(*)(void)  callback 
)
static

Definition at line 35 of file thread.c.

35  {
36  DWORD result;
37  HANDLE existing_event, created_event;
38 
39  created_event = CreateEvent(NULL, 1, 0, NULL);
40  if (created_event == 0) {
41  /* Could fail in a low-memory situation? */
42  uv_fatal_error(GetLastError(), "CreateEvent");
43  }
44 
45  existing_event = InterlockedCompareExchangePointer(&guard->event,
46  created_event,
47  NULL);
48 
49  if (existing_event == NULL) {
50  /* We won the race */
51  callback();
52 
53  result = SetEvent(created_event);
54  assert(result);
55  guard->ran = 1;
56 
57  } else {
58  /* We lost the race. Destroy the event we created and wait for the existing
59  * one to become signaled. */
60  CloseHandle(created_event);
61  result = WaitForSingleObject(existing_event, INFINITE);
62  assert(result == WAIT_OBJECT_0);
63  }
64 }
#define NULL
Definition: cris-opc.c:27
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35
assert(limit<=UINT32_MAX/2)
DWORD * HANDLE
DWORD

References assert(), DWORD, HANDLE, NULL, and uv_fatal_error().

Referenced by uv_once().

◆ uv__thread_start()

static UINT __stdcall uv__thread_start ( void *  arg)
static

Definition at line 97 of file thread.c.

97  {
98  struct thread_ctx *ctx_p;
99  struct thread_ctx ctx;
100 
101  ctx_p = arg;
102  ctx = *ctx_p;
103  uv__free(ctx_p);
104 
106  uv_key_set(&uv__current_thread_key, (void*) ctx.self);
107 
108  ctx.entry(ctx.arg);
109 
110  return 0;
111 }
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
void uv_key_set(uv_key_t *key, void *value)
Definition: thread.c:839
void uv_once(uv_once_t *guard, void(*callback)(void))
Definition: thread.c:419
static uv_once_t uv__current_thread_init_guard
Definition: thread.c:81
static void uv__init_current_thread_key(void)
Definition: thread.c:84
void uv__free(void *ptr)
Definition: uv-common.c:81

References arg(), uv__current_thread_init_guard, uv__current_thread_key, uv__free(), uv__init_current_thread_key(), uv_key_set(), and uv_once().

Referenced by uv_thread_create_ex().

◆ uv_barrier_destroy()

void uv_barrier_destroy ( uv_barrier_t barrier)

Definition at line 456 of file thread.c.

456  {
457  uv_sem_destroy(&barrier->turnstile2);
458  uv_sem_destroy(&barrier->turnstile1);
459  uv_mutex_destroy(&barrier->mutex);
460 }
uv_mutex_t mutex
Definition: win.h:279
uv_sem_t turnstile2
Definition: win.h:281
uv_sem_t turnstile1
Definition: win.h:280
void uv_mutex_destroy(uv_mutex_t *mutex)
Definition: thread.c:324
void uv_sem_destroy(uv_sem_t *sem)
Definition: thread.c:662

References assert(), uv_barrier_t::b, b, uv_barrier_t::mutex, NULL, uv_barrier_t::turnstile1, uv_barrier_t::turnstile2, uv__free(), uv_cond_destroy(), uv_mutex_destroy(), uv_mutex_lock(), uv_mutex_unlock(), and uv_sem_destroy().

Referenced by main().

◆ uv_barrier_init()

int uv_barrier_init ( uv_barrier_t barrier,
unsigned int  count 
)

Definition at line 427 of file thread.c.

427  {
428  int err;
429 
430  barrier->n = count;
431  barrier->count = 0;
432 
433  err = uv_mutex_init(&barrier->mutex);
434  if (err)
435  return err;
436 
437  err = uv_sem_init(&barrier->turnstile1, 0);
438  if (err)
439  goto error2;
440 
441  err = uv_sem_init(&barrier->turnstile2, 1);
442  if (err)
443  goto error;
444 
445  return 0;
446 
447 error:
448  uv_sem_destroy(&barrier->turnstile1);
449 error2:
450  uv_mutex_destroy(&barrier->mutex);
451  return err;
452 
453 }
static bool err
Definition: armass.c:435
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
unsigned int n
Definition: win.h:277
unsigned int count
Definition: win.h:278
int uv_sem_init(uv_sem_t *sem, unsigned int value)
Definition: thread.c:650
int uv_mutex_init(uv_mutex_t *mutex)
Definition: thread.c:282
void error(const char *msg)
Definition: untgz.c:593

References uv_barrier_t::b, b, count, uv_barrier_t::count, err, error(), uv_barrier_t::mutex, uv_barrier_t::n, NULL, uv_barrier_t::turnstile1, uv_barrier_t::turnstile2, uv__free(), uv__malloc(), uv_cond_init(), uv_mutex_destroy(), uv_mutex_init(), uv_sem_destroy(), and uv_sem_init().

Referenced by main().

◆ uv_barrier_wait()

int uv_barrier_wait ( uv_barrier_t barrier)

Definition at line 463 of file thread.c.

463  {
464  int serial_thread;
465 
466  uv_mutex_lock(&barrier->mutex);
467  if (++barrier->count == barrier->n) {
468  uv_sem_wait(&barrier->turnstile2);
469  uv_sem_post(&barrier->turnstile1);
470  }
471  uv_mutex_unlock(&barrier->mutex);
472 
473  uv_sem_wait(&barrier->turnstile1);
474  uv_sem_post(&barrier->turnstile1);
475 
476  uv_mutex_lock(&barrier->mutex);
477  serial_thread = (--barrier->count == 0);
478  if (serial_thread) {
479  uv_sem_wait(&barrier->turnstile1);
480  uv_sem_post(&barrier->turnstile2);
481  }
482  uv_mutex_unlock(&barrier->mutex);
483 
484  uv_sem_wait(&barrier->turnstile2);
485  uv_sem_post(&barrier->turnstile2);
486  return serial_thread;
487 }
void uv_sem_wait(uv_sem_t *sem)
Definition: thread.c:678
void uv_mutex_unlock(uv_mutex_t *mutex)
Definition: thread.c:350
void uv_sem_post(uv_sem_t *sem)
Definition: thread.c:670
void uv_mutex_lock(uv_mutex_t *mutex)
Definition: thread.c:330

References uv_barrier_t::b, b, uv_barrier_t::count, uv_barrier_t::mutex, uv_barrier_t::n, NULL, uv_barrier_t::turnstile1, uv_barrier_t::turnstile2, uv_cond_signal(), uv_cond_wait(), uv_mutex_lock(), uv_mutex_unlock(), uv_sem_post(), and uv_sem_wait().

Referenced by main(), reader(), and writer().

◆ uv_cond_broadcast()

void uv_cond_broadcast ( uv_cond_t cond)

Definition at line 408 of file thread.c.

408  {
409  WakeAllConditionVariable(&cond->cond_var);
410 }
#define cond(bop, top, mask, flags)

References cond.

◆ uv_cond_destroy()

void uv_cond_destroy ( uv_cond_t cond)

Definition at line 397 of file thread.c.

397  {
398  /* nothing to do */
399  (void) &cond;
400 }

References cond, err, ETIMEDOUT, mutex, NULL, timespec::tv_nsec, and timespec::tv_sec.

Referenced by uv__threadpool_cleanup().

◆ uv_cond_init()

int uv_cond_init ( uv_cond_t cond)

Definition at line 391 of file thread.c.

391  {
392  InitializeConditionVariable(&cond->cond_var);
393  return 0;
394 }

References cond, err, error(), and UV__ERR.

Referenced by init_threads().

◆ uv_cond_signal()

void uv_cond_signal ( uv_cond_t cond)

Definition at line 403 of file thread.c.

403  {
404  WakeConditionVariable(&cond->cond_var);
405 }

References cond.

Referenced by post(), and worker().

◆ uv_cond_timedwait()

int uv_cond_timedwait ( uv_cond_t cond,
uv_mutex_t mutex,
uint64_t  timeout 
)

Definition at line 418 of file thread.c.

418  {
419  if (SleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
420  return 0;
421  if (GetLastError() != ERROR_TIMEOUT)
422  abort();
423  return UV_ETIMEDOUT;
424 }
uv_timer_t timeout
Definition: main.c:9
static uv_mutex_t mutex
Definition: threadpool.c:34

References cond, DWORD, ETIMEDOUT, gettimeofday, mutex, NANOSEC, NULL, r, timeout, tv, timespec::tv_nsec, timespec::tv_sec, uv__hrtime(), and UV_CLOCK_PRECISE.

◆ uv_cond_wait()

void uv_cond_wait ( uv_cond_t cond,
uv_mutex_t mutex 
)

Definition at line 413 of file thread.c.

413  {
414  if (!SleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
415  abort();
416 }

References cond, and mutex.

Referenced by worker().

◆ uv_key_create()

int uv_key_create ( uv_key_t key)

Definition at line 490 of file thread.c.

490  {
491  key->tls_index = TlsAlloc();
492  if (key->tls_index == TLS_OUT_OF_INDEXES)
493  return UV_ENOMEM;
494  return 0;
495 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118

References key, NULL, and UV__ERR.

◆ uv_key_delete()

void uv_key_delete ( uv_key_t key)

Definition at line 498 of file thread.c.

498  {
499  if (TlsFree(key->tls_index) == FALSE)
500  abort();
501  key->tls_index = TLS_OUT_OF_INDEXES;
502 }
#define FALSE
Definition: mybfd.h:102

References FALSE, and key.

◆ uv_key_get()

void* uv_key_get ( uv_key_t key)

Definition at line 505 of file thread.c.

505  {
506  void* value;
507 
508  value = TlsGetValue(key->tls_index);
509  if (value == NULL)
510  if (GetLastError() != ERROR_SUCCESS)
511  abort();
512 
513  return value;
514 }
static int value
Definition: cmd_api.c:93

References key, NULL, and value.

◆ uv_key_set()

void uv_key_set ( uv_key_t key,
void *  value 
)

Definition at line 517 of file thread.c.

517  {
518  if (TlsSetValue(key->tls_index, value) == FALSE)
519  abort();
520 }

References FALSE, key, and value.

◆ uv_mutex_destroy()

void uv_mutex_destroy ( uv_mutex_t mutex)

Definition at line 218 of file thread.c.

218  {
219  DeleteCriticalSection(mutex);
220 }

References mutex.

Referenced by child_fork(), uv__loop_close(), uv__threadpool_cleanup(), and uv_loop_init().

◆ uv_mutex_init()

int uv_mutex_init ( uv_mutex_t mutex)

Definition at line 207 of file thread.c.

207  {
208  InitializeCriticalSection(mutex);
209  return 0;
210 }

References err, mutex, NULL, and UV__ERR.

Referenced by epoll_init(), init_process_title_mutex_once(), init_threads(), uv__fd_hash_init(), uv__loops_init(), uv_console_init(), and uv_loop_init().

◆ uv_mutex_init_recursive()

int uv_mutex_init_recursive ( uv_mutex_t mutex)

Definition at line 213 of file thread.c.

213  {
214  return uv_mutex_init(mutex);
215 }

References err, mutex, UV__ERR, and uv_mutex_init().

◆ uv_mutex_lock()

◆ uv_mutex_trylock()

int uv_mutex_trylock ( uv_mutex_t mutex)

Definition at line 228 of file thread.c.

228  {
229  if (TryEnterCriticalSection(mutex))
230  return 0;
231  else
232  return UV_EBUSY;
233 }

References EAGAIN, EBUSY, err, and mutex.

◆ uv_mutex_unlock()

◆ uv_once()

void uv_once ( uv_once_t guard,
void(*)(void)  callback 
)

Definition at line 67 of file thread.c.

67  {
68  /* Fast case - avoid WaitForSingleObject. */
69  if (guard->ran) {
70  return;
71  }
72 
73  uv__once_inner(guard, callback);
74 }
static void uv__once_inner(uv_once_t *guard, void(*callback)(void))
Definition: thread.c:35

References uv__once_inner().

Referenced by epoll_create1(), epoll_file_close(), uv__fs_mkstemp(), uv__get_overlapped_dummy(), uv__hrtime(), uv__once_init(), uv__random_devurandom(), uv__random_getentropy(), uv__random_getrandom_init(), uv__signal_global_once_init(), uv__udp_sendmsg(), uv__work_submit(), uv_exepath(), uv_get_process_title(), uv_set_process_title(), uv_setup_args(), uv_spawn(), and uv_udp_using_recvmmsg().

◆ uv_rwlock_destroy()

void uv_rwlock_destroy ( uv_rwlock_t rwlock)

Definition at line 258 of file thread.c.

258  {
259  DeleteCriticalSection(&rwlock->state_.num_readers_lock_);
260  CloseHandle(rwlock->state_.write_semaphore_);
261 }
CRITICAL_SECTION num_readers_lock_
Definition: win.h:262
HANDLE write_semaphore_
Definition: win.h:263
struct uv_rwlock_t::@394 state_

References uv_rwlock_t::num_readers_lock_, uv_rwlock_t::state_, and uv_rwlock_t::write_semaphore_.

Referenced by main(), uv__loop_close(), and uv_loop_init().

◆ uv_rwlock_init()

int uv_rwlock_init ( uv_rwlock_t rwlock)

Definition at line 241 of file thread.c.

241  {
242  /* Initialize the semaphore that acts as the write lock. */
243  HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);
244  if (handle == NULL)
245  return uv_translate_sys_error(GetLastError());
246  rwlock->state_.write_semaphore_ = handle;
247 
248  /* Initialize the critical section protecting the reader count. */
249  InitializeCriticalSection(&rwlock->state_.num_readers_lock_);
250 
251  /* Initialize the reader count. */
252  rwlock->state_.num_readers_ = 0;
253 
254  return 0;
255 }
static mcore_handle handle
Definition: asm_mcore.c:8
unsigned int num_readers_
Definition: win.h:261
UV_EXTERN int uv_translate_sys_error(int sys_errno)
Definition: core.c:1249

References handle, HANDLE, NULL, uv_rwlock_t::num_readers_, uv_rwlock_t::num_readers_lock_, uv_rwlock_t::state_, UV__ERR, uv_translate_sys_error(), and uv_rwlock_t::write_semaphore_.

Referenced by main(), and uv_loop_init().

◆ uv_rwlock_rdlock()

void uv_rwlock_rdlock ( uv_rwlock_t rwlock)

Definition at line 264 of file thread.c.

264  {
265  /* Acquire the lock that protects the reader count. */
266  EnterCriticalSection(&rwlock->state_.num_readers_lock_);
267 
268  /* Increase the reader count, and lock for write if this is the first
269  * reader.
270  */
271  if (++rwlock->state_.num_readers_ == 1) {
272  DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
273  if (r != WAIT_OBJECT_0)
274  uv_fatal_error(GetLastError(), "WaitForSingleObject");
275  }
276 
277  /* Release the lock that protects the reader count. */
278  LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
279 }
#define r
Definition: crypto_rc6.c:12

References DWORD, uv_rwlock_t::num_readers_, uv_rwlock_t::num_readers_lock_, r, uv_rwlock_t::state_, uv_fatal_error(), and uv_rwlock_t::write_semaphore_.

Referenced by reader(), uv__fs_mkstemp(), and uv__fs_open().

◆ uv_rwlock_rdunlock()

void uv_rwlock_rdunlock ( uv_rwlock_t rwlock)

Definition at line 314 of file thread.c.

314  {
315  EnterCriticalSection(&rwlock->state_.num_readers_lock_);
316 
317  if (--rwlock->state_.num_readers_ == 0) {
318  if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
319  uv_fatal_error(GetLastError(), "ReleaseSemaphore");
320  }
321 
322  LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
323 }

References NULL, uv_rwlock_t::num_readers_, uv_rwlock_t::num_readers_lock_, uv_rwlock_t::state_, uv_fatal_error(), and uv_rwlock_t::write_semaphore_.

Referenced by reader(), uv__fs_mkstemp(), and uv__fs_open().

◆ uv_rwlock_tryrdlock()

int uv_rwlock_tryrdlock ( uv_rwlock_t rwlock)

Definition at line 282 of file thread.c.

282  {
283  int err;
284 
285  if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_))
286  return UV_EBUSY;
287 
288  err = 0;
289 
290  if (rwlock->state_.num_readers_ == 0) {
291  /* Currently there are no other readers, which means that the write lock
292  * needs to be acquired.
293  */
294  DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
295  if (r == WAIT_OBJECT_0)
296  rwlock->state_.num_readers_++;
297  else if (r == WAIT_TIMEOUT)
298  err = UV_EBUSY;
299  else if (r == WAIT_FAILED)
300  uv_fatal_error(GetLastError(), "WaitForSingleObject");
301 
302  } else {
303  /* The write lock has already been acquired because there are other
304  * active readers.
305  */
306  rwlock->state_.num_readers_++;
307  }
308 
309  LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
310  return err;
311 }

References DWORD, EAGAIN, EBUSY, err, uv_rwlock_t::num_readers_, uv_rwlock_t::num_readers_lock_, r, uv_rwlock_t::state_, uv_fatal_error(), and uv_rwlock_t::write_semaphore_.

◆ uv_rwlock_trywrlock()

int uv_rwlock_trywrlock ( uv_rwlock_t rwlock)

Definition at line 333 of file thread.c.

333  {
334  DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
335  if (r == WAIT_OBJECT_0)
336  return 0;
337  else if (r == WAIT_TIMEOUT)
338  return UV_EBUSY;
339  else
340  uv_fatal_error(GetLastError(), "WaitForSingleObject");
341 }

References DWORD, EAGAIN, EBUSY, err, r, uv_rwlock_t::state_, uv_fatal_error(), and uv_rwlock_t::write_semaphore_.

◆ uv_rwlock_wrlock()

void uv_rwlock_wrlock ( uv_rwlock_t rwlock)

Definition at line 326 of file thread.c.

326  {
327  DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
328  if (r != WAIT_OBJECT_0)
329  uv_fatal_error(GetLastError(), "WaitForSingleObject");
330 }

References DWORD, r, uv_rwlock_t::state_, uv_fatal_error(), and uv_rwlock_t::write_semaphore_.

Referenced by uv_spawn(), and writer().

◆ uv_rwlock_wrunlock()

void uv_rwlock_wrunlock ( uv_rwlock_t rwlock)

Definition at line 344 of file thread.c.

344  {
345  if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
346  uv_fatal_error(GetLastError(), "ReleaseSemaphore");
347 }

References NULL, uv_rwlock_t::state_, uv_fatal_error(), and uv_rwlock_t::write_semaphore_.

Referenced by uv_spawn(), and writer().

◆ uv_sem_destroy()

void uv_sem_destroy ( uv_sem_t sem)

Definition at line 359 of file thread.c.

359  {
360  if (!CloseHandle(*sem))
361  abort();
362 }

References platform_needs_custom_semaphore, uv__custom_sem_destroy(), and uv__sem_destroy().

Referenced by init_threads(), and uv__stream_close().

◆ uv_sem_init()

int uv_sem_init ( uv_sem_t sem,
unsigned int  value 
)

Definition at line 350 of file thread.c.

350  {
351  *sem = CreateSemaphore(NULL, value, INT_MAX, NULL);
352  if (*sem == NULL)
353  return uv_translate_sys_error(GetLastError());
354  else
355  return 0;
356 }
#define INT_MAX
Definition: cp-demangle.c:131

References INT_MAX, NULL, platform_needs_custom_semaphore, uv__custom_sem_init(), uv__sem_init(), uv_once(), uv_translate_sys_error(), and value.

Referenced by init_threads(), and uv_console_init().

◆ uv_sem_post()

void uv_sem_post ( uv_sem_t sem)

◆ uv_sem_trywait()

int uv_sem_trywait ( uv_sem_t sem)

Definition at line 377 of file thread.c.

377  {
378  DWORD r = WaitForSingleObject(*sem, 0);
379 
380  if (r == WAIT_OBJECT_0)
381  return 0;
382 
383  if (r == WAIT_TIMEOUT)
384  return UV_EAGAIN;
385 
386  abort();
387  return -1; /* Satisfy the compiler. */
388 }

References DWORD, platform_needs_custom_semaphore, r, uv__custom_sem_trywait(), and uv__sem_trywait().

◆ uv_sem_wait()

void uv_sem_wait ( uv_sem_t sem)

Definition at line 371 of file thread.c.

371  {
372  if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0)
373  abort();
374 }

References platform_needs_custom_semaphore, uv__custom_sem_wait(), and uv__sem_wait().

Referenced by init_threads(), uv__cancel_read_console(), uv_tty_get_vterm_state(), uv_tty_get_winsize(), uv_tty_init(), uv_tty_set_mode(), uv_tty_set_vterm_state(), and uv_tty_write_bufs().

◆ uv_thread_create()

int uv_thread_create ( uv_thread_t tid,
void(*)(void *arg entry,
void *  arg 
)

Definition at line 114 of file thread.c.

114  {
115  uv_thread_options_t params;
116  params.flags = UV_THREAD_NO_FLAGS;
117  return uv_thread_create_ex(tid, &params, entry, arg);
118 }
Definition: zipcmp.c:77
unsigned int flags
Definition: uv.h:1753
int uv_thread_create_ex(uv_thread_t *tid, const uv_thread_options_t *params, void(*entry)(void *arg), void *arg)
Definition: thread.c:216
@ UV_THREAD_NO_FLAGS
Definition: uv.h:1748

References uv_thread_options_s::flags, uv_thread_create_ex(), and UV_THREAD_NO_FLAGS.

Referenced by init_threads(), and main().

◆ uv_thread_create_ex()

int uv_thread_create_ex ( uv_thread_t tid,
const uv_thread_options_t params,
void(*)(void *arg entry,
void *  arg 
)

Definition at line 120 of file thread.c.

123  {
124  struct thread_ctx* ctx;
125  int err;
126  HANDLE thread;
127  SYSTEM_INFO sysinfo;
128  size_t stack_size;
129  size_t pagesize;
130 
131  stack_size =
132  params->flags & UV_THREAD_HAS_STACK_SIZE ? params->stack_size : 0;
133 
134  if (stack_size != 0) {
135  GetNativeSystemInfo(&sysinfo);
136  pagesize = (size_t)sysinfo.dwPageSize;
137  /* Round up to the nearest page boundary. */
138  stack_size = (stack_size + pagesize - 1) &~ (pagesize - 1);
139 
140  if ((unsigned)stack_size != stack_size)
141  return UV_EINVAL;
142  }
143 
144  ctx = uv__malloc(sizeof(*ctx));
145  if (ctx == NULL)
146  return UV_ENOMEM;
147 
148  ctx->entry = entry;
149  ctx->arg = arg;
150 
151  /* Create the thread in suspended state so we have a chance to pass
152  * its own creation handle to it */
153  thread = (HANDLE) _beginthreadex(NULL,
154  (unsigned)stack_size,
156  ctx,
157  CREATE_SUSPENDED,
158  NULL);
159  if (thread == NULL) {
160  err = errno;
161  uv__free(ctx);
162  } else {
163  err = 0;
164  *tid = thread;
165  ctx->self = thread;
166  ResumeThread(thread);
167  }
168 
169  switch (err) {
170  case 0:
171  return 0;
172  case EACCES:
173  return UV_EACCES;
174  case EAGAIN:
175  return UV_EAGAIN;
176  case EINVAL:
177  return UV_EINVAL;
178  }
179 
180  return UV_EIO;
181 }
static const char struct stat static buf struct stat static buf static vhangup int struct rusage static rusage sysinfo
Definition: sflib.h:147
#define EINVAL
Definition: sftypes.h:132
int size_t
Definition: sftypes.h:40
#define EACCES
Definition: sftypes.h:123
#define EAGAIN
Definition: sftypes.h:121
void(* entry)(void *arg)
Definition: thread.c:91
size_t stack_size
Definition: uv.h:1754
static UINT __stdcall uv__thread_start(void *arg)
Definition: thread.c:97
void * uv__malloc(size_t size)
Definition: uv-common.c:75
@ UV_THREAD_HAS_STACK_SIZE
Definition: uv.h:1749

References arg(), EACCES, EAGAIN, EINVAL, thread_ctx::entry, err, f, uv_thread_options_s::flags, HANDLE, in, NULL, uv_thread_options_s::stack_size, sysinfo, thread_stack_size(), UV__ERR, uv__free(), uv__malloc(), uv__thread_start(), and UV_THREAD_HAS_STACK_SIZE.

◆ uv_thread_equal()

int uv_thread_equal ( const uv_thread_t t1,
const uv_thread_t t2 
)

Definition at line 202 of file thread.c.

202  {
203  return *t1 == *t2;
204 }

References benchmark::t1.

◆ uv_thread_join()

int uv_thread_join ( uv_thread_t tid)

Definition at line 190 of file thread.c.

190  {
191  if (WaitForSingleObject(*tid, INFINITE))
192  return uv_translate_sys_error(GetLastError());
193  else {
194  CloseHandle(*tid);
195  *tid = 0;
196  MemoryBarrier(); /* For feature parity with pthread_join(). */
197  return 0;
198  }
199 }

References NULL, UV__ERR, and uv_translate_sys_error().

Referenced by main(), uv__stream_close(), and uv__threadpool_cleanup().

◆ uv_thread_self()

uv_thread_t uv_thread_self ( void  )

Definition at line 184 of file thread.c.

184  {
187 }
void * uv_key_get(uv_key_t *key)
Definition: thread.c:834
pthread_t uv_thread_t
Definition: unix.h:136

References uv__current_thread_init_guard, uv__current_thread_key, uv__init_current_thread_key(), uv_key_get(), and uv_once().

Variable Documentation

◆ uv__current_thread_init_guard

uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT
static

Definition at line 81 of file thread.c.

Referenced by uv__thread_start(), and uv_thread_self().

◆ uv__current_thread_key

uv_key_t uv__current_thread_key
static

Definition at line 80 of file thread.c.

Referenced by uv__init_current_thread_key(), uv__thread_start(), and uv_thread_self().