1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cppu.hxx"
31 #include <osl/diagnose.h>
32 #include <uno/threadpool.h>
34 #include <rtl/instance.hxx>
37 #include "jobqueue.hxx"
38 #include "threadpool.hxx"
44 void SAL_CALL
cppu_requestThreadWorker( void *pVoid
)
46 ::cppu_threadpool::ORequestThread
*pThread
= ( ::cppu_threadpool::ORequestThread
* ) pVoid
;
49 pThread
->onTerminated();
54 namespace cppu_threadpool
{
56 // ----------------------------------------------------------------------------------
57 ThreadAdmin::~ThreadAdmin()
59 #if OSL_DEBUG_LEVEL > 1
62 fprintf( stderr
, "%lu Threads left\n" , static_cast<unsigned long>(m_lst
.size()) );
67 void ThreadAdmin::add( ORequestThread
*p
)
69 MutexGuard
aGuard( m_mutex
);
73 void ThreadAdmin::remove( ORequestThread
* p
)
75 MutexGuard
aGuard( m_mutex
);
76 ::std::list
< ORequestThread
* >::iterator ii
= ::std::find( m_lst
.begin(), m_lst
.end(), p
);
77 OSL_ASSERT( ii
!= m_lst
.end() );
81 void ThreadAdmin::join()
83 ORequestThread
*pCurrent
;
88 MutexGuard
aGuard( m_mutex
);
91 pCurrent
= m_lst
.front();
92 pCurrent
->setDeleteSelf( sal_False
);
103 struct theThreadAdmin
: public rtl::StaticWithInit
< ThreadAdminHolder
, theThreadAdmin
>
105 ThreadAdminHolder
operator () () {
106 ThreadAdminHolder
aRet(new ThreadAdmin());
111 ThreadAdminHolder
& ThreadAdmin::getInstance()
113 return theThreadAdmin::get();
116 // ----------------------------------------------------------------------------------
117 ORequestThread::ORequestThread( JobQueue
*pQueue
,
118 const ByteSequence
&aThreadId
,
119 sal_Bool bAsynchron
)
121 , m_aThreadAdmin( ThreadAdmin::getInstance() )
123 , m_aThreadId( aThreadId
)
124 , m_bAsynchron( bAsynchron
)
125 , m_bDeleteSelf( sal_True
)
127 m_aThreadAdmin
->add( this );
131 ORequestThread::~ORequestThread()
135 osl_destroyThread(m_thread
);
140 void ORequestThread::setTask( JobQueue
*pQueue
,
141 const ByteSequence
&aThreadId
,
142 sal_Bool bAsynchron
)
145 m_aThreadId
= aThreadId
;
146 m_bAsynchron
= bAsynchron
;
149 sal_Bool
ORequestThread::create()
151 OSL_ASSERT(m_thread
== 0); // only one running thread per instance
153 m_thread
= osl_createSuspendedThread( cppu_requestThreadWorker
, (void*)this);
156 osl_resumeThread( m_thread
);
159 return m_thread
!= 0;
162 void ORequestThread::join()
164 osl_joinWithThread( m_thread
);
167 void ORequestThread::onTerminated()
169 m_aThreadAdmin
->remove( this );
176 void ORequestThread::run()
178 ThreadPoolHolder theThreadPool
= cppu_threadpool::ThreadPool::getInstance();
184 if ( !uno_bindIdToCurrentThread( m_aThreadId
.getHandle() ) )
190 while( ! m_pQueue
->isEmpty() )
192 // Note : Oneways should not get a disposable disposeid,
193 // It does not make sense to dispose a call in this state.
194 // That's way we put it an disposeid, that can't be used otherwise.
196 sal::static_int_cast
< sal_Int64
>(
197 reinterpret_cast< sal_IntPtr
>(this)),
200 if( m_pQueue
->isEmpty() )
202 theThreadPool
->revokeQueue( m_aThreadId
, m_bAsynchron
);
203 // Note : revokeQueue might have failed because m_pQueue.isEmpty()
204 // may be false (race).
213 uno_releaseIdFromCurrentThread();
216 theThreadPool
->waitInPool( this );