xref: /aoo41x/main/sw/source/core/inc/threadmanager.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef _THREADMANAGER_HXX
28 #define _THREADMANAGER_HXX
29 
30 #include <ithreadlistenerowner.hxx>
31 #include <vcl/timer.hxx>
32 #include <osl/mutex.hxx>
33 #include <osl/interlck.h>
34 #include <rtl/ref.hxx>
35 
36 #include <deque>
37 #include <list>
38 #include <cppuhelper/weak.hxx>
39 #include "com/sun/star/util/XJobManager.hpp"
40 #include <observablethread.hxx>
41 #include <cancellablejob.hxx>
42 #include <threadlistener.hxx>
43 
44 #include <boost/shared_ptr.hpp>
45 #include <boost/weak_ptr.hpp>
46 
47 /** class to manage threads
48 
49     OD 2007-01-29 #i73788#
50     An instance of this class takes care of the starting of threads.
51     It assures that not more than <mnStartedSize> threads
52     are started.
53 
54     @author OD
55 */
56 class ThreadManager : public IThreadListenerOwner
57 {
58     public:
59 
60         explicit ThreadManager( ::com::sun::star::uno::Reference< ::com::sun::star::util::XJobManager >& rThreadJoiner );
61         ~ThreadManager();
62 
63         // --> IThreadListenerOwner
64         virtual boost::weak_ptr< IFinishedThreadListener > GetThreadListenerWeakRef();
65         virtual void NotifyAboutFinishedThread( const oslInterlockedCount nThreadID );
66         // <--
67 
68         /** initialization
69 
70             IMPORTANT NOTE: Needs to be called directly after construction
71 
72             @author OD
73         */
74         void Init();
75 
76         /** add thread to the thread manager and taking ownership for the thread
77 
78             @author OD
79 
80             @return unique ID for added thread
81         */
82         oslInterlockedCount AddThread(
83                             const ::rtl::Reference< ObservableThread >& rThread );
84 
85         void RemoveThread( const oslInterlockedCount nThreadID,
86                            const bool bThreadFinished = false );
87 
88         DECL_LINK( TryToStartNewThread, Timer* );
89 
90         /** suspend the starting of threads
91 
92             Suspending the starting of further threads is sensible during the
93             destruction of a Writer document.
94 
95             @author OD
96         */
97         inline void SuspendStartingOfThreads()
98         {
99             osl::MutexGuard aGuard(maMutex);
100 
101             mbStartingOfThreadsSuspended = true;
102         }
103 
104         /** continues the starting of threads after it has been suspended
105 
106             @author OD
107         */
108         void ResumeStartingOfThreads();
109 
110         inline bool StartingOfThreadsSuspended()
111         {
112             osl::MutexGuard aGuard(maMutex);
113 
114             return mbStartingOfThreadsSuspended;
115         }
116 
117         struct tThreadData
118         {
119             oslInterlockedCount nThreadID;
120             ::rtl::Reference< ObservableThread > pThread;
121             com::sun::star::uno::Reference< com::sun::star::util::XCancellable > aJob;
122 
123             tThreadData()
124                 : nThreadID( 0 ),
125                   pThread( 0 ),
126                   aJob()
127             {}
128         };
129 
130     private:
131 
132         static const std::deque< tThreadData >::size_type mnStartedSize;
133 
134         osl::Mutex maMutex;
135 
136         ::com::sun::star::uno::WeakReference< ::com::sun::star::util::XJobManager > mrThreadJoiner;
137 
138         boost::shared_ptr< ThreadListener > mpThreadListener;
139 
140         oslInterlockedCount mnThreadIDCounter;
141 
142         std::deque< tThreadData > maWaitingForStartThreads;
143         std::deque< tThreadData > maStartedThreads;
144 
145         Timer maStartNewThreadTimer;
146 
147         bool mbStartingOfThreadsSuspended;
148 
149         struct ThreadPred
150         {
151             oslInterlockedCount mnThreadID;
152             explicit ThreadPred( oslInterlockedCount nThreadID )
153                 : mnThreadID( nThreadID )
154             {}
155 
156             bool operator() ( const tThreadData& rThreadData ) const
157             {
158                 return rThreadData.nThreadID == mnThreadID;
159             }
160         };
161 
162 
163         inline oslInterlockedCount RetrieveNewThreadID()
164         {
165             return osl_incrementInterlockedCount( &mnThreadIDCounter );
166         }
167 
168         bool StartWaitingThread();
169 
170         bool StartThread( const tThreadData& aThreadData );
171 };
172 #endif
173