00001 /******************************************************************************* 00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2005 Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * - Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * - Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its 00016 * contributors may be used to endorse or promote products derived from this 00017 * software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 *******************************************************************************/ 00031 00032 00038 #ifndef BLOCXX_THREAD_HPP_INCLUDE_GUARD_ 00039 #define BLOCXX_THREAD_HPP_INCLUDE_GUARD_ 00040 #include "blocxx/BLOCXX_config.h" 00041 #include "blocxx/Exception.hpp" 00042 #include "blocxx/String.hpp" 00043 #include "blocxx/ThreadImpl.hpp" 00044 #include "blocxx/IntrusiveReference.hpp" 00045 #include "blocxx/IntrusiveCountableBase.hpp" 00046 #include "blocxx/Assertion.hpp" 00047 #include "blocxx/Condition.hpp" 00048 #include "blocxx/NonRecursiveMutex.hpp" 00049 #include "blocxx/ThreadDoneCallback.hpp" 00050 #include "blocxx/ThreadCancelledException.hpp" 00051 00052 namespace BLOCXX_NAMESPACE 00053 { 00054 00056 BLOCXX_DECLARE_APIEXCEPTION(CancellationDenied, BLOCXX_COMMON_API); 00057 BLOCXX_DECLARE_APIEXCEPTION(Thread, BLOCXX_COMMON_API); 00059 class BLOCXX_COMMON_API Thread : public IntrusiveCountableBase 00060 { 00061 public: 00065 Thread(); 00071 virtual ~Thread(); 00076 virtual void start(const ThreadDoneCallbackRef& cb = ThreadDoneCallbackRef(0)); 00095 void cooperativeCancel(); 00131 bool definitiveCancel(UInt32 waitForCooperativeSecs = 60); 00151 void cancel(); 00180 static void testCancel(); 00181 private: 00199 virtual void doCooperativeCancel(); 00207 virtual void doDefinitiveCancel(); 00208 public: 00212 bool isRunning() 00213 { 00214 return m_isRunning == true; 00215 } 00227 Int32 join(); 00237 Thread_t getId() 00238 { 00239 return m_id; 00240 } 00246 static void sleep(UInt32 milliSeconds) 00247 { 00248 ThreadImpl::sleep(milliSeconds); 00249 } 00254 static void yield() 00255 { 00256 ThreadImpl::yield(); 00257 } 00258 private: 00262 virtual Int32 run() = 0; 00263 // thread state 00264 Thread_t m_id; 00265 bool m_isRunning; 00266 bool m_isStarting; 00267 bool m_joined; 00268 // used to implement cancellation. 00269 friend void ThreadImpl::testCancel(); 00270 NonRecursiveMutex m_cancelLock; 00271 Condition m_cancelCond; 00272 bool m_cancelRequested; 00273 bool m_cancelled; 00274 00275 static Int32 threadRunner(void* paramPtr); 00276 void doneRunning(const ThreadDoneCallbackRef& cb); 00277 00278 // non-copyable 00279 Thread(const Thread&); 00280 Thread& operator=(const Thread&); 00281 00282 }; 00283 BLOCXX_EXPORT_TEMPLATE(BLOCXX_COMMON_API, IntrusiveReference, Thread); 00284 00285 } // end namespace BLOCXX_NAMESPACE 00286 00287 #endif 00288