Update ooo320-m1
[ooovba.git] / sw / source / core / docnode / threadmanager.cxx
blobf3bf3c04114f49156108fa8a8ba489bf62ed2c24
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: threadmanager.cxx,v $
10 * $Revision: 1.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "precompiled_sw.hxx"
31 #include <threadmanager.hxx>
32 #include <errhdl.hxx>
34 #include <algorithm>
36 using namespace ::com::sun::star;
38 /** class to manage threads
40 OD 2007-01-29 #i73788#
42 @author OD
44 const std::deque< ThreadManager::tThreadData >::size_type ThreadManager::mnStartedSize = 10;
46 ThreadManager::ThreadManager( uno::Reference< util::XJobManager >& rThreadJoiner )
47 : maMutex(),
48 mrThreadJoiner( rThreadJoiner ),
49 mpThreadListener(),
50 mnThreadIDCounter( 0 ),
51 maWaitingForStartThreads(),
52 maStartedThreads(),
53 maStartNewThreadTimer(),
54 mbStartingOfThreadsSuspended( false )
58 void ThreadManager::Init()
60 mpThreadListener.reset( new ThreadListener( *this ) );
62 maStartNewThreadTimer.SetTimeout( 2000 );
63 maStartNewThreadTimer.SetTimeoutHdl( LINK( this, ThreadManager, TryToStartNewThread ) );
66 ThreadManager::~ThreadManager()
68 maWaitingForStartThreads.clear();
69 maStartedThreads.clear();
72 boost::weak_ptr< IFinishedThreadListener > ThreadManager::GetThreadListenerWeakRef()
74 return mpThreadListener;
77 void ThreadManager::NotifyAboutFinishedThread( const oslInterlockedCount nThreadID )
79 RemoveThread( nThreadID, true );
82 oslInterlockedCount ThreadManager::AddThread(
83 const rtl::Reference< ObservableThread >& rThread )
86 osl::MutexGuard aGuard(maMutex);
88 // create new thread
89 tThreadData aThreadData;
90 oslInterlockedCount nNewThreadID( RetrieveNewThreadID() );
92 aThreadData.nThreadID = nNewThreadID;
94 aThreadData.pThread = rThread;
95 aThreadData.aJob = new CancellableJob( aThreadData.pThread );
97 aThreadData.pThread->setPriority( osl_Thread_PriorityBelowNormal );
98 mpThreadListener->ListenToThread( aThreadData.nThreadID,
99 *(aThreadData.pThread) );
102 // add thread to manager
103 if ( maStartedThreads.size() < mnStartedSize &&
104 !StartingOfThreadsSuspended() )
106 // Try to start thread
107 if ( !StartThread( aThreadData ) )
109 // No success on starting thread
110 // If no more started threads exist, but still threads are waiting,
111 // setup Timer to start thread from waiting ones
112 if ( maStartedThreads.empty() && !maWaitingForStartThreads.empty() )
114 maStartNewThreadTimer.Start();
118 else
120 // Thread will be started later
121 maWaitingForStartThreads.push_back( aThreadData );
124 return nNewThreadID;
127 void ThreadManager::RemoveThread( const oslInterlockedCount nThreadID,
128 const bool bThreadFinished )
130 // --> SAFE ----
131 osl::MutexGuard aGuard(maMutex);
133 std::deque< tThreadData >::iterator aIter =
134 std::find_if( maStartedThreads.begin(), maStartedThreads.end(),
135 ThreadPred( nThreadID ) );
137 if ( aIter != maStartedThreads.end() )
139 tThreadData aTmpThreadData( (*aIter) );
141 maStartedThreads.erase( aIter );
143 if ( bThreadFinished )
145 // release thread as job from thread joiner instance
146 ::com::sun::star::uno::Reference< ::com::sun::star::util::XJobManager > rThreadJoiner( mrThreadJoiner );
147 if ( rThreadJoiner.is() )
149 rThreadJoiner->releaseJob( aTmpThreadData.aJob );
151 else
153 ASSERT( false, "<ThreadManager::RemoveThread(..)> - ThreadJoiner already gone!" );
157 // Try to start thread from waiting ones
158 TryToStartNewThread( 0 );
160 else
162 aIter = std::find_if( maWaitingForStartThreads.begin(),
163 maWaitingForStartThreads.end(), ThreadPred( nThreadID ) );
165 if ( aIter != maWaitingForStartThreads.end() )
167 maWaitingForStartThreads.erase( aIter );
170 // <-- SAFE ----
173 bool ThreadManager::StartWaitingThread()
175 if ( !maWaitingForStartThreads.empty() )
177 tThreadData aThreadData( maWaitingForStartThreads.front() );
178 maWaitingForStartThreads.pop_front();
179 return StartThread( aThreadData );
181 else
183 return false;
187 bool ThreadManager::StartThread( const tThreadData& rThreadData )
189 bool bThreadStarted( false );
191 if ( rThreadData.pThread->create() )
193 // start of thread successful.
194 bThreadStarted = true;
196 maStartedThreads.push_back( rThreadData );
198 // register thread as job at thread joiner instance
199 ::com::sun::star::uno::Reference< ::com::sun::star::util::XJobManager > rThreadJoiner( mrThreadJoiner );
200 if ( rThreadJoiner.is() )
202 rThreadJoiner->registerJob( rThreadData.aJob );
204 else
206 ASSERT( false, "<ThreadManager::StartThread(..)> - ThreadJoiner already gone!" );
209 else
211 // thread couldn't be started.
212 maWaitingForStartThreads.push_front( rThreadData );
215 return bThreadStarted;
218 IMPL_LINK( ThreadManager, TryToStartNewThread, Timer *, EMPTYARG )
220 osl::MutexGuard aGuard(maMutex);
222 if ( !StartingOfThreadsSuspended() )
224 // Try to start thread from waiting ones
225 if ( !StartWaitingThread() )
227 // No success on starting thread
228 // If no more started threads exist, but still threads are waiting,
229 // setup Timer to start thread from waiting ones
230 if ( maStartedThreads.empty() && !maWaitingForStartThreads.empty() )
232 maStartNewThreadTimer.Start();
237 return sal_True;
240 void ThreadManager::ResumeStartingOfThreads()
242 osl::MutexGuard aGuard(maMutex);
244 mbStartingOfThreadsSuspended = false;
246 while ( maStartedThreads.size() < mnStartedSize &&
247 !maWaitingForStartThreads.empty() )
249 if ( !StartWaitingThread() )
251 // No success on starting thread
252 // If no more started threads exist, but still threads are waiting,
253 // setup Timer to start thread from waiting ones
254 if ( maStartedThreads.empty() && !maWaitingForStartThreads.empty() )
256 maStartNewThreadTimer.Start();
257 break;