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