1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: threadmanager.cxx,v $
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>
36 using namespace ::com::sun::star
;
38 /** class to manage threads
40 OD 2007-01-29 #i73788#
44 const std::deque
< ThreadManager::tThreadData
>::size_type
ThreadManager::mnStartedSize
= 10;
46 ThreadManager::ThreadManager( uno::Reference
< util::XJobManager
>& rThreadJoiner
)
48 mrThreadJoiner( rThreadJoiner
),
50 mnThreadIDCounter( 0 ),
51 maWaitingForStartThreads(),
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
);
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();
120 // Thread will be started later
121 maWaitingForStartThreads
.push_back( aThreadData
);
127 void ThreadManager::RemoveThread( const oslInterlockedCount nThreadID
,
128 const bool bThreadFinished
)
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
);
153 ASSERT( false, "<ThreadManager::RemoveThread(..)> - ThreadJoiner already gone!" );
157 // Try to start thread from waiting ones
158 TryToStartNewThread( 0 );
162 aIter
= std::find_if( maWaitingForStartThreads
.begin(),
163 maWaitingForStartThreads
.end(), ThreadPred( nThreadID
) );
165 if ( aIter
!= maWaitingForStartThreads
.end() )
167 maWaitingForStartThreads
.erase( aIter
);
173 bool ThreadManager::StartWaitingThread()
175 if ( !maWaitingForStartThreads
.empty() )
177 tThreadData
aThreadData( maWaitingForStartThreads
.front() );
178 maWaitingForStartThreads
.pop_front();
179 return StartThread( aThreadData
);
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
);
206 ASSERT( false, "<ThreadManager::StartThread(..)> - ThreadJoiner already gone!" );
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();
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();