/*
 * Copyright (C) 2009-2012 the libgit2 contributors
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
#include "common.h"
#include "global.h"
#include "git2/threads.h" 
#include "thread-utils.h"

/**
 * Handle the global state with TLS
 *
 * If libgit2 is built with GIT_THREADS enabled,
 * the `git_threads_init()` function must be called
 * before calling any other function of the library.
 *
 * This function allocates a TLS index (using pthreads
 * or the native Win32 API) to store the global state
 * on a per-thread basis.
 *
 * Any internal method that requires global state will
 * then call `git__global_state()` which returns a pointer
 * to the global state structure; this pointer is lazily
 * allocated on each thread.
 *
 * Before shutting down the library, the
 * `git_threads_shutdown` method must be called to free
 * the previously reserved TLS index.
 *
 * If libgit2 is built without threading support, the
 * `git__global_statestate()` call returns a pointer to a single,
 * statically allocated global state. The `git_thread_`
 * functions are not available in that case.
 */

#if defined(GIT_THREADS) && defined(GIT_WIN32)

static DWORD _tls_index;
static int _tls_init = 0;

void git_threads_init(void)
{
	if (_tls_init)
		return;

	_tls_index = TlsAlloc();
	_tls_init = 1;
}

void git_threads_shutdown(void)
{
	TlsFree(_tls_index);
	_tls_init = 0;
}

git_global_st *git__global_state(void)
{
	void *ptr;

	if ((ptr = TlsGetValue(_tls_index)) != NULL)
		return ptr;

	ptr = git__malloc(sizeof(git_global_st));
	if (!ptr)
		return NULL;

	memset(ptr, 0x0, sizeof(git_global_st));
	TlsSetValue(_tls_index, ptr);
	return ptr;
}

#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)

static pthread_key_t _tls_key;
static int _tls_init = 0;

static void cb__free_status(void *st)
{
	git__free(st);
}

void git_threads_init(void)
{
	if (_tls_init)
		return;

	pthread_key_create(&_tls_key, &cb__free_status);
	_tls_init = 1;
}

void git_threads_shutdown(void)
{
	pthread_key_delete(_tls_key);
	_tls_init = 0;
}

git_global_st *git__global_state(void)
{
	void *ptr;

	if ((ptr = pthread_getspecific(_tls_key)) != NULL)
		return ptr;

	ptr = git__malloc(sizeof(git_global_st));
	if (!ptr)
		return NULL;

	memset(ptr, 0x0, sizeof(git_global_st));
	pthread_setspecific(_tls_key, ptr);
	return ptr;
}

#else

static git_global_st __state;

void git_threads_init(void)
{
	/* noop */ 
}

void git_threads_shutdown(void)
{
	/* noop */
}

git_global_st *git__global_state(void)
{
	return &__state;
}

#endif /* GIT_THREADS */
