src/os/unix/ngx_pthread_thread.c - nginx-1.7.10

Global variables defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>


  7. static ngx_uint_t   nthreads;
  8. static ngx_uint_t   max_threads;


  9. static pthread_attr_t  thr_attr;


  10. ngx_err_t
  11. ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
  12.     void *arg, ngx_log_t *log)
  13. {
  14.     int  err;

  15.     if (nthreads >= max_threads) {
  16.         ngx_log_error(NGX_LOG_CRIT, log, 0,
  17.                       "no more than %ui threads can be created", max_threads);
  18.         return NGX_ERROR;
  19.     }

  20.     err = pthread_create(tid, &thr_attr, func, arg);

  21.     if (err != 0) {
  22.         ngx_log_error(NGX_LOG_ALERT, log, err, "pthread_create() failed");
  23.         return err;
  24.     }

  25.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
  26.                    "thread is created: " NGX_TID_T_FMT, *tid);

  27.     nthreads++;

  28.     return err;
  29. }


  30. ngx_int_t
  31. ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
  32. {
  33.     int  err;

  34.     max_threads = n;

  35.     err = pthread_attr_init(&thr_attr);

  36.     if (err != 0) {
  37.         ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
  38.                       "pthread_attr_init() failed");
  39.         return NGX_ERROR;
  40.     }

  41.     err = pthread_attr_setstacksize(&thr_attr, size);

  42.     if (err != 0) {
  43.         ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
  44.                       "pthread_attr_setstacksize() failed");
  45.         return NGX_ERROR;
  46.     }

  47.     ngx_threaded = 1;

  48.     return NGX_OK;
  49. }


  50. ngx_mutex_t *
  51. ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
  52. {
  53.     int           err;
  54.     ngx_mutex_t  *m;

  55.     m = ngx_alloc(sizeof(ngx_mutex_t), log);
  56.     if (m == NULL) {
  57.         return NULL;
  58.     }

  59.     m->log = log;

  60.     err = pthread_mutex_init(&m->mutex, NULL);

  61.     if (err != 0) {
  62.         ngx_log_error(NGX_LOG_ALERT, m->log, err,
  63.                       "pthread_mutex_init() failed");
  64.         return NULL;
  65.     }

  66.     return m;
  67. }


  68. void
  69. ngx_mutex_destroy(ngx_mutex_t *m)
  70. {
  71.     int  err;

  72.     err = pthread_mutex_destroy(&m->mutex);

  73.     if (err != 0) {
  74.         ngx_log_error(NGX_LOG_ALERT, m->log, err,
  75.                       "pthread_mutex_destroy(%p) failed", m);
  76.     }

  77.     ngx_free(m);
  78. }


  79. void
  80. ngx_mutex_lock(ngx_mutex_t *m)
  81. {
  82.     int  err;

  83.     if (!ngx_threaded) {
  84.         return;
  85.     }

  86.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "lock mutex %p", m);

  87.     err = pthread_mutex_lock(&m->mutex);

  88.     if (err != 0) {
  89.         ngx_log_error(NGX_LOG_ALERT, m->log, err,
  90.                       "pthread_mutex_lock(%p) failed", m);
  91.         ngx_abort();
  92.     }

  93.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);

  94.     return;
  95. }


  96. ngx_int_t
  97. ngx_mutex_trylock(ngx_mutex_t *m)
  98. {
  99.     int  err;

  100.     if (!ngx_threaded) {
  101.         return NGX_OK;
  102.     }

  103.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "try lock mutex %p", m);

  104.     err = pthread_mutex_trylock(&m->mutex);

  105.     if (err == NGX_EBUSY) {
  106.         return NGX_AGAIN;
  107.     }

  108.     if (err != 0) {
  109.         ngx_log_error(NGX_LOG_ALERT, m->log, err,
  110.                       "pthread_mutex_trylock(%p) failed", m);
  111.         ngx_abort();
  112.     }

  113.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);

  114.     return NGX_OK;
  115. }


  116. void
  117. ngx_mutex_unlock(ngx_mutex_t *m)
  118. {
  119.     int  err;

  120.     if (!ngx_threaded) {
  121.         return;
  122.     }

  123.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "unlock mutex %p", m);

  124.     err = pthread_mutex_unlock(&m->mutex);

  125.     if (err != 0) {
  126.         ngx_log_error(NGX_LOG_ALERT, m->log, err,
  127.                       "pthread_mutex_unlock(%p) failed", m);
  128.         ngx_abort();
  129.     }

  130.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is unlocked", m);

  131.     return;
  132. }


  133. ngx_cond_t *
  134. ngx_cond_init(ngx_log_t *log)
  135. {
  136.     int          err;
  137.     ngx_cond_t  *cv;

  138.     cv = ngx_alloc(sizeof(ngx_cond_t), log);
  139.     if (cv == NULL) {
  140.         return NULL;
  141.     }

  142.     cv->log = log;

  143.     err = pthread_cond_init(&cv->cond, NULL);

  144.     if (err != 0) {
  145.         ngx_log_error(NGX_LOG_ALERT, cv->log, err,
  146.                       "pthread_cond_init() failed");
  147.         return NULL;
  148.     }

  149.     return cv;
  150. }


  151. void
  152. ngx_cond_destroy(ngx_cond_t *cv)
  153. {
  154.     int  err;

  155.     err = pthread_cond_destroy(&cv->cond);

  156.     if (err != 0) {
  157.         ngx_log_error(NGX_LOG_ALERT, cv->log, err,
  158.                       "pthread_cond_destroy(%p) failed", cv);
  159.     }

  160.     ngx_free(cv);
  161. }


  162. ngx_int_t
  163. ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
  164. {
  165.     int  err;

  166.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p wait", cv);

  167.     err = pthread_cond_wait(&cv->cond, &m->mutex);

  168.     if (err != 0) {
  169.         ngx_log_error(NGX_LOG_ALERT, cv->log, err,
  170.                       "pthread_cond_wait(%p) failed", cv);
  171.         return NGX_ERROR;
  172.     }

  173.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv);

  174.     ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);

  175.     return NGX_OK;
  176. }


  177. ngx_int_t
  178. ngx_cond_signal(ngx_cond_t *cv)
  179. {
  180.     int  err;

  181.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p to signal", cv);

  182.     err = pthread_cond_signal(&cv->cond);

  183.     if (err != 0) {
  184.         ngx_log_error(NGX_LOG_ALERT, cv->log, err,
  185.                       "pthread_cond_signal(%p) failed", cv);
  186.         return NGX_ERROR;
  187.     }

  188.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is signaled", cv);

  189.     return NGX_OK;
  190. }