1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "asyncrequests.hxx" 25 #include <vcl/svapp.hxx> 26 #include <vos/mutex.hxx> 27 28 //----------------------------------------------------------------------------- 29 // namespace 30 //----------------------------------------------------------------------------- 31 32 namespace fpicker{ 33 namespace win32{ 34 namespace vista{ 35 36 namespace css = ::com::sun::star; 37 38 //----------------------------------------------------------------------------- 39 void lcl_sleep(::osl::Condition& aCondition , 40 ::sal_Int32 nMilliSeconds) 41 { 42 sal_uLong nAcquireCount = Application::ReleaseSolarMutex(); 43 44 if (nMilliSeconds < 1) 45 aCondition.wait(0); 46 else 47 { 48 TimeValue aTime; 49 aTime.Seconds = (nMilliSeconds / 1000); 50 aTime.Nanosec = (nMilliSeconds % 1000) * 1000000; 51 aCondition.wait(&aTime); 52 } 53 54 Application::AcquireSolarMutex( nAcquireCount ); 55 } 56 57 //----------------------------------------------------------------------------- 58 void Request::wait(::sal_Int32 nMilliSeconds) 59 { 60 lcl_sleep(m_aJoiner, nMilliSeconds); 61 } 62 63 void Request::waitProcessMessages() 64 { 65 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 66 while (!m_aJoiner.check()) 67 Application::Yield(); 68 } 69 70 //----------------------------------------------------------------------------- 71 void Request::notify() 72 { 73 m_aJoiner.set(); 74 } 75 76 //----------------------------------------------------------------------------- 77 AsyncRequests::AsyncRequests(const RequestHandlerRef& rHandler) 78 : ::cppu::BaseMutex( ) 79 , ::osl::Thread ( ) 80 , m_bFinish (sal_False) 81 , m_rHandler (rHandler ) 82 , m_lRequests ( ) 83 { 84 } 85 86 //----------------------------------------------------------------------------- 87 AsyncRequests::~AsyncRequests() 88 { 89 // SYNCHRONIZED -> 90 ::osl::ResettableMutexGuard aLock(m_aMutex); 91 m_bFinish = sal_True; 92 aLock.clear(); 93 // <- SYNCHRONIZED 94 95 join(); 96 } 97 98 void AsyncRequests::triggerRequestProcessMessages (const RequestRef& rRequest) 99 { 100 // SYNCHRONIZED -> 101 ::osl::ResettableMutexGuard aLock(m_aMutex); 102 m_lRequests.push(rRequest); 103 aLock.clear(); 104 // <- SYNCHRONIZED 105 106 if ( ! isRunning()) 107 create(); 108 109 rRequest->waitProcessMessages(); 110 } 111 112 //----------------------------------------------------------------------------- 113 void AsyncRequests::triggerRequestBlocked(const RequestRef& rRequest) 114 { 115 // SYNCHRONIZED -> 116 ::osl::ResettableMutexGuard aLock(m_aMutex); 117 m_lRequests.push(rRequest); 118 aLock.clear(); 119 // <- SYNCHRONIZED 120 121 if ( ! isRunning()) 122 create(); 123 124 rRequest->wait(Request::WAIT_INFINITE); 125 } 126 127 //----------------------------------------------------------------------------- 128 void AsyncRequests::triggerRequestNonBlocked(const RequestRef& rRequest) 129 { 130 // SYNCHRONIZED -> 131 ::osl::ResettableMutexGuard aLock(m_aMutex); 132 m_lRequests.push(rRequest); 133 aLock.clear(); 134 // <- SYNCHRONIZED 135 136 if ( ! isRunning()) 137 create(); 138 } 139 140 //----------------------------------------------------------------------------- 141 void AsyncRequests::triggerRequestDirectly(const RequestRef& rRequest) 142 { 143 // SYNCHRONIZED -> 144 ::osl::ResettableMutexGuard aLock(m_aMutex); 145 RequestHandlerRef rHandler = m_rHandler; 146 aLock.clear(); 147 // <- SYNCHRONIZED 148 149 if (rHandler != NULL) 150 rHandler->doRequest(rRequest); 151 } 152 153 //----------------------------------------------------------------------------- 154 void AsyncRequests::triggerRequestThreadAware(const RequestRef& rRequest, 155 ::sal_Int16 nWait ) 156 { 157 oslThreadIdentifier nOurThreadId = getIdentifier(); 158 oslThreadIdentifier nCallerThreadId = ::osl::Thread::getCurrentIdentifier(); 159 if (nOurThreadId == nCallerThreadId) 160 triggerRequestDirectly(rRequest); 161 else if (nWait == BLOCKED) 162 triggerRequestBlocked(rRequest); 163 else if (nWait == PROCESS_MESSAGES) 164 triggerRequestProcessMessages(rRequest); 165 else 166 triggerRequestNonBlocked(rRequest); 167 } 168 169 //----------------------------------------------------------------------------- 170 171 172 //----------------------------------------------------------------------------- 173 void SAL_CALL AsyncRequests::run() 174 { 175 static const ::sal_Int32 TIME_TO_WAIT_FOR_NEW_REQUESTS = 250; 176 177 // SYNCHRONIZED -> 178 ::osl::ResettableMutexGuard aLock(m_aMutex); 179 RequestHandlerRef rHandler = m_rHandler; 180 ::sal_Bool bFinished = m_bFinish; 181 aLock.clear(); 182 // <- SYNCHRONIZED 183 184 if (rHandler != NULL) 185 rHandler->before(); 186 187 ::osl::Condition aWait; 188 189 while ( ! bFinished) 190 { 191 // SYNCHRONIZED -> 192 aLock.reset(); 193 194 RequestRef rRequest; 195 if ( ! m_lRequests.empty()) 196 { 197 rRequest = m_lRequests.front(); 198 m_lRequests.pop(); 199 } 200 bFinished = m_bFinish; 201 202 aLock.clear(); 203 // <- SYNCHRONIZED 204 205 if (rRequest == NULL) 206 { 207 lcl_sleep(aWait, TIME_TO_WAIT_FOR_NEW_REQUESTS); 208 continue; 209 } 210 211 if (rHandler != NULL) 212 { 213 rHandler->doRequest(rRequest); 214 rRequest->notify(); 215 } 216 } 217 218 if (rHandler != NULL) 219 rHandler->after(); 220 } 221 222 } // namespace vista 223 } // namespace win32 224 } // namespace fpicker 225