"Fossies" - the Fresh Open Source Software Archive

Member "rrdtool-1.7.2/src/rrd_thread_safe.c" (27 May 2019, 3296 Bytes) of package /linux/misc/rrdtool-1.7.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rrd_thread_safe.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.7.1_vs_1.7.2.

    1 /*****************************************************************************
    2  * RRDtool 1.7.2 Copyright by Tobi Oetiker
    3  * This file:     Copyright 2003 Peter Stamfest <peter@stamfest.at> 
    4  *                             & Tobias Oetiker
    5  * Distributed under the GPL
    6  *****************************************************************************
    7  * rrd_thread_safe.c   Contains routines used when thread safety is required
    8  *****************************************************************************
    9  * $Id$
   10  *************************************************************************** */
   11 
   12 #include <pthread.h>
   13 #include <string.h>
   14 /* #include <error.h> */
   15 #include "rrd.h"
   16 #include "rrd_tool.h"
   17 
   18 /* Key for the thread-specific rrd_context */
   19 static pthread_key_t context_key;
   20 
   21 /* Once-only initialization of the key */
   22 static pthread_once_t context_key_once = PTHREAD_ONCE_INIT;
   23 
   24 /* Free the thread-specific rrd_context - we might actually use
   25    rrd_free_context instead...
   26  */
   27 static void context_destroy_context(
   28     void *ctx_)
   29 {
   30     rrd_context_t *ctx = ctx_;
   31 
   32     if (ctx)
   33         rrd_free_context(ctx);
   34 }
   35 
   36 /* Allocate the key */
   37 static void context_get_key(
   38     void)
   39 {
   40     pthread_key_create(&context_key, context_destroy_context);
   41 }
   42 
   43 rrd_context_t *rrd_get_context(
   44     void)
   45 {
   46     rrd_context_t *ctx;
   47 
   48     pthread_once(&context_key_once, context_get_key);
   49     ctx = pthread_getspecific(context_key);
   50     if (!ctx) {
   51         ctx = rrd_new_context();
   52         pthread_setspecific(context_key, ctx);
   53     }
   54     return ctx;
   55 }
   56 
   57 #ifdef HAVE_STRERROR_R
   58 const char *rrd_strerror(
   59     int err)
   60 {
   61     rrd_context_t *ctx = rrd_get_context();
   62     char *ret = "unknown error";
   63 
   64     *ctx->lib_errstr = '\0';
   65 
   66     /* Even though POSIX/XSI requires "strerror_r" to return an "int", some
   67      * systems (e.g. the GNU libc) return a "char *" _and_ ignore the second
   68      * argument ... -tokkee */
   69 #ifdef STRERROR_R_CHAR_P
   70     ret = strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr));
   71     if ((! ret) || (*ret == '\0')) {
   72         if (*ctx->lib_errstr != '\0')
   73             ret = ctx->lib_errstr;
   74         else {
   75             /* according to the manpage this should not happen -
   76                let's handle it somehow sanely anyway */
   77             snprintf(ctx->lib_errstr, sizeof(ctx->lib_errstr),
   78                     "unknown error %i - strerror_r did not return anything",
   79                     err);
   80             ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
   81             ret = ctx->lib_errstr;
   82         }
   83     }
   84 #else /* ! STRERROR_R_CHAR_P */
   85     if (strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr))) {
   86         snprintf(ctx->lib_errstr, sizeof(ctx->lib_errstr),
   87                 "unknown error %i - strerror_r returned with errno = %i",
   88                 err, errno);
   89         ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
   90     }
   91     ret = ctx->lib_errstr;
   92 #endif
   93     return ret;
   94 }
   95 #else
   96 #undef strerror
   97 const char *rrd_strerror(
   98     int err)
   99 {
  100     static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
  101     rrd_context_t *ctx;
  102 
  103     ctx = rrd_get_context();
  104     pthread_mutex_lock(&mtx);
  105     strncpy(ctx->lib_errstr, strerror(err), sizeof(ctx->lib_errstr));
  106     ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
  107     pthread_mutex_unlock(&mtx);
  108     return ctx->lib_errstr;
  109 }
  110 #endif