1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #ifndef _THREADMANAGER_HXX 24 #define _THREADMANAGER_HXX 25 26 #include <ithreadlistenerowner.hxx> 27 #include <vcl/timer.hxx> 28 #include <osl/mutex.hxx> 29 #include <osl/interlck.h> 30 #include <rtl/ref.hxx> 31 32 #include <deque> 33 #include <list> 34 #include <cppuhelper/weak.hxx> 35 #include "com/sun/star/util/XJobManager.hpp" 36 #include <observablethread.hxx> 37 #include <cancellablejob.hxx> 38 #include <threadlistener.hxx> 39 40 #include <boost/shared_ptr.hpp> 41 #include <boost/weak_ptr.hpp> 42 43 /** class to manage threads 44 45 OD 2007-01-29 #i73788# 46 An instance of this class takes care of the starting of threads. 47 It assures that not more than <mnStartedSize> threads 48 are started. 49 50 @author OD 51 */ 52 class ThreadManager : public IThreadListenerOwner 53 { 54 public: 55 56 explicit ThreadManager( ::com::sun::star::uno::Reference< ::com::sun::star::util::XJobManager >& rThreadJoiner ); 57 ~ThreadManager(); 58 59 // --> IThreadListenerOwner 60 virtual boost::weak_ptr< IFinishedThreadListener > GetThreadListenerWeakRef(); 61 virtual void NotifyAboutFinishedThread( const oslInterlockedCount nThreadID ); 62 // <-- 63 64 /** initialization 65 66 IMPORTANT NOTE: Needs to be called directly after construction 67 68 @author OD 69 */ 70 void Init(); 71 72 /** add thread to the thread manager and taking ownership for the thread 73 74 @author OD 75 76 @return unique ID for added thread 77 */ 78 oslInterlockedCount AddThread( 79 const ::rtl::Reference< ObservableThread >& rThread ); 80 81 void RemoveThread( const oslInterlockedCount nThreadID, 82 const bool bThreadFinished = false ); 83 84 DECL_LINK( TryToStartNewThread, Timer* ); 85 86 /** suspend the starting of threads 87 88 Suspending the starting of further threads is sensible during the 89 destruction of a Writer document. 90 91 @author OD 92 */ SuspendStartingOfThreads()93 inline void SuspendStartingOfThreads() 94 { 95 osl::MutexGuard aGuard(maMutex); 96 97 mbStartingOfThreadsSuspended = true; 98 } 99 100 /** continues the starting of threads after it has been suspended 101 102 @author OD 103 */ 104 void ResumeStartingOfThreads(); 105 StartingOfThreadsSuspended()106 inline bool StartingOfThreadsSuspended() 107 { 108 osl::MutexGuard aGuard(maMutex); 109 110 return mbStartingOfThreadsSuspended; 111 } 112 113 struct tThreadData 114 { 115 oslInterlockedCount nThreadID; 116 ::rtl::Reference< ObservableThread > pThread; 117 com::sun::star::uno::Reference< com::sun::star::util::XCancellable > aJob; 118 tThreadDataThreadManager::tThreadData119 tThreadData() 120 : nThreadID( 0 ), 121 pThread( 0 ), 122 aJob() 123 {} 124 }; 125 126 private: 127 128 static const std::deque< tThreadData >::size_type mnStartedSize; 129 130 osl::Mutex maMutex; 131 132 ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XJobManager > mrThreadJoiner; 133 134 boost::shared_ptr< ThreadListener > mpThreadListener; 135 136 oslInterlockedCount mnThreadIDCounter; 137 138 std::deque< tThreadData > maWaitingForStartThreads; 139 std::deque< tThreadData > maStartedThreads; 140 141 Timer maStartNewThreadTimer; 142 143 bool mbStartingOfThreadsSuspended; 144 145 struct ThreadPred 146 { 147 oslInterlockedCount mnThreadID; ThreadPredThreadManager::ThreadPred148 explicit ThreadPred( oslInterlockedCount nThreadID ) 149 : mnThreadID( nThreadID ) 150 {} 151 operator ()ThreadManager::ThreadPred152 bool operator() ( const tThreadData& rThreadData ) const 153 { 154 return rThreadData.nThreadID == mnThreadID; 155 } 156 }; 157 158 RetrieveNewThreadID()159 inline oslInterlockedCount RetrieveNewThreadID() 160 { 161 return osl_incrementInterlockedCount( &mnThreadIDCounter ); 162 } 163 164 bool StartWaitingThread(); 165 166 bool StartThread( const tThreadData& aThreadData ); 167 }; 168 #endif 169