File: | cppu/source/threadpool/thread.cxx |
Location: | line 183, column 25 |
Description: | Called C++ object pointer is null |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
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/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
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 . | |||
18 | */ | |||
19 | ||||
20 | #include <stdio.h> | |||
21 | #include <osl/diagnose.h> | |||
22 | #include <uno/threadpool.h> | |||
23 | ||||
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> | |||
29 | ||||
30 | #include "thread.hxx" | |||
31 | #include "jobqueue.hxx" | |||
32 | #include "threadpool.hxx" | |||
33 | ||||
34 | namespace { | |||
35 | ||||
36 | namespace css = com::sun::star; | |||
37 | ||||
38 | } | |||
39 | ||||
40 | using namespace osl; | |||
41 | ||||
42 | namespace cppu_threadpool { | |||
43 | ||||
44 | // ---------------------------------------------------------------------------------- | |||
45 | ThreadAdmin::ThreadAdmin(): m_disposed(false) {} | |||
46 | ||||
47 | ThreadAdmin::~ThreadAdmin() | |||
48 | { | |||
49 | #if OSL_DEBUG_LEVEL1 > 1 | |||
50 | if( m_lst.size() ) | |||
51 | { | |||
52 | fprintf( stderrstderr, "%lu Threads left\n" , static_cast<unsigned long>(m_lst.size()) ); | |||
53 | } | |||
54 | #endif | |||
55 | } | |||
56 | ||||
57 | void ThreadAdmin::add( rtl::Reference< ORequestThread > const & p ) | |||
58 | { | |||
59 | MutexGuard aGuard( m_mutex ); | |||
60 | if( m_disposed ) | |||
61 | { | |||
62 | throw css::lang::DisposedException( | |||
63 | rtl::OUString( | |||
64 | RTL_CONSTASCII_USTRINGPARAM((&("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed" )[0]), ((sal_Int32)((sizeof ("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed") / sizeof ( ("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed" )[0]))-1)), (((rtl_TextEncoding) 11)) | |||
65 | "cppu_threadpool::ORequestThread created after"(&("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed" )[0]), ((sal_Int32)((sizeof ("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed") / sizeof ( ("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed" )[0]))-1)), (((rtl_TextEncoding) 11)) | |||
66 | " cppu_threadpool::ThreadAdmin has been disposed")(&("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed" )[0]), ((sal_Int32)((sizeof ("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed") / sizeof ( ("cppu_threadpool::ORequestThread created after" " cppu_threadpool::ThreadAdmin has been disposed" )[0]))-1)), (((rtl_TextEncoding) 11))), | |||
67 | css::uno::Reference< css::uno::XInterface >()); | |||
68 | } | |||
69 | m_lst.push_back( p ); | |||
70 | } | |||
71 | ||||
72 | void ThreadAdmin::remove_locked( rtl::Reference< ORequestThread > const & p ) | |||
73 | { | |||
74 | ::std::list< rtl::Reference< ORequestThread > >::iterator ii = ::std::find( m_lst.begin(), m_lst.end(), p ); | |||
75 | if( ii != m_lst.end() ) | |||
76 | { | |||
77 | m_lst.erase( ii ); | |||
78 | } | |||
79 | } | |||
80 | ||||
81 | void ThreadAdmin::remove( rtl::Reference< ORequestThread > const & p ) | |||
82 | { | |||
83 | MutexGuard aGuard( m_mutex ); | |||
84 | remove_locked( p ); | |||
85 | } | |||
86 | ||||
87 | void ThreadAdmin::join() | |||
88 | { | |||
89 | { | |||
90 | MutexGuard aGuard( m_mutex ); | |||
91 | m_disposed = true; | |||
92 | } | |||
93 | for (;;) | |||
94 | { | |||
95 | rtl::Reference< ORequestThread > pCurrent; | |||
96 | { | |||
97 | MutexGuard aGuard( m_mutex ); | |||
98 | if( m_lst.empty() ) | |||
99 | { | |||
100 | break; | |||
101 | } | |||
102 | pCurrent = m_lst.front(); | |||
103 | m_lst.pop_front(); | |||
104 | } | |||
105 | pCurrent->join(); | |||
106 | } | |||
107 | } | |||
108 | ||||
109 | // ---------------------------------------------------------------------------------- | |||
110 | ORequestThread::ORequestThread( ThreadPoolHolder const &aThreadPool, | |||
111 | JobQueue *pQueue, | |||
112 | const ByteSequence &aThreadId, | |||
113 | sal_Bool bAsynchron ) | |||
114 | : m_aThreadPool( aThreadPool ) | |||
115 | , m_pQueue( pQueue ) | |||
116 | , m_aThreadId( aThreadId ) | |||
117 | , m_bAsynchron( bAsynchron ) | |||
118 | {} | |||
119 | ||||
120 | ORequestThread::~ORequestThread() {} | |||
121 | ||||
122 | void ORequestThread::setTask( JobQueue *pQueue, | |||
123 | const ByteSequence &aThreadId, | |||
124 | sal_Bool bAsynchron ) | |||
125 | { | |||
126 | m_pQueue = pQueue; | |||
127 | m_aThreadId = aThreadId; | |||
128 | m_bAsynchron = bAsynchron; | |||
129 | } | |||
130 | ||||
131 | void ORequestThread::launch() | |||
132 | { | |||
133 | // Assumption is that osl::Thread::create returns normally with a true | |||
134 | // return value iff it causes osl::Thread::run to start executing: | |||
135 | acquire(); | |||
136 | ThreadAdmin & rThreadAdmin = m_aThreadPool->getThreadAdmin(); | |||
137 | osl::ClearableMutexGuard g(rThreadAdmin.m_mutex); | |||
138 | rThreadAdmin.add( this ); | |||
139 | try { | |||
140 | if (!create()) { | |||
141 | throw std::runtime_error("osl::Thread::create failed"); | |||
142 | } | |||
143 | } catch (...) { | |||
144 | rThreadAdmin.remove_locked( this ); | |||
145 | g.clear(); | |||
146 | release(); | |||
147 | throw; | |||
148 | } | |||
149 | } | |||
150 | ||||
151 | void ORequestThread::onTerminated() | |||
152 | { | |||
153 | m_aThreadPool->getThreadAdmin().remove( this ); | |||
154 | release(); | |||
155 | } | |||
156 | ||||
157 | void ORequestThread::run() | |||
158 | { | |||
159 | try | |||
160 | { | |||
161 | while ( m_pQueue ) | |||
| ||||
162 | { | |||
163 | if( ! m_bAsynchron ) | |||
164 | { | |||
165 | if ( !uno_bindIdToCurrentThread( m_aThreadId.getHandle() ) ) | |||
166 | { | |||
167 | OSL_ASSERT( false )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/cppu/source/threadpool/thread.cxx" ":" "167" ": "), "OSL_ASSERT: %s", "false"); } } while (false ); | |||
168 | } | |||
169 | } | |||
170 | ||||
171 | while( ! m_pQueue->isEmpty() ) | |||
172 | { | |||
173 | // Note : Oneways should not get a disposable disposeid, | |||
174 | // It does not make sense to dispose a call in this state. | |||
175 | // That's way we put it an disposeid, that can't be used otherwise. | |||
176 | m_pQueue->enter( | |||
177 | sal::static_int_cast< sal_Int64 >( | |||
178 | reinterpret_cast< sal_IntPtr >(this)), | |||
179 | sal_True((sal_Bool)1) ); | |||
180 | ||||
181 | if( m_pQueue->isEmpty() ) | |||
182 | { | |||
183 | m_aThreadPool->revokeQueue( m_aThreadId , m_bAsynchron ); | |||
| ||||
184 | // Note : revokeQueue might have failed because m_pQueue.isEmpty() | |||
185 | // may be false (race). | |||
186 | } | |||
187 | } | |||
188 | ||||
189 | delete m_pQueue; | |||
190 | m_pQueue = 0; | |||
191 | ||||
192 | if( ! m_bAsynchron ) | |||
193 | { | |||
194 | uno_releaseIdFromCurrentThread(); | |||
195 | } | |||
196 | ||||
197 | m_aThreadPool->waitInPool( this ); | |||
198 | } | |||
199 | } | |||
200 | catch (...) | |||
201 | { | |||
202 | // Work around the problem that onTerminated is not called if run | |||
203 | // throws an exception: | |||
204 | onTerminated(); | |||
205 | throw; | |||
206 | } | |||
207 | } | |||
208 | } | |||
209 | ||||
210 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |