I have attempted doing a fluent API for creating random int
arrays, and the following is what I came up with:
fluent_arrays.h:
#ifndef FLUENT_ARRAYS_H
#define FLUENT_ARRAYS_H
#define REQUEST_THREAD_LOCAL 1
#ifdef REQUEST_THREAD_LOCAL
#define THREAD_LOCAL __thread
#else
#define THREAD_LOCAL
#endif
/*******************************************************************************
* The maximum integer selector. *
*******************************************************************************/
typedef struct {
int* (*with_maximum)(const int maximum);
} maximum_selector;
/*******************************************************************************
* The minimum integer selector. *
*******************************************************************************/
typedef struct {
maximum_selector* (*with_minimum)(const int minimum);
} minimum_selector;
/*******************************************************************************
* The array length selector. *
*******************************************************************************/
typedef struct {
minimum_selector* (*of_length)(const size_t length);
} size_selector;
/*******************************************************************************
* Thread specific state. *
*******************************************************************************/
static THREAD_LOCAL int tl_api_initialised = 0;
static THREAD_LOCAL int tl_minimum;
static THREAD_LOCAL size_t tl_length;
/*******************************************************************************
* Global state. *
*******************************************************************************/
static size_selector gl_size_selector;
static minimum_selector gl_minimum_selector;
static maximum_selector gl_maximum_selector;
/*******************************************************************************
* Implements maximum integer selection and creation of actual array. *
*******************************************************************************/
static int* impl_with_maximum(const int maximum)
{
int* p_array = malloc(tl_length);
const int minimum = tl_minimum;
for (size_t i = 0; i < tl_length; ++i)
{
p_array[i] = (rand() % (maximum - minimum + 1)) + minimum;
}
return p_array;
}
/*******************************************************************************
* Implements minimum integer selection. *
*******************************************************************************/
static maximum_selector* impl_with_minimum(const int minimum)
{
tl_minimum = minimum;
return &gl_maximum_selector;
}
/*******************************************************************************
* Implements array length selection. *
*******************************************************************************/
static minimum_selector* impl_with_length(const size_t length)
{
tl_length = length;
return &gl_minimum_selector;
}
/*******************************************************************************
* Initiates the fluent API for creating random arrays. *
*******************************************************************************/
size_selector* create_random_array()
{
if (!tl_api_initialised)
{
gl_size_selector.of_length = impl_with_length;
gl_minimum_selector.with_minimum = impl_with_minimum;
gl_maximum_selector.with_maximum = impl_with_maximum;
tl_api_initialised = 1;
}
return &gl_size_selector;
}
#endif /* FLUENT_ARRAYS_H */
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "fluent_arrays.h"
/*******************************************************************************
* Prints an integer array. *
*******************************************************************************/
static void print_int_array(const int *const p_array, const size_t length)
{
for (size_t i = 0; i < length; ++i)
{
printf("%d ", p_array[i]);
}
puts("");
}
/*******************************************************************************
* The demonstration. *
*******************************************************************************/
int main(int argc, char** argv) {
srand(time(NULL)); // <-- I know that this is not thread-safe.
const size_t LENGTH = 30;
// FUNKY FLUENT API IN C
int* p_array = create_random_array()->of_length(LENGTH)
->with_minimum(-5)
->with_maximum(20);
print_int_array(p_array, LENGTH);
return (EXIT_SUCCESS);
}
My main question is: how can I make this thread-safe (*nix, Mac OS X, Windows)?