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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #include <svtools/asynclink.hxx>
28 #include <vos/mutex.hxx>
29 #include <tools/debug.hxx>
30 #include <vcl/timer.hxx>
31 #include <vcl/svapp.hxx>
32 
33 //--------------------------------------------------------------------
34 namespace svtools {
35 
CreateMutex()36 void AsynchronLink::CreateMutex()
37 {
38     if( !_pMutex ) _pMutex = new vos::OMutex;
39 }
40 
Call(void * pObj,sal_Bool bAllowDoubles,sal_Bool bUseTimer)41 void AsynchronLink::Call( void* pObj, sal_Bool
42 #ifdef DBG_UTIL
43 bAllowDoubles
44 #endif
45 , sal_Bool bUseTimer )
46 {
47 #ifdef DBG_UTIL
48 	if ( bUseTimer || !_bInCall )
49 		DBG_WARNING( "Recursives Call. Eher ueber Timer. TLX Fragen" );
50 #endif
51 	if( _aLink.IsSet() )
52 	{
53 		_pArg = pObj;
54 		DBG_ASSERT( bAllowDoubles ||
55 					( !_nEventId && ( !_pTimer || !_pTimer->IsActive() ) ),
56 					"Schon ein Call unterwegs" );
57 		if( _nEventId )
58 		{
59 			if( _pMutex ) _pMutex->acquire();
60 			Application::RemoveUserEvent( _nEventId );
61 			if( _pMutex ) _pMutex->release();
62 		}
63 		if( _pTimer )_pTimer->Stop();
64 		if( bUseTimer )
65 		{
66 			if( !_pTimer )
67 			{
68 				_pTimer = new Timer;
69 				_pTimer->SetTimeout( 0 );
70 				_pTimer->SetTimeoutHdl( STATIC_LINK(
71 					this, AsynchronLink, HandleCall) );
72 			}
73 			_pTimer->Start();
74 		}
75 		else
76 		{
77 			if( _pMutex ) _pMutex->acquire();
78             Application::PostUserEvent( _nEventId, STATIC_LINK( this, AsynchronLink, HandleCall), 0 );
79 			if( _pMutex ) _pMutex->release();
80 		}
81 	}
82 }
83 
~AsynchronLink()84 AsynchronLink::~AsynchronLink()
85 {
86 	if( _nEventId )
87 	{
88 		Application::RemoveUserEvent( _nEventId );
89 	}
90 	delete _pTimer;
91 	if( _pDeleted ) *_pDeleted = sal_True;
92 	delete _pMutex;
93 }
94 
IMPL_STATIC_LINK(AsynchronLink,HandleCall,void *,EMPTYARG)95 IMPL_STATIC_LINK( AsynchronLink, HandleCall, void*, EMPTYARG )
96 {
97 	if( pThis->_pMutex ) pThis->_pMutex->acquire();
98 	pThis->_nEventId = 0;
99 	if( pThis->_pMutex ) pThis->_pMutex->release();
100 	pThis->Call_Impl( pThis->_pArg );
101 	return 0;
102 }
103 
ForcePendingCall()104 void AsynchronLink::ForcePendingCall()
105 {
106 	ClearPendingCall();
107 	Call_Impl( _pArg );
108 }
109 
ClearPendingCall()110 void AsynchronLink::ClearPendingCall()
111 {
112     if( _pMutex ) _pMutex->acquire();
113 	if( _nEventId )
114 	{
115 		Application::RemoveUserEvent( _nEventId );
116 		_nEventId = 0;
117 	}
118     if( _pMutex ) _pMutex->release();
119 	if( _pTimer ) _pTimer->Stop();
120 }
121 
Call_Impl(void * pArg)122 void AsynchronLink::Call_Impl( void* pArg )
123 {
124 	_bInCall = sal_True;
125 	sal_Bool bDeleted = sal_False;
126 	_pDeleted = &bDeleted;
127 	_aLink.Call( pArg );
128 	if( !bDeleted )
129 	{
130 		_bInCall = sal_False;
131 		_pDeleted = 0;
132 	}
133 }
134 
135 }
136