1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "asyncrequests.hxx" 29 #include <vcl/svapp.hxx> 30 #include <vos/mutex.hxx> 31 32 //----------------------------------------------------------------------------- 33 // namespace 34 //----------------------------------------------------------------------------- 35 36 namespace fpicker{ 37 namespace win32{ 38 namespace vista{ 39 40 namespace css = ::com::sun::star; 41 42 //----------------------------------------------------------------------------- 43 void lcl_sleep(::osl::Condition& aCondition , 44 ::sal_Int32 nMilliSeconds) 45 { 46 sal_uLong nAcquireCount = Application::ReleaseSolarMutex(); 47 48 if (nMilliSeconds < 1) 49 aCondition.wait(0); 50 else 51 { 52 TimeValue aTime; 53 aTime.Seconds = (nMilliSeconds / 1000); 54 aTime.Nanosec = (nMilliSeconds % 1000) * 1000000; 55 aCondition.wait(&aTime); 56 } 57 58 Application::AcquireSolarMutex( nAcquireCount ); 59 } 60 61 //----------------------------------------------------------------------------- 62 void Request::wait(::sal_Int32 nMilliSeconds) 63 { 64 lcl_sleep(m_aJoiner, nMilliSeconds); 65 } 66 67 void Request::waitProcessMessages() 68 { 69 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 70 while (!m_aJoiner.check()) 71 Application::Yield(); 72 } 73 74 //----------------------------------------------------------------------------- 75 void Request::notify() 76 { 77 m_aJoiner.set(); 78 } 79 80 //----------------------------------------------------------------------------- 81 AsyncRequests::AsyncRequests(const RequestHandlerRef& rHandler) 82 : ::cppu::BaseMutex( ) 83 , ::osl::Thread ( ) 84 , m_bFinish (sal_False) 85 , m_rHandler (rHandler ) 86 , m_lRequests ( ) 87 { 88 } 89 90 //----------------------------------------------------------------------------- 91 AsyncRequests::~AsyncRequests() 92 { 93 // SYNCHRONIZED -> 94 ::osl::ResettableMutexGuard aLock(m_aMutex); 95 m_bFinish = sal_True; 96 aLock.clear(); 97 // <- SYNCHRONIZED 98 99 join(); 100 } 101 102 void AsyncRequests::triggerRequestProcessMessages (const RequestRef& rRequest) 103 { 104 // SYNCHRONIZED -> 105 ::osl::ResettableMutexGuard aLock(m_aMutex); 106 m_lRequests.push(rRequest); 107 aLock.clear(); 108 // <- SYNCHRONIZED 109 110 if ( ! isRunning()) 111 create(); 112 113 rRequest->waitProcessMessages(); 114 } 115 116 //----------------------------------------------------------------------------- 117 void AsyncRequests::triggerRequestBlocked(const RequestRef& rRequest) 118 { 119 // SYNCHRONIZED -> 120 ::osl::ResettableMutexGuard aLock(m_aMutex); 121 m_lRequests.push(rRequest); 122 aLock.clear(); 123 // <- SYNCHRONIZED 124 125 if ( ! isRunning()) 126 create(); 127 128 rRequest->wait(Request::WAIT_INFINITE); 129 } 130 131 //----------------------------------------------------------------------------- 132 void AsyncRequests::triggerRequestNonBlocked(const RequestRef& rRequest) 133 { 134 // SYNCHRONIZED -> 135 ::osl::ResettableMutexGuard aLock(m_aMutex); 136 m_lRequests.push(rRequest); 137 aLock.clear(); 138 // <- SYNCHRONIZED 139 140 if ( ! isRunning()) 141 create(); 142 } 143 144 //----------------------------------------------------------------------------- 145 void AsyncRequests::triggerRequestDirectly(const RequestRef& rRequest) 146 { 147 // SYNCHRONIZED -> 148 ::osl::ResettableMutexGuard aLock(m_aMutex); 149 RequestHandlerRef rHandler = m_rHandler; 150 aLock.clear(); 151 // <- SYNCHRONIZED 152 153 if (rHandler != NULL) 154 rHandler->doRequest(rRequest); 155 } 156 157 //----------------------------------------------------------------------------- 158 void AsyncRequests::triggerRequestThreadAware(const RequestRef& rRequest, 159 ::sal_Int16 nWait ) 160 { 161 oslThreadIdentifier nOurThreadId = getIdentifier(); 162 oslThreadIdentifier nCallerThreadId = ::osl::Thread::getCurrentIdentifier(); 163 if (nOurThreadId == nCallerThreadId) 164 triggerRequestDirectly(rRequest); 165 else if (nWait == BLOCKED) 166 triggerRequestBlocked(rRequest); 167 else if (nWait == PROCESS_MESSAGES) 168 triggerRequestProcessMessages(rRequest); 169 else 170 triggerRequestNonBlocked(rRequest); 171 } 172 173 //----------------------------------------------------------------------------- 174 175 176 //----------------------------------------------------------------------------- 177 void SAL_CALL AsyncRequests::run() 178 { 179 static const ::sal_Int32 TIME_TO_WAIT_FOR_NEW_REQUESTS = 250; 180 181 // SYNCHRONIZED -> 182 ::osl::ResettableMutexGuard aLock(m_aMutex); 183 RequestHandlerRef rHandler = m_rHandler; 184 ::sal_Bool bFinished = m_bFinish; 185 aLock.clear(); 186 // <- SYNCHRONIZED 187 188 if (rHandler != NULL) 189 rHandler->before(); 190 191 ::osl::Condition aWait; 192 193 while ( ! bFinished) 194 { 195 // SYNCHRONIZED -> 196 aLock.reset(); 197 198 RequestRef rRequest; 199 if ( ! m_lRequests.empty()) 200 { 201 rRequest = m_lRequests.front(); 202 m_lRequests.pop(); 203 } 204 bFinished = m_bFinish; 205 206 aLock.clear(); 207 // <- SYNCHRONIZED 208 209 if (rRequest == NULL) 210 { 211 lcl_sleep(aWait, TIME_TO_WAIT_FOR_NEW_REQUESTS); 212 continue; 213 } 214 215 if (rHandler != NULL) 216 { 217 rHandler->doRequest(rRequest); 218 rRequest->notify(); 219 } 220 } 221 222 if (rHandler != NULL) 223 rHandler->after(); 224 } 225 226 } // namespace vista 227 } // namespace win32 228 } // namespace fpicker 229