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