From: <sv...@ww...> - 2005-11-13 18:01:54
|
Author: mkrose Date: 2005-11-13 10:01:44 -0800 (Sun, 13 Nov 2005) New Revision: 1670 Modified: trunk/CSP/SimData/Include/SimData/LogStream.h trunk/CSP/SimData/Include/SimData/Thread.h trunk/CSP/SimData/Include/SimData/ThreadUtil.h trunk/CSP/SimData/Source/LogStream.cpp trunk/CSP/SimData/Source/ThreadUtil.cpp Log: Fix compile errors under windows related to pthread_t. Provide a somewhat more robust way of dealing with these objects. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1670 Modified: trunk/CSP/SimData/Include/SimData/LogStream.h =================================================================== --- trunk/CSP/SimData/Include/SimData/LogStream.h 2005-11-13 16:25:27 UTC (rev 1669) +++ trunk/CSP/SimData/Include/SimData/LogStream.h 2005-11-13 18:01:44 UTC (rev 1670) @@ -105,7 +105,7 @@ void setLocking(bool thread_safe=true) { m_threadsafe = thread_safe; } void lock() { if (m_threadsafe) m_mutex.lock(); } void unlock() { if (m_threadsafe) m_mutex.unlock(); } - uint32 initialThreadId() const { return m_initial_thread_id; } + pthread_t initialThread() const { return m_initial_thread; } #endif // SIMDATA_NOTHREADS /** Test if a given priority and category should be logged. @@ -145,7 +145,7 @@ #ifndef SIMDATA_NOTHREADS ThreadMutex m_mutex; bool m_threadsafe; - uint32 m_initial_thread_id; + pthread_t m_initial_thread; #endif }; Modified: trunk/CSP/SimData/Include/SimData/Thread.h =================================================================== --- trunk/CSP/SimData/Include/SimData/Thread.h 2005-11-13 16:25:27 UTC (rev 1669) +++ trunk/CSP/SimData/Include/SimData/Thread.h 2005-11-13 18:01:44 UTC (rev 1670) @@ -64,7 +64,7 @@ /** Return the id of the current thread. */ - static inline unsigned long id() { return pthread_self(); } + static inline pthread_t id() { return pthread_self(); } /** Terminate the currently executing thread. */ @@ -147,31 +147,6 @@ public: typedef simdata::Ref<Task> Ref; -#ifndef PTHREADS_WIN - typedef pthread_t ThreadId; -#else - // small wrapper for pthreads win dated 11-22-2004 - struct ThreadId: public pthread_t { - ThreadId(unsigned int i) {x = i;} - ThreadId& operator=(const pthread_t& other) { - if (this != &other) { - x = other.x; - p = other.p; - } - return *this; - } - bool operator==(unsigned int i) const { - return x == i; - } - bool operator!=(unsigned int i) const { - return !(*this == i); - } - bool operator&&(bool other) const { - return (*this != 0) && other; - } - }; -#endif - /** Test if a request to abort the task has been made. * * @return true if abort() has been called, false otherwise. @@ -214,7 +189,7 @@ /** Initialize the task state. */ - Task(): m_running(false), m_detached(false), m_complete(false), m_abort(false), m_thread_id(0) { + Task(): m_running(false), m_detached(false), m_complete(false), m_abort(false) { } virtual ~Task() { } @@ -247,7 +222,6 @@ */ void _execute() { m_running = true; - m_thread_id = pthread_self(); try { run(); } catch (Exception &e) { @@ -283,15 +257,9 @@ bool m_detached; bool m_complete; bool m_abort; - ThreadId m_thread_id; ThreadCondition m_exit; }; -#ifdef PTHREADS_WIN -inline bool operator&&(bool lhs,const Task::ThreadId& rhs) { - return rhs.operator&&(lhs); -} -#endif /** Base class for wrapping a Posix thread. * @@ -310,7 +278,7 @@ * @param task a non-null Task pointer to bind to this thread. * @param name a unique string identifier for this thread. */ - BaseThread(Task *task, std::string const &name): m_task(task), m_thread_id(0), m_cancelled(false) { + BaseThread(Task *task, std::string const &name): m_task(task), m_started(false), m_cancelled(false) { assert(task); if (name.size()) { task->setName(name); @@ -409,6 +377,7 @@ // is called. _start takes care of deleting the reference. int result = pthread_create(&m_thread_id, 0, &Task::_start, new Ref<Task>(m_task)); ThreadException::checkThrow(result); + m_started = true; } /** Start the thread running and detach it. @@ -421,13 +390,13 @@ /** Returns true if this thread has been started successfully via start(). */ bool isStarted() const { - return m_thread_id != 0; + return m_started; } /** Test if this thread has been started but has not yet finished. */ bool isActive() const { - return m_task.valid() && m_thread_id && !m_task->isComplete(); + return m_task.valid() && isStarted() && !m_task->isComplete(); } /** Test if this thread has been detached. @@ -443,7 +412,8 @@ private: Ref<Task> m_task; - Task::ThreadId m_thread_id; + pthread_t m_thread_id; + bool m_started; bool m_cancelled; }; Modified: trunk/CSP/SimData/Include/SimData/ThreadUtil.h =================================================================== --- trunk/CSP/SimData/Include/SimData/ThreadUtil.h 2005-11-13 16:25:27 UTC (rev 1669) +++ trunk/CSP/SimData/Include/SimData/ThreadUtil.h 2005-11-13 18:01:44 UTC (rev 1670) @@ -24,6 +24,7 @@ * @brief Thread utility classes. */ +#ifndef SIMDATA_NOTHREADS #ifndef __SIMDATA_THREADUTIL_H__ #define __SIMDATA_THREADUTIL_H__ @@ -31,6 +32,7 @@ #include <SimData/Namespace.h> #include <SimData/Properties.h> #include <SimData/ExceptionBase.h> +#include <pthread.h> NAMESPACE_SIMDATA @@ -62,8 +64,15 @@ inline void unlock() { } }; +/** Convert an (opaque) pthread_t to an unsigned long. The value + * is intended for diagnostic logging only. Use pthread_equal to + * compare thread ids. + */ +unsigned long pthread_t_to_ulong(pthread_t const &id); + NAMESPACE_SIMDATA_END #endif // __SIMDATA_THREADUTIL_H__ +#endif // SIMDATA_NOTHREADS Modified: trunk/CSP/SimData/Source/LogStream.cpp =================================================================== --- trunk/CSP/SimData/Source/LogStream.cpp 2005-11-13 16:25:27 UTC (rev 1669) +++ trunk/CSP/SimData/Source/LogStream.cpp 2005-11-13 18:01:44 UTC (rev 1670) @@ -29,6 +29,7 @@ #include <SimData/FileUtility.h> #include <SimData/Trace.h> #include <SimData/Thread.h> +#include <SimData/ThreadUtil.h> #include <iostream> #include <iomanip> @@ -97,12 +98,13 @@ } #ifndef SIMDATA_NOTHREADS if (flags & LogStream::THREAD) { - // compress the 32-bit thread id into 6 characters. note that this is *not* the standard - // base64 encoding. the numbers are in front to make it more likely that the final output - // resembles a numeric value. - const char *encode64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; - uint32 id = static_cast<uint32>(thread::id()); - if (id != m_stream.initialThreadId()) { + pthread_t thread_id = thread::id(); + if (!pthread_equal(thread_id, m_stream.initialThread())) { + // compress the low 32 or 36 bits of thread id into 6 characters. note that this is *not* + // the standard base64 encoding. the numbers are in front to make it more likely that the + // final output resembles a numeric value. + const char *encode64 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; + unsigned long id = pthread_t_to_ulong(thread_id); char id_buffer[8]; id_buffer[6] = ' '; id_buffer[7] = 0; @@ -142,7 +144,7 @@ void LogStream::init() { #ifndef SIMDATA_NOTHREADS m_threadsafe = true; - m_initial_thread_id = static_cast<uint32>(thread::id()); + m_initial_thread = thread::id(); #endif } Modified: trunk/CSP/SimData/Source/ThreadUtil.cpp =================================================================== --- trunk/CSP/SimData/Source/ThreadUtil.cpp 2005-11-13 16:25:27 UTC (rev 1669) +++ trunk/CSP/SimData/Source/ThreadUtil.cpp 2005-11-13 18:01:44 UTC (rev 1670) @@ -27,8 +27,10 @@ #ifndef SIMDATA_NOTHREADS #include <SimData/ThreadUtil.h> +#include <SimData/HashUtility.h> #include <SimData/Log.h> +#include <pthread.h> #include <string> #include <sstream> @@ -68,6 +70,21 @@ addMessage(msg.str()); } +unsigned long pthread_t_to_ulong(pthread_t const &id) { +#ifdef PTW32_VERSION // pthreads-win32 + return static_cast<unsigned long>(id.p); // pointer to the thread object +#else + // if pthread_t is small, assume it is a simple numeric id. + if (sizeof(pthread_t) == sizeof(unsigned long)) return *reinterpret_cast<const unsigned long*>(&id); + if (sizeof(pthread_t) == sizeof(unsigned)) return *reinterpret_cast<const unsigned*>(&id); + // for other implementations that define pthread_t as a struct, return a 32-bit hash of + // the pthread_t structure. this is dangerous, since the structure may contain mutable + // data that is unrelated to the thread identity (e.g., a reference count). the posix + // standard doesn't provide any good options in this case. feel free to special case + // specific pthread libraries using more #ifdef branches above if necessary. + return hash_uint32(reinterpret_cast<const char*>(&id), sizeof(pthread_t)); +#endif +} NAMESPACE_SIMDATA_END |