Skip to content

Commit

Permalink
Add checks for inadvertant use of symbols from C11 threads.h
Browse files Browse the repository at this point in the history
  • Loading branch information
wch committed Jan 4, 2019
1 parent 20ff554 commit 48cc5fb
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 21 deletions.
58 changes: 58 additions & 0 deletions src/badthreads.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef _BADTHREADS_H_
#define _BADTHREADS_H_

/*
* This file contains functions and symbols that are defined in C11 threads.h.
* If any of these symbols are used in a file that includes badthreads.h, it
* should throw an error at compile time.
*
* The purpose of this file is to make sure that code does not accidentally
* use symbols from threads.h. If this happens, and the system C library has
* C11-style thread support, then the resulting object could link to the
* system's functions that have the same name, instead of the local functions.
*/

#define thrd_t THREADS_H_ERROR
#define thrd_create THREADS_H_ERROR
#define thrd_equal THREADS_H_ERROR
#define thrd_current THREADS_H_ERROR
#define thrd_sleep THREADS_H_ERROR
#define thrd_yield THREADS_H_ERROR
#define thrd_exit THREADS_H_ERROR
#define thrd_detach THREADS_H_ERROR
#define thrd_join THREADS_H_ERROR
#define thrd_success THREADS_H_ERROR
#define thrd_timedout THREADS_H_ERROR
#define thrd_busy THREADS_H_ERROR
#define thrd_nomem THREADS_H_ERROR
#define thrd_error THREADS_H_ERROR
#define thrd_start_t THREADS_H_ERROR
#define mtx_t THREADS_H_ERROR
#define mtx_init THREADS_H_ERROR
#define mtx_lock THREADS_H_ERROR
#define mtx_timedlock THREADS_H_ERROR
#define mtx_trylock THREADS_H_ERROR
#define mtx_unlock THREADS_H_ERROR
#define mtx_destroy THREADS_H_ERROR
#define mtx_plain THREADS_H_ERROR
#define mtx_recursive THREADS_H_ERROR
#define mtx_timed THREADS_H_ERROR
#define call_once THREADS_H_ERROR
#define cnd_t THREADS_H_ERROR
#define cnd_init THREADS_H_ERROR
#define cnd_signal THREADS_H_ERROR
#define cnd_broadcast THREADS_H_ERROR
#define cnd_wait THREADS_H_ERROR
#define cnd_timedwait THREADS_H_ERROR
#define cnd_destroy THREADS_H_ERROR
#define thread_local THREADS_H_ERROR
#define tss_t THREADS_H_ERROR
#define TSS_DTOR_ITERATIONS THREADS_H_ERROR
#define tss_dtor_t THREADS_H_ERROR
#define tss_create THREADS_H_ERROR
#define tss_get THREADS_H_ERROR
#define tss_set THREADS_H_ERROR
#define tss_delete THREADS_H_ERROR


#endif
21 changes: 11 additions & 10 deletions src/tinycthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ freely, subject to the following restrictions:
*/

#include "tinycthread.h"
#include "badthreads.h"
#include <stdlib.h>

/* Platform specific includes */
Expand Down Expand Up @@ -474,11 +475,11 @@ int tct_cnd_timedwait(tct_cnd_t *cond, tct_mtx_t *mtx, const struct timespec *ts
#if defined(_TTHREAD_WIN32_)
struct TinyCThreadTSSData {
void* value;
tss_t key;
tct_tss_t key;
struct TinyCThreadTSSData* next;
};

static tss_dtor_t _tinycthread_tss_dtors[1088] = { NULL, };
static tct_tss_dtor_t _tinycthread_tss_dtors[1088] = { NULL, };

static _Thread_local struct TinyCThreadTSSData* _tinycthread_tss_head = NULL;
static _Thread_local struct TinyCThreadTSSData* _tinycthread_tss_tail = NULL;
Expand All @@ -491,7 +492,7 @@ static void _tinycthread_tss_cleanup (void) {
unsigned int again = 1;
void* value;

for (iteration = 0 ; iteration < TSS_DTOR_ITERATIONS && again > 0 ; iteration++)
for (iteration = 0 ; iteration < TCT_TSS_DTOR_ITERATIONS && again > 0 ; iteration++)
{
again = 0;
for (data = _tinycthread_tss_head ; data != NULL ; data = data->next)
Expand Down Expand Up @@ -550,7 +551,7 @@ static void NTAPI _tinycthread_tss_callback(PVOID h, DWORD dwReason, PVOID pv)

/** Information to pass to the new thread (what to run). */
typedef struct {
thrd_start_t mFunction; /**< Pointer to the function to be executed. */
tct_thrd_start_t mFunction; /**< Pointer to the function to be executed. */
void * mArg; /**< Function argument for the thread function. */
} _thread_start_info;

Expand All @@ -561,7 +562,7 @@ static DWORD WINAPI _thrd_wrapper_function(LPVOID aArg)
static void * _thrd_wrapper_function(void * aArg)
#endif
{
thrd_start_t fun;
tct_thrd_start_t fun;
void *arg;
int res;

Expand All @@ -588,7 +589,7 @@ static void * _thrd_wrapper_function(void * aArg)
#endif
}

int tct_thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
int tct_thrd_create(thrd_t *thr, tct_thrd_start_t func, void *arg)
{
/* Fill out the thread startup information (passed to the thread wrapper,
which will eventually free it) */
Expand Down Expand Up @@ -747,7 +748,7 @@ void tct_thrd_yield(void)
#endif
}

int tct_tss_create(tss_t *key, tss_dtor_t dtor)
int tct_tss_create(tct_tss_t *key, tct_tss_dtor_t dtor)
{
#if defined(_TTHREAD_WIN32_)
*key = TlsAlloc();
Expand All @@ -765,7 +766,7 @@ int tct_tss_create(tss_t *key, tss_dtor_t dtor)
return tct_thrd_success;
}

void tct_tss_delete(tss_t key)
void tct_tss_delete(tct_tss_t key)
{
#if defined(_TTHREAD_WIN32_)
struct TinyCThreadTSSData* data = (struct TinyCThreadTSSData*) TlsGetValue (key);
Expand Down Expand Up @@ -802,7 +803,7 @@ void tct_tss_delete(tss_t key)
#endif
}

void *tct_tss_get(tss_t key)
void *tct_tss_get(tct_tss_t key)
{
#if defined(_TTHREAD_WIN32_)
struct TinyCThreadTSSData* data = (struct TinyCThreadTSSData*)TlsGetValue(key);
Expand All @@ -816,7 +817,7 @@ void *tct_tss_get(tss_t key)
#endif
}

int tct_tss_set(tss_t key, void *val)
int tct_tss_set(tct_tss_t key, void *val)
{
#if defined(_TTHREAD_WIN32_)
struct TinyCThreadTSSData* data = (struct TinyCThreadTSSData*)TlsGetValue(key);
Expand Down
24 changes: 13 additions & 11 deletions src/tinycthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ freely, subject to the following restrictions:
extern "C" {
#endif

#include "badthreads.h"

// jcheng 2017-11-03: _XOPEN_SOURCE 600 is necessary to prevent Solaris headers
// from complaining about the combination of C99 and _XOPEN_SOURCE <= 500. The
// error message starts with:
Expand Down Expand Up @@ -171,9 +173,9 @@ int _tthread_timespec_get(struct timespec *ts, int base);

/* Macros */
#if defined(_TTHREAD_WIN32_)
#define TSS_DTOR_ITERATIONS (4)
#define TCT_TSS_DTOR_ITERATIONS (4)
#else
#define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
#define TCT_TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
#endif

/* Function return values */
Expand Down Expand Up @@ -342,7 +344,7 @@ typedef pthread_t thrd_t;
* @return The thread return value, which can be obtained by another thread
* by using the @ref thrd_join() function.
*/
typedef int (*thrd_start_t)(void *arg);
typedef int (*tct_thrd_start_t)(void *arg);

/** Create a new thread.
* @param thr Identifier of the newly created thread.
Expand All @@ -356,7 +358,7 @@ typedef int (*thrd_start_t)(void *arg);
* original thread has exited and either been detached or joined to another
* thread.
*/
int tct_thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
int tct_thrd_create(thrd_t *thr, tct_thrd_start_t func, void *arg);

/** Identify the calling thread.
* @return The identifier of the calling thread.
Expand Down Expand Up @@ -412,15 +414,15 @@ void tct_thrd_yield(void);

/* Thread local storage */
#if defined(_TTHREAD_WIN32_)
typedef DWORD tss_t;
typedef DWORD tct_tss_t;
#else
typedef pthread_key_t tss_t;
typedef pthread_key_t tct_tss_t;
#endif

/** Destructor function for a thread-specific storage.
* @param val The value of the destructed thread-specific storage.
*/
typedef void (*tss_dtor_t)(void *val);
typedef void (*tct_tss_dtor_t)(void *val);

/** Create a thread-specific storage.
* @param key The unique key identifier that will be set if the function is
Expand All @@ -434,21 +436,21 @@ typedef void (*tss_dtor_t)(void *val);
* for DLLs loaded with LoadLibraryEx. In order to be certain, you
* should use @ref thrd_create whenever possible.
*/
int tct_tss_create(tss_t *key, tss_dtor_t dtor);
int tct_tss_create(tct_tss_t *key, tct_tss_dtor_t dtor);

/** Delete a thread-specific storage.
* The function releases any resources used by the given thread-specific
* storage.
* @param key The key that shall be deleted.
*/
void tct_tss_delete(tss_t key);
void tct_tss_delete(tct_tss_t key);

/** Get the value for a thread-specific storage.
* @param key The thread-specific storage identifier.
* @return The value for the current thread held in the given thread-specific
* storage.
*/
void *tct_tss_get(tss_t key);
void *tct_tss_get(tct_tss_t key);

/** Set the value for a thread-specific storage.
* @param key The thread-specific storage identifier.
Expand All @@ -457,7 +459,7 @@ void *tct_tss_get(tss_t key);
* @return @ref thrd_success on success, or @ref thrd_error if the request could
* not be honored.
*/
int tct_tss_set(tss_t key, void *val);
int tct_tss_set(tct_tss_t key, void *val);

#if defined(_TTHREAD_WIN32_)
typedef struct {
Expand Down

0 comments on commit 48cc5fb

Please sign in to comment.