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 RTL_CONSTASCII_USTRINGPARAM(
59 "cppu_threadpool::ORequestThread created after"
60 " cppu_threadpool::ThreadAdmin has been disposed")),
61 css::uno::Reference
< css::uno::XInterface
>());
66 void ThreadAdmin::remove_locked( rtl::Reference
< ORequestThread
> const & p
)
68 ::std::list
< rtl::Reference
< ORequestThread
> >::iterator ii
= ::std::find( m_lst
.begin(), m_lst
.end(), p
);
69 if( ii
!= m_lst
.end() )
75 void ThreadAdmin::remove( rtl::Reference
< ORequestThread
> const & p
)
77 MutexGuard
aGuard( m_mutex
);
81 void ThreadAdmin::join()
84 MutexGuard
aGuard( m_mutex
);
89 rtl::Reference
< ORequestThread
> pCurrent
;
91 MutexGuard
aGuard( m_mutex
);
96 pCurrent
= m_lst
.front();
103 // ----------------------------------------------------------------------------------
104 ORequestThread::ORequestThread( ThreadPoolHolder
const &aThreadPool
,
106 const ByteSequence
&aThreadId
,
107 sal_Bool bAsynchron
)
108 : m_aThreadPool( aThreadPool
)
110 , m_aThreadId( aThreadId
)
111 , m_bAsynchron( bAsynchron
)
114 ORequestThread::~ORequestThread() {}
116 void ORequestThread::setTask( JobQueue
*pQueue
,
117 const ByteSequence
&aThreadId
,
118 sal_Bool bAsynchron
)
121 m_aThreadId
= aThreadId
;
122 m_bAsynchron
= bAsynchron
;
125 void ORequestThread::launch()
127 // Assumption is that osl::Thread::create returns normally with a true
128 // return value iff it causes osl::Thread::run to start executing:
130 ThreadAdmin
& rThreadAdmin
= m_aThreadPool
->getThreadAdmin();
131 osl::ClearableMutexGuard
g(rThreadAdmin
.m_mutex
);
132 rThreadAdmin
.add( this );
135 throw std::runtime_error("osl::Thread::create failed");
138 rThreadAdmin
.remove_locked( this );
145 void ORequestThread::onTerminated()
147 m_aThreadPool
->getThreadAdmin().remove( this );
151 void ORequestThread::run()
159 if ( !uno_bindIdToCurrentThread( m_aThreadId
.getHandle() ) )
165 while( ! m_pQueue
->isEmpty() )
167 // Note : Oneways should not get a disposable disposeid,
168 // It does not make sense to dispose a call in this state.
169 // That's way we put it an disposeid, that can't be used otherwise.
171 sal::static_int_cast
< sal_Int64
>(
172 reinterpret_cast< sal_IntPtr
>(this)),
175 if( m_pQueue
->isEmpty() )
177 m_aThreadPool
->revokeQueue( m_aThreadId
, m_bAsynchron
);
178 // Note : revokeQueue might have failed because m_pQueue.isEmpty()
179 // may be false (race).
188 uno_releaseIdFromCurrentThread();
191 m_aThreadPool
->waitInPool( this );
196 // Work around the problem that onTerminated is not called if run
197 // throws an exception:
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */