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 #include <hash_map>
28 
29 #include <osl/conditn.h>
30 
31 #include <rtl/byteseq.hxx>
32 
33 #include <boost/shared_ptr.hpp>
34 
35 #include "jobqueue.hxx"
36 
37 
38 using namespace ::rtl;
39 namespace cppu_threadpool {
40 	class ORequestThread;
41 
42 	struct EqualThreadId
43 	{
44 		sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const
45 			{
46 				return a == b;
47 			}
48 	};
49 
50 	struct HashThreadId
51 	{
52 		sal_Int32 operator () ( const ::rtl::ByteSequence &a  )  const
53 			{
54 				if( a.getLength() >= 4 )
55 				{
56 					return *(sal_Int32 *)a.getConstArray();
57 				}
58 				return 0;
59 			}
60 	};
61 
62 	typedef	::std::hash_map
63 	<
64 	    ByteSequence, // ThreadID
65 		::std::pair < JobQueue * , JobQueue * >,
66 		HashThreadId,
67 		EqualThreadId
68 	> ThreadIdHashMap;
69 
70 	typedef	::std::list	< sal_Int64 > DisposedCallerList;
71 
72 
73 	struct WaitingThread
74 	{
75 		oslCondition condition;
76 		ORequestThread *thread;
77 	};
78 
79 	typedef	::std::list	< struct ::cppu_threadpool::WaitingThread * > WaitingThreadList;
80 
81 	class DisposedCallerAdmin;
82 	typedef boost::shared_ptr<DisposedCallerAdmin> DisposedCallerAdminHolder;
83 
84 	class DisposedCallerAdmin
85 	{
86 	public:
87 		~DisposedCallerAdmin();
88 
89 		static DisposedCallerAdminHolder getInstance();
90 
91 		void dispose( sal_Int64 nDisposeId );
92 		void stopDisposing( sal_Int64 nDisposeId );
93 		sal_Bool isDisposed( sal_Int64 nDisposeId );
94 
95 	private:
96 		::osl::Mutex m_mutex;
97 		DisposedCallerList m_lst;
98 	};
99 
100 	class ThreadPool;
101 	typedef boost::shared_ptr<ThreadPool> ThreadPoolHolder;
102 
103 	class ThreadPool
104 	{
105 	public:
106 		ThreadPool();
107 		~ThreadPool();
108 		static ThreadPoolHolder getInstance();
109 
110 		void dispose( sal_Int64 nDisposeId );
111 		void stopDisposing( sal_Int64 nDisposeId );
112 
113 		void addJob( const ByteSequence &aThreadId,
114 					 sal_Bool bAsynchron,
115 					 void *pThreadSpecificData,
116 					 RequestFun * doRequest );
117 
118 		void prepare( const ByteSequence &aThreadId );
119 		void * enter( const ByteSequence &aThreadId, sal_Int64 nDisposeId );
120 
121 		/********
122 		 * @return true, if queue could be succesfully revoked.
123 		 ********/
124 		sal_Bool revokeQueue( const ByteSequence & aThreadId , sal_Bool bAsynchron );
125 
126 		void waitInPool( ORequestThread *pThread );
127 	private:
128 		void createThread( JobQueue *pQueue, const ByteSequence &aThreadId,	sal_Bool bAsynchron);
129 
130 
131 		ThreadIdHashMap m_mapQueue;
132 		::osl::Mutex m_mutex;
133 
134 		::osl::Mutex m_mutexWaitingThreadList;
135 		WaitingThreadList m_lstThreads;
136 
137 		DisposedCallerAdminHolder m_DisposedCallerAdmin;
138 	};
139 
140 } // end namespace cppu_threadpool
141