File: | cppu/source/threadpool/thread.cxx |
Location: | line 136, column 38 |
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(); |
Called C++ object pointer is null | |
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: */ |