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_sd.hxx"
26
27 #include "tools/TimerBasedTaskExecution.hxx"
28 #include "tools/AsynchronousTask.hxx"
29 #include <tools/time.hxx>
30 #include <osl/diagnose.h>
31 #include <boost/weak_ptr.hpp>
32
33 #undef VERBOSE
34
35 namespace sd { namespace tools {
36
37 /** Used by the shared_ptr instead of the private destructor.
38 */
39 class TimerBasedTaskExecution::Deleter
40 {
41 public:
operator ()(TimerBasedTaskExecution * pObject)42 void operator() (TimerBasedTaskExecution* pObject)
43 {
44 delete pObject;
45 }
46 };
47
48
49
50
Create(const::boost::shared_ptr<AsynchronousTask> & rpTask,sal_uInt32 nMillisecondsBetweenSteps,sal_uInt32 nMaxTimePerStep)51 ::boost::shared_ptr<TimerBasedTaskExecution> TimerBasedTaskExecution::Create (
52 const ::boost::shared_ptr<AsynchronousTask>& rpTask,
53 sal_uInt32 nMillisecondsBetweenSteps,
54 sal_uInt32 nMaxTimePerStep)
55 {
56 ::boost::shared_ptr<TimerBasedTaskExecution> pExecution(
57 new TimerBasedTaskExecution(rpTask,nMillisecondsBetweenSteps,nMaxTimePerStep),
58 Deleter());
59 // Let the new object have a shared_ptr to itself, so that it can
60 // release itself when the AsynchronousTask has been executed
61 // completely.
62 pExecution->SetSelf(pExecution);
63 return pExecution;
64 }
65
66
67
68
Release(void)69 void TimerBasedTaskExecution::Release (void)
70 {
71 maTimer.Stop();
72 mpSelf.reset();
73 }
74
75
76
77
78 //static
ReleaseTask(const::boost::weak_ptr<TimerBasedTaskExecution> & rpExecution)79 void TimerBasedTaskExecution::ReleaseTask (
80 const ::boost::weak_ptr<TimerBasedTaskExecution>& rpExecution)
81 {
82 if ( ! rpExecution.expired())
83 {
84 try
85 {
86 ::boost::shared_ptr<tools::TimerBasedTaskExecution> pExecution (rpExecution);
87 pExecution->Release();
88 }
89 catch (::boost::bad_weak_ptr)
90 {
91 // When a bad_weak_ptr has been thrown then the object pointed
92 // to by rpTask has been released right after we checked that it
93 // still existed. Too bad, but that means, that we have nothing
94 // more do.
95 }
96 }
97 }
98
99
100
101
TimerBasedTaskExecution(const::boost::shared_ptr<AsynchronousTask> & rpTask,sal_uInt32 nMillisecondsBetweenSteps,sal_uInt32 nMaxTimePerStep)102 TimerBasedTaskExecution::TimerBasedTaskExecution (
103 const ::boost::shared_ptr<AsynchronousTask>& rpTask,
104 sal_uInt32 nMillisecondsBetweenSteps,
105 sal_uInt32 nMaxTimePerStep)
106 : mpTask(rpTask),
107 maTimer(),
108 mpSelf(),
109 mnMaxTimePerStep(nMaxTimePerStep)
110 {
111 Link aLink(LINK(this,TimerBasedTaskExecution,TimerCallback));
112 maTimer.SetTimeoutHdl(aLink);
113 maTimer.SetTimeout(nMillisecondsBetweenSteps);
114 maTimer.Start();
115 }
116
117
118
119
~TimerBasedTaskExecution(void)120 TimerBasedTaskExecution::~TimerBasedTaskExecution (void)
121 {
122 maTimer.Stop();
123 }
124
125
126
127
SetSelf(const::boost::shared_ptr<TimerBasedTaskExecution> & rpSelf)128 void TimerBasedTaskExecution::SetSelf (
129 const ::boost::shared_ptr<TimerBasedTaskExecution>& rpSelf)
130 {
131 if (mpTask.get() != NULL)
132 mpSelf = rpSelf;
133 }
134
135
136
137
IMPL_LINK(TimerBasedTaskExecution,TimerCallback,Timer *,EMPTYARG)138 IMPL_LINK(TimerBasedTaskExecution,TimerCallback, Timer*,EMPTYARG)
139 {
140 if (mpTask.get() != NULL)
141 {
142 if (mpTask->HasNextStep())
143 {
144 // Execute as many steps as fit into the time span of length
145 // mnMaxTimePerStep. Note that the last step may take longer
146 // than allowed.
147 sal_uInt32 nStartTime (Time().GetMSFromTime());
148 #ifdef VERBOSE
149 OSL_TRACE("starting TimerBasedTaskExecution at %d", nStartTime);
150 #endif
151 do
152 {
153 mpTask->RunNextStep();
154 sal_uInt32 nDuration (Time().GetMSFromTime()-nStartTime);
155 #ifdef VERBOSE
156 OSL_TRACE("executed step in %d", nDuration);
157 #endif
158 if (nDuration > mnMaxTimePerStep)
159 break;
160 }
161 while (mpTask->HasNextStep());
162 #ifdef VERBOSE
163 OSL_TRACE("TimerBasedTaskExecution sleeping");
164 #endif
165 maTimer.Start();
166 }
167 else
168 mpSelf.reset();
169 }
170
171 return 0;
172 }
173
174
175 } } // end of namespace ::sd::tools
176
177