Files
src-1.2/engine/shared/library/sharedFoundation/src/linux/PerThreadData.cpp
T

162 lines
4.6 KiB
C++

// ======================================================================
//
// PerThreadData.cpp
// jeff grills
//
// copyright 1998 Bootprint Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/PerThreadData.h"
#include "sharedSynchronization/Gate.h"
// ======================================================================
pthread_key_t PerThreadData::slot;
bool PerThreadData::slotCreated=false;
// ======================================================================
// Install the per-thread-data subsystem
//
// Remarks:
//
// This routine will install the per-thread-data subsystem that is required for several
// other subsystems in the engine. It should be called from the primary thread before
// any other threads have been created. It will also call threadInstall() for the
// primary thread.
//
// See Also:
//
// PerThreadData::remove()
void PerThreadData::install(void)
{
if (pthread_key_create(&slot, 0)!=0)
{
FATAL(true, ("pthread_key_create failed"));
}
slotCreated=true;
threadInstall();
}
// ----------------------------------------------------------------------
/**
* Remove the per-thread-subsystem.
*
* This routine should be called by the primary thread after all other threads have
* terminated, and no other uses of per-thread-data will occur.
*
* @see PerThreadData::install()
*/
void PerThreadData::remove(void)
{
threadRemove();
if (pthread_key_delete(slot)!=0)
{
FATAL(true, ("pthread_key_delete failed"));
}
slotCreated=false;
}
// ----------------------------------------------------------------------
/**
* Get access to the per-thread-data.
*
* This routine will verify the per-thread-data subsystem has been installed and the
* threadInstall() function has been called for the current thread.
*
* @return A pointer to the per-thread-data.
*/
PerThreadData::Data *PerThreadData::getData(bool allowReturnNull)
{
UNREF(allowReturnNull);
if (!slotCreated)
{
DEBUG_FATAL(true && !allowReturnNull, ("not installed"));
return NULL;
}
Data * const data = reinterpret_cast<Data *>(pthread_getspecific(slot));
DEBUG_FATAL(!data && !allowReturnNull, ("not installed for this thread"));
return data;
}
// ----------------------------------------------------------------------
/**
* Create the per-thread-data for a new thread.
*
* This routine should be called in a thread before the first usage of per-thread-data.
*
* If the client is calling this function on a thread that existed before the engine was
* installed, the client should set isNewThread to false. Setting isNewThread to false
* prevents the function from validating that the thread's TLS is NULL. For threads existing
* before the engine is installed, the TLS data for the thread is undefined.
*
* @param isNewThread [IN] true if the thread was created after the engine was installed, false otherwise
* @see PerThreadData::threadRemove()
*/
void PerThreadData::threadInstall(bool isNewThread)
{
UNREF(isNewThread);
DEBUG_FATAL(!slotCreated, ("not installed"));
// only check for already-set data if this is supposed to be a new thread
DEBUG_FATAL(isNewThread && pthread_getspecific(slot), ("already installed for this thread"));
// create the data
Data * const data = new Data;
// initialize the data
memset(data, 0, sizeof(*data));
//create the event for file streaming reads
data->readGate = new Gate(false);
// set the data into the thread slot
const BOOL result = pthread_setspecific(slot, data);
UNREF(result);
DEBUG_FATAL(result, ("pthread_setspecific failed")); //NB: unlike Windows, returns 0 on success.
} //lint !e429 // Warning -- Custodial pointer 'data' has not been freed or returned) // stored int thread-local-storage
// ----------------------------------------------------------------------
/**
* Destroythe per-thread-data for a terminating thread.
*
* This routine should be called in a thread after the last usage of per-thread-data.
*
* @see PerThreadData::threadInstall()
*/
void PerThreadData::threadRemove(void)
{
DEBUG_FATAL(!slotCreated, ("not installed"));
DEBUG_FATAL(!pthread_getspecific(slot), ("thread not installed"));
// get the data
Data *data = getData();
//close the event used for file streaming reads
delete data->readGate;
data->readGate = NULL;
// wipe the data in the thread slot
const BOOL result2 = pthread_setspecific(slot, NULL);
UNREF(result2);
DEBUG_FATAL(result2, ("TlsSetValue failed")); //NB: unlike Windows, returns 0 on success.
// free the memory
delete data;
}
// ======================================================================