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 .
20 #include <sal/config.h>
24 #include <osl/diagnose.h>
25 #include <uno/threadpool.h>
26 #include <sal/log.hxx>
30 #include "jobqueue.hxx"
31 #include "threadpool.hxx"
36 namespace cppu_threadpool
{
39 ThreadAdmin::ThreadAdmin(): m_disposed(false) {}
41 ThreadAdmin::~ThreadAdmin()
43 SAL_WARN_IF(m_deque
.size(), "cppu.threadpool", m_deque
.size() << "Threads left");
46 bool ThreadAdmin::add_locked( rtl::Reference
< ORequestThread
> const & p
)
52 m_deque
.push_back( p
);
56 void ThreadAdmin::remove_locked( rtl::Reference
< ORequestThread
> const & p
)
58 m_deque
.erase(std::find( m_deque
.begin(), m_deque
.end(), p
), m_deque
.end());
61 void ThreadAdmin::remove( rtl::Reference
< ORequestThread
> const & p
)
63 std::scoped_lock
aGuard( m_mutex
);
67 void ThreadAdmin::join()
70 std::scoped_lock
aGuard( m_mutex
);
75 rtl::Reference
< ORequestThread
> pCurrent
;
77 std::scoped_lock
aGuard( m_mutex
);
82 pCurrent
= m_deque
.front();
85 if (pCurrent
->getIdentifier()
86 != osl::Thread::getCurrentIdentifier())
94 ORequestThread::ORequestThread( ThreadPoolHolder aThreadPool
,
96 ByteSequence aThreadId
,
98 : m_aThreadPool(std::move( aThreadPool
))
100 , m_aThreadId(std::move( aThreadId
))
101 , m_bAsynchron( bAsynchron
)
104 ORequestThread::~ORequestThread() {}
106 void ORequestThread::setTask( JobQueue
*pQueue
,
107 const ByteSequence
&aThreadId
,
111 m_aThreadId
= aThreadId
;
112 m_bAsynchron
= bAsynchron
;
115 bool ORequestThread::launch()
117 // Assumption is that osl::Thread::create returns normally with a true
118 // return value iff it causes osl::Thread::run to start executing:
120 ThreadAdmin
& rThreadAdmin
= m_aThreadPool
->getThreadAdmin();
121 std::unique_lock
g(rThreadAdmin
.m_mutex
);
122 if (!rThreadAdmin
.add_locked( this )) {
130 rThreadAdmin
.remove_locked( this );
138 void ORequestThread::onTerminated()
140 m_aThreadPool
->getThreadAdmin().remove( this );
144 void ORequestThread::run()
146 osl_setThreadName("cppu_threadpool::ORequestThread");
154 if ( !uno_bindIdToCurrentThread( m_aThreadId
.getHandle() ) )
160 while( ! m_pQueue
->isEmpty() )
162 // Note : Oneways should not get a disposable disposeid,
163 // It does not make sense to dispose a call in this state.
164 // That's way we put it a disposeid, that can't be used otherwise.
169 if( m_pQueue
->isEmpty() )
171 m_aThreadPool
->revokeQueue( m_aThreadId
, m_bAsynchron
);
172 // Note : revokeQueue might have failed because m_pQueue.isEmpty()
173 // may be false (race).
182 uno_releaseIdFromCurrentThread();
185 m_aThreadPool
->waitInPool( this );
190 // Work around the problem that onTerminated is not called if run
191 // throws an exception:
198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */