This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/celix_err in repository https://gitbox.apache.org/repos/asf/celix.git
commit 98c5ce426729e2d86b81840e9cda2efd3db46ce2 Author: Pepijn Noltes <[email protected]> AuthorDate: Tue May 2 11:48:03 2023 +0200 Update celix err to support __thread instead of tss usage --- libs/utils/gtest/src/ErrTestSuite.cc | 4 ++-- libs/utils/include/celix_err.h | 16 +++++++++++++--- libs/utils/src/celix_err.c | 32 ++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/libs/utils/gtest/src/ErrTestSuite.cc b/libs/utils/gtest/src/ErrTestSuite.cc index 6a8c4431..16539843 100644 --- a/libs/utils/gtest/src/ErrTestSuite.cc +++ b/libs/utils/gtest/src/ErrTestSuite.cc @@ -54,7 +54,7 @@ TEST_F(ErrTestSuite, ResetErrorTest) { } TEST_F(ErrTestSuite, EdgeCaseTest) { - //test only "" error message, 1 char per message so max error count is CELIX_ERR_BUFFER_SIZE + //test only "" error messages, 1 char per message so max error count is CELIX_ERR_BUFFER_SIZE for (int i = 0; i < CELIX_ERR_BUFFER_SIZE + 10; ++i) { celix_err_push(""); } @@ -64,7 +64,7 @@ TEST_F(ErrTestSuite, EdgeCaseTest) { } EXPECT_EQ(0, celix_err_getErrorCount()); - //test only "[0-9]" error message, 2 char per message so max error count is CELIX_ERR_BUFFER_SIZE/2 + //test only "[0-9]" error messages, 2 char per message so max error count is CELIX_ERR_BUFFER_SIZE/2 for (int i = 0; i < (CELIX_ERR_BUFFER_SIZE/2) + 10; ++i) { celix_err_pushf("%i", i % 10); } diff --git a/libs/utils/include/celix_err.h b/libs/utils/include/celix_err.h index 7acb0f77..4fc3b408 100644 --- a/libs/utils/include/celix_err.h +++ b/libs/utils/include/celix_err.h @@ -32,7 +32,6 @@ extern "C" { * @thread_safety Thread safe. */ -//TODO make configurable with a cmake option /** * @brief The error message buffer size per thread. */ @@ -41,26 +40,37 @@ extern "C" { /** * @brief Returns the last error message from the current thread. - * The error message is stored on a local thread storage and is valid until a new error message is pushed. - * @returnval NULL if no error message is available. + * + * The returned error message is stored on a local thread storage and is valid until a new error message is pushed. + * + * @return The last error message from the current thread. + * + * @retval NULL if no error message is available. */ CELIX_UTILS_EXPORT const char* celix_err_popLastError(); /** * @brief Push an formatted error message to the thread specific storage rcm errors. + * + * @param format The format string for the error message. + * @param ... The arguments for the format string. */ CELIX_UTILS_EXPORT void celix_err_pushf(const char* format, ...) __attribute__((format(printf, 1, 2))); /** * @brief Push an error message to the thread specific storage rcm errors. + * + * @param msg The error message to push. */ CELIX_UTILS_EXPORT void celix_err_push(const char* msg); /** * @brief Returns the number of error messages from the current thread. + * + * @return The number of error messages for the current thread. */ CELIX_UTILS_EXPORT int celix_err_getErrorCount(); diff --git a/libs/utils/src/celix_err.c b/libs/utils/src/celix_err.c index a6a67f11..e5c55bf2 100644 --- a/libs/utils/src/celix_err.c +++ b/libs/utils/src/celix_err.c @@ -19,19 +19,23 @@ #include "celix_err.h" -#include <stdlib.h> #include <stdarg.h> #include <stdio.h> -#include <pthread.h> #include <string.h> -pthread_key_t celix_err_tssKey; //TODO replace with celix_tss_key and celix_tss_* functions +#ifdef CELIX_ERR_USE_THREAD_LOCAL +#include <stdlib.h> + +#include "celix_threads.h" +#endif typedef struct celix_err { char buffer[CELIX_ERR_BUFFER_SIZE]; size_t pos; } celix_err_t; +#ifdef CELIX_ERR_USE_THREAD_LOCAL +celix_tss_key_t celix_err_tssKey; static void celix_err_destroyTssErr(void* data) { celix_err_t* err = data; if (err != NULL) { @@ -40,7 +44,7 @@ static void celix_err_destroyTssErr(void* data) { } static celix_err_t* celix_err_getTssErr() { - celix_err_t* err = pthread_getspecific(celix_err_tssKey); + celix_err_t* err = celix_tss_get(celix_err_tssKey); if (err) { return err; } @@ -48,7 +52,7 @@ static celix_err_t* celix_err_getTssErr() { err = malloc(sizeof(*err)); if (err) { err->pos = 0; //no entry - int rc = pthread_setspecific(celix_err_tssKey, err); + int rc = celix_tss_set(celix_err_tssKey, err); if (rc != 0) { fprintf(stderr, "Failed to set thread specific storage for celix_err: %s\n", strerror(rc)); free(err); @@ -61,18 +65,27 @@ static celix_err_t* celix_err_getTssErr() { } __attribute__((constructor)) void celix_err_initThreadSpecificStorageKey() { - int rc = pthread_key_create(&celix_err_tssKey, celix_err_destroyTssErr); + int rc = celix_tss_create(&celix_err_tssKey, celix_err_destroyTssErr); if (rc != 0) { fprintf(stderr,"Failed to create thread specific storage key for celix_err\n"); } } __attribute__((destructor)) void celix_err_deinitThreadSpecificStorageKey() { - int rc = pthread_key_delete(celix_err_tssKey); + int rc = celix_tss_delete(celix_err_tssKey); if (rc != 0) { fprintf(stderr,"Failed to delete thread specific storage key for celix_err\n"); } } +#else //Use __thread static variable instead of thread specific storage functions + +__thread celix_err_t celix_err_tssErr = { .buffer = {0}, .pos = 0 }; + +static celix_err_t* celix_err_getTssErr() { + return &celix_err_tssErr; +} + +#endif const char* celix_err_popLastError() { const char* result = NULL; @@ -100,9 +113,8 @@ int celix_err_getErrorCount() { } void celix_err_resetErrors() { - void* data = pthread_getspecific(celix_err_tssKey); - if (data != NULL) { - celix_err_t* err = data; + celix_err_t* err = celix_err_getTssErr(); + if (err) { err->pos = 0; //no entry } }
