1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 31 #include "tools/TimerBasedTaskExecution.hxx" 32 #include "tools/AsynchronousTask.hxx" 33 #include <tools/time.hxx> 34 #include <osl/diagnose.h> 35 #include <boost/weak_ptr.hpp> 36 37 #undef VERBOSE 38 39 namespace sd { namespace tools { 40 41 /** Used by the shared_ptr instead of the private destructor. 42 */ 43 class TimerBasedTaskExecution::Deleter 44 { 45 public: 46 void operator() (TimerBasedTaskExecution* pObject) 47 { 48 delete pObject; 49 } 50 }; 51 52 53 54 55 ::boost::shared_ptr<TimerBasedTaskExecution> TimerBasedTaskExecution::Create ( 56 const ::boost::shared_ptr<AsynchronousTask>& rpTask, 57 sal_uInt32 nMillisecondsBetweenSteps, 58 sal_uInt32 nMaxTimePerStep) 59 { 60 ::boost::shared_ptr<TimerBasedTaskExecution> pExecution( 61 new TimerBasedTaskExecution(rpTask,nMillisecondsBetweenSteps,nMaxTimePerStep), 62 Deleter()); 63 // Let the new object have a shared_ptr to itself, so that it can 64 // release itself when the AsynchronousTask has been executed 65 // completely. 66 pExecution->SetSelf(pExecution); 67 return pExecution; 68 } 69 70 71 72 73 void TimerBasedTaskExecution::Release (void) 74 { 75 maTimer.Stop(); 76 mpSelf.reset(); 77 } 78 79 80 81 82 //static 83 void TimerBasedTaskExecution::ReleaseTask ( 84 const ::boost::weak_ptr<TimerBasedTaskExecution>& rpExecution) 85 { 86 if ( ! rpExecution.expired()) 87 { 88 try 89 { 90 ::boost::shared_ptr<tools::TimerBasedTaskExecution> pExecution (rpExecution); 91 pExecution->Release(); 92 } 93 catch (::boost::bad_weak_ptr) 94 { 95 // When a bad_weak_ptr has been thrown then the object pointed 96 // to by rpTask has been released right after we checked that it 97 // still existed. Too bad, but that means, that we have nothing 98 // more do. 99 } 100 } 101 } 102 103 104 105 106 TimerBasedTaskExecution::TimerBasedTaskExecution ( 107 const ::boost::shared_ptr<AsynchronousTask>& rpTask, 108 sal_uInt32 nMillisecondsBetweenSteps, 109 sal_uInt32 nMaxTimePerStep) 110 : mpTask(rpTask), 111 maTimer(), 112 mpSelf(), 113 mnMaxTimePerStep(nMaxTimePerStep) 114 { 115 Link aLink(LINK(this,TimerBasedTaskExecution,TimerCallback)); 116 maTimer.SetTimeoutHdl(aLink); 117 maTimer.SetTimeout(nMillisecondsBetweenSteps); 118 maTimer.Start(); 119 } 120 121 122 123 124 TimerBasedTaskExecution::~TimerBasedTaskExecution (void) 125 { 126 maTimer.Stop(); 127 } 128 129 130 131 132 void TimerBasedTaskExecution::SetSelf ( 133 const ::boost::shared_ptr<TimerBasedTaskExecution>& rpSelf) 134 { 135 if (mpTask.get() != NULL) 136 mpSelf = rpSelf; 137 } 138 139 140 141 142 IMPL_LINK(TimerBasedTaskExecution,TimerCallback, Timer*,EMPTYARG) 143 { 144 if (mpTask.get() != NULL) 145 { 146 if (mpTask->HasNextStep()) 147 { 148 // Execute as many steps as fit into the time span of length 149 // mnMaxTimePerStep. Note that the last step may take longer 150 // than allowed. 151 sal_uInt32 nStartTime (Time().GetMSFromTime()); 152 #ifdef VERBOSE 153 OSL_TRACE("starting TimerBasedTaskExecution at %d", nStartTime); 154 #endif 155 do 156 { 157 mpTask->RunNextStep(); 158 sal_uInt32 nDuration (Time().GetMSFromTime()-nStartTime); 159 #ifdef VERBOSE 160 OSL_TRACE("executed step in %d", nDuration); 161 #endif 162 if (nDuration > mnMaxTimePerStep) 163 break; 164 } 165 while (mpTask->HasNextStep()); 166 #ifdef VERBOSE 167 OSL_TRACE("TimerBasedTaskExecution sleeping"); 168 #endif 169 maTimer.Start(); 170 } 171 else 172 mpSelf.reset(); 173 } 174 175 return 0; 176 } 177 178 179 } } // end of namespace ::sd::tools 180 181