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