1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <osl/diagnose.h>
22 #include <uno/threadpool.h>
24 #include <com/sun/star/lang/DisposedException.hpp>
25 #include <com/sun/star/uno/Reference.hxx>
26 #include <com/sun/star/uno/XInterface.hpp>
27 #include <rtl/ustring.h>
28 #include <rtl/ustring.hxx>
31 #include "jobqueue.hxx"
32 #include "threadpool.hxx"
36 namespace cppu_threadpool
{
38 // ----------------------------------------------------------------------------------
39 ThreadAdmin::ThreadAdmin(): m_disposed(false) {}
41 ThreadAdmin::~ThreadAdmin()
43 #if OSL_DEBUG_LEVEL > 1
46 fprintf( stderr
, "%lu Threads left\n" , static_cast<unsigned long>(m_lst
.size()) );
51 void ThreadAdmin::add( rtl::Reference
< ORequestThread
> const & p
)
53 MutexGuard
aGuard( m_mutex
);
56 throw css::lang::DisposedException(
58 "cppu_threadpool::ORequestThread created after"
59 " cppu_threadpool::ThreadAdmin has been disposed"),
60 css::uno::Reference
< css::uno::XInterface
>());
65 void ThreadAdmin::remove_locked( rtl::Reference
< ORequestThread
> const & p
)
67 ::std::list
< rtl::Reference
< ORequestThread
> >::iterator ii
= ::std::find( m_lst
.begin(), m_lst
.end(), p
);
68 if( ii
!= m_lst
.end() )
74 void ThreadAdmin::remove( rtl::Reference
< ORequestThread
> const & p
)
76 MutexGuard
aGuard( m_mutex
);
80 void ThreadAdmin::join()
83 MutexGuard
aGuard( m_mutex
);
88 rtl::Reference
< ORequestThread
> pCurrent
;
90 MutexGuard
aGuard( m_mutex
);
95 pCurrent
= m_lst
.front();
102 // ----------------------------------------------------------------------------------
103 ORequestThread::ORequestThread( ThreadPoolHolder
const &aThreadPool
,
105 const ByteSequence
&aThreadId
,
106 sal_Bool bAsynchron
)
107 : m_aThreadPool( aThreadPool
)
109 , m_aThreadId( aThreadId
)
110 , m_bAsynchron( bAsynchron
)
113 ORequestThread::~ORequestThread() {}
115 void ORequestThread::setTask( JobQueue
*pQueue
,
116 const ByteSequence
&aThreadId
,
117 sal_Bool bAsynchron
)
120 m_aThreadId
= aThreadId
;
121 m_bAsynchron
= bAsynchron
;
124 void ORequestThread::launch()
126 // Assumption is that osl::Thread::create returns normally with a true
127 // return value iff it causes osl::Thread::run to start executing:
129 ThreadAdmin
& rThreadAdmin
= m_aThreadPool
->getThreadAdmin();
130 osl::ClearableMutexGuard
g(rThreadAdmin
.m_mutex
);
131 rThreadAdmin
.add( this );
134 throw std::runtime_error("osl::Thread::create failed");
137 rThreadAdmin
.remove_locked( this );
144 void ORequestThread::onTerminated()
146 m_aThreadPool
->getThreadAdmin().remove( this );
150 void ORequestThread::run()
158 if ( !uno_bindIdToCurrentThread( m_aThreadId
.getHandle() ) )
164 while( ! m_pQueue
->isEmpty() )
166 // Note : Oneways should not get a disposable disposeid,
167 // It does not make sense to dispose a call in this state.
168 // That's way we put it an disposeid, that can't be used otherwise.
170 sal::static_int_cast
< sal_Int64
>(
171 reinterpret_cast< sal_IntPtr
>(this)),
174 if( m_pQueue
->isEmpty() )
176 m_aThreadPool
->revokeQueue( m_aThreadId
, m_bAsynchron
);
177 // Note : revokeQueue might have failed because m_pQueue.isEmpty()
178 // may be false (race).
187 uno_releaseIdFromCurrentThread();
190 m_aThreadPool
->waitInPool( this );
195 // Work around the problem that onTerminated is not called if run
196 // throws an exception:
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */