version 1.58, 2006/08/09 21:12:42
|
version 1.59, 2006/11/10 18:14:58
|
|
|
// | // |
//============================================================================== | //============================================================================== |
// | // |
// Author: Mike Day (mdday@us.ibm.com) |
|
// |
|
// Modified By: Markus Mueller |
|
// Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) |
|
// Amit K Arora, IBM (amita@in.ibm.com) for PEP#101 |
|
// David Dillard, VERITAS Software Corp. |
|
// (david.dillard@veritas.com) |
|
// Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) |
|
// Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2393 |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#ifndef Pegasus_Thread_h | #ifndef Pegasus_Thread_h |
|
|
_data =::operator new(_size); | _data =::operator new(_size); |
} | } |
| |
thread_data(const char *key, size_t size, void *data) : |
thread_data(const char *key, size_t size, void *data) |
_delete_func(default_delete), _size(size) |
: _delete_func(default_delete), _size(size) |
{ | { |
PEGASUS_ASSERT(key != NULL); | PEGASUS_ASSERT(key != NULL); |
PEGASUS_ASSERT(data != NULL); | PEGASUS_ASSERT(data != NULL); |
|
|
} | } |
| |
/** | /** |
* This function is used to retrieve data from the |
This function is used to retrieve data from the |
* TSD, the thread specific data. |
TSD, the thread specific data. |
* |
|
* Be aware that there is NOTHING in place to stop |
Be aware that there is NOTHING in place to stop |
* other users of the thread to change the data you |
other users of the thread to change the data you |
* get from this function. |
get from this function. |
* |
|
* You, the developer has to make sure that there are |
You, the developer has to make sure that there are |
* no situations in which this can arise (ie, have a |
no situations in which this can arise (ie, have a |
* lock for the function which manipulates the TSD. |
lock for the function which manipulates the TSD. |
*/ | */ |
void get_data(void **data, size_t * size) | void get_data(void **data, size_t * size) |
{ | { |
|
|
| |
*data = _data; | *data = _data; |
*size = _size; | *size = _size; |
return; |
|
|
|
} | } |
| |
// @exception NullPointer | // @exception NullPointer |
|
|
*buf =::operator new(_size); | *buf =::operator new(_size); |
*size = _size; | *size = _size; |
memcpy(*buf, _data, _size); | memcpy(*buf, _data, _size); |
return; |
|
} | } |
| |
inline Boolean operator==(const void *key) const | inline Boolean operator==(const void *key) const |
{ | { |
if (!strcmp(_key.get(), reinterpret_cast < const char *>(key))) | if (!strcmp(_key.get(), reinterpret_cast < const char *>(key))) |
return (true); |
return true; |
return (false); |
return false; |
} | } |
| |
inline Boolean operator==(const thread_data & b) const | inline Boolean operator==(const thread_data & b) const |
{ | { |
return (operator==(b._key.get())); |
return operator==(b._key.get()); |
} | } |
| |
static bool equal(const thread_data * node, const void *key) | static bool equal(const thread_data * node, const void *key) |
|
|
{ | { |
public: | public: |
| |
Thread(ThreadReturnType(PEGASUS_THREAD_CDECL * start) (void *), |
Thread( |
void *parameter, Boolean detached); |
ThreadReturnType(PEGASUS_THREAD_CDECL* start) (void*), |
|
void* parameter, |
|
Boolean detached); |
| |
~Thread(); | ~Thread(); |
| |
|
|
_tsd.lock(); | _tsd.lock(); |
thread_data *tsd = _tsd.find(thread_data::equal, key); | thread_data *tsd = _tsd.find(thread_data::equal, key); |
if (tsd != NULL) | if (tsd != NULL) |
return ((void *) (tsd->_data)); |
return (void *) (tsd->_data); |
else | else |
return (NULL); |
return NULL; |
} | } |
| |
// @exception IPCException | // @exception IPCException |
|
|
_tsd.try_lock(); | _tsd.try_lock(); |
thread_data *tsd = _tsd.find(thread_data::equal, key); | thread_data *tsd = _tsd.find(thread_data::equal, key); |
if (tsd != NULL) | if (tsd != NULL) |
return ((void *) (tsd->_data)); |
return (void *) (tsd->_data); |
else | else |
return (NULL); |
return NULL; |
} | } |
| |
| |
|
|
// create or re-initialize tsd associated with the key | // create or re-initialize tsd associated with the key |
// if the tsd already exists, delete the existing buffer | // if the tsd already exists, delete the existing buffer |
// @exception IPCException | // @exception IPCException |
void put_tsd(const char *key, void (*delete_func) (void *), Uint32 size, |
void put_tsd( |
|
const char* key, |
|
void (*delete_func) (void *), |
|
Uint32 size, |
void *value) | void *value) |
{ | { |
PEGASUS_ASSERT(key != NULL); | PEGASUS_ASSERT(key != NULL); |
AutoPtr < thread_data > tsd; | AutoPtr < thread_data > tsd; |
tsd.reset(_tsd.remove(thread_data::equal, key)); // may throw |
// This may throw an IPCException |
// an IPC |
tsd.reset(_tsd.remove(thread_data::equal, key)); |
// exception |
|
tsd.reset(); | tsd.reset(); |
AutoPtr < thread_data > ntsd(new thread_data(key)); | AutoPtr < thread_data > ntsd(new thread_data(key)); |
ntsd->put_data(delete_func, size, value); | ntsd->put_data(delete_func, size, value); |
try |
// This may throw an IPCException |
{ |
|
_tsd.insert_front(ntsd.get()); | _tsd.insert_front(ntsd.get()); |
} |
|
catch(IPCException & e) |
|
{ |
|
e = e; |
|
throw; |
|
} |
|
ntsd.release(); | ntsd.release(); |
} | } |
|
|
inline ThreadReturnType get_exit() | inline ThreadReturnType get_exit() |
{ | { |
return _exit_code; | return _exit_code; |
|
|
// Note: this may return NULL if no Thread object is associated | // Note: this may return NULL if no Thread object is associated |
// with the caller's thread. | // with the caller's thread. |
// | // |
static Thread *getCurrent(); // l10n |
static Thread *getCurrent(); |
| |
// | // |
// Sets the Thread object associated with the caller's thread. | // Sets the Thread object associated with the caller's thread. |
// Note: the Thread object must be placed on the heap. | // Note: the Thread object must be placed on the heap. |
// | // |
static void setCurrent(Thread * thrd); // l10n |
static void setCurrent(Thread* thrd); |
| |
// | // |
// Gets the AcceptLanguageList object associated with the caller's | // Gets the AcceptLanguageList object associated with the caller's |
|
|
// Note: this may return NULL if no Thread object, or no | // Note: this may return NULL if no Thread object, or no |
// AcceptLanguageList object, is associated with the caller's thread. | // AcceptLanguageList object, is associated with the caller's thread. |
// | // |
static AcceptLanguageList *getLanguages(); // l10n |
static AcceptLanguageList* getLanguages(); |
| |
// | // |
// Sets the AcceptLanguageList object associated with the caller's | // Sets the AcceptLanguageList object associated with the caller's |
|
|
// the caller's thread. | // the caller's thread. |
// Note: the AcceptLanguageList object must be placed on the heap. | // Note: the AcceptLanguageList object must be placed on the heap. |
// | // |
static void setLanguages(AcceptLanguageList * langs); // l10n |
static void setLanguages(AcceptLanguageList* langs); |
| |
// | // |
// Removes the AcceptLanguageList object associated with the caller's | // Removes the AcceptLanguageList object associated with the caller's |
// Thread. | // Thread. |
// | // |
static void clearLanguages(); // l10n |
static void clearLanguages(); |
| |
private: | private: |
Thread(); | Thread(); |
| |
static Sint8 initializeKey(); // l10n |
static Sint8 initializeKey(); |
| |
// @exception IPCException | // @exception IPCException |
inline void create_tsd(const char *key) | inline void create_tsd(const char *key) |
|
|
_tsd.insert_front(tsd.get()); | _tsd.insert_front(tsd.get()); |
tsd.release(); | tsd.release(); |
} | } |
|
|
ThreadHandle _handle; | ThreadHandle _handle; |
Boolean _is_detached; | Boolean _is_detached; |
Boolean _cancel_enabled; | Boolean _cancel_enabled; |
|
|
void *_thread_parm; | void *_thread_parm; |
ThreadReturnType _exit_code; | ThreadReturnType _exit_code; |
static Boolean _signals_blocked; | static Boolean _signals_blocked; |
static TSDKeyType _platform_thread_key; // l10n |
static TSDKeyType _platform_thread_key; |
static Boolean _key_initialized; // l10n |
static Boolean _key_initialized; |
static Boolean _key_error; // l10n |
static Boolean _key_error; |
}; | }; |
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |