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>
29 #include "jobqueue.hxx"
30 #include "threadpool.hxx"
35 namespace cppu_threadpool
{
38 ThreadAdmin::ThreadAdmin(): m_disposed(false) {}
40 ThreadAdmin::~ThreadAdmin()
42 SAL_WARN_IF(m_deque
.size(), "cppu.threadpool", m_deque
.size() << "Threads left");
45 bool ThreadAdmin::add_locked( rtl::Reference
< ORequestThread
> const & p
)
51 m_deque
.push_back( p
);
55 void ThreadAdmin::remove_locked( rtl::Reference
< ORequestThread
> const & p
)
57 m_deque
.erase(std::find( m_deque
.begin(), m_deque
.end(), p
), m_deque
.end());
60 void ThreadAdmin::remove( rtl::Reference
< ORequestThread
> const & p
)
62 std::scoped_lock
aGuard( m_mutex
);
66 void ThreadAdmin::join()
69 std::scoped_lock
aGuard( m_mutex
);
74 rtl::Reference
< ORequestThread
> pCurrent
;
76 std::scoped_lock
aGuard( m_mutex
);
81 pCurrent
= m_deque
.front();
84 if (pCurrent
->getIdentifier()
85 != osl::Thread::getCurrentIdentifier())
93 ORequestThread::ORequestThread( ThreadPoolHolder
const &aThreadPool
,
95 const ByteSequence
&aThreadId
,
97 : m_aThreadPool( aThreadPool
)
99 , m_aThreadId( aThreadId
)
100 , m_bAsynchron( bAsynchron
)
103 ORequestThread::~ORequestThread() {}
105 void ORequestThread::setTask( JobQueue
*pQueue
,
106 const ByteSequence
&aThreadId
,
110 m_aThreadId
= aThreadId
;
111 m_bAsynchron
= bAsynchron
;
114 bool ORequestThread::launch()
116 // Assumption is that osl::Thread::create returns normally with a true
117 // return value iff it causes osl::Thread::run to start executing:
119 ThreadAdmin
& rThreadAdmin
= m_aThreadPool
->getThreadAdmin();
120 std::unique_lock
g(rThreadAdmin
.m_mutex
);
121 if (!rThreadAdmin
.add_locked( this )) {
129 rThreadAdmin
.remove_locked( this );
137 void ORequestThread::onTerminated()
139 m_aThreadPool
->getThreadAdmin().remove( this );
143 void ORequestThread::run()
145 osl_setThreadName("cppu_threadpool::ORequestThread");
153 if ( !uno_bindIdToCurrentThread( m_aThreadId
.getHandle() ) )
159 while( ! m_pQueue
->isEmpty() )
161 // Note : Oneways should not get a disposable disposeid,
162 // It does not make sense to dispose a call in this state.
163 // That's way we put it a disposeid, that can't be used otherwise.
168 if( m_pQueue
->isEmpty() )
170 m_aThreadPool
->revokeQueue( m_aThreadId
, m_bAsynchron
);
171 // Note : revokeQueue might have failed because m_pQueue.isEmpty()
172 // may be false (race).
181 uno_releaseIdFromCurrentThread();
184 m_aThreadPool
->waitInPool( this );
189 // Work around the problem that onTerminated is not called if run
190 // throws an exception:
197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */