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: 42 void operator() (TimerBasedTaskExecution* pObject) 43 { 44 delete pObject; 45 } 46 }; 47 48 49 50 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 69 void TimerBasedTaskExecution::Release (void) 70 { 71 maTimer.Stop(); 72 mpSelf.reset(); 73 } 74 75 76 77 78 //static 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 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 120 TimerBasedTaskExecution::~TimerBasedTaskExecution (void) 121 { 122 maTimer.Stop(); 123 } 124 125 126 127 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 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