/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/** Queue all scheduled tasks and process them when their time has come.
*/ class TimerScheduler
: public std::enable_shared_from_this<TimerScheduler>, public ::osl::Thread
{ public: static std::shared_ptr<TimerScheduler> Instance(
uno::Reference<uno::XComponentContext> const& xContext); static SharedTimerTask CreateTimerTask ( const PresenterTimer::Task& rTask, const TimeValue& rDueTime, const sal_Int64 nRepeatInterval);
void TimerScheduler::CancelTask (const sal_Int32 nTaskId)
{ // Set of scheduled tasks is sorted after their due times, not their // task ids. Therefore we have to do a linear search for the task to // cancel.
{
std::scoped_lock aGuard (maTaskContainerMutex); auto iTask = std::find_if(maScheduledTasks.begin(), maScheduledTasks.end(),
[nTaskId](const SharedTimerTask& rxTask) { return rxTask->mnTaskId == nTaskId; }); if (iTask != maScheduledTasks.end())
maScheduledTasks.erase(iTask);
}
// The task that is to be canceled may be currently about to be // processed. Mark it with a flag that a) prevents a repeating task // from being scheduled again and b) tries to prevent its execution.
{
std::scoped_lock aGuard (maCurrentTaskMutex); if (mpCurrentTask
&& mpCurrentTask->mnTaskId == nTaskId)
mpCurrentTask->mbIsCanceled = true;
}
while (true)
{ // Get the current time.
TimeValue aCurrentTime; if ( ! GetCurrentTime(aCurrentTime))
{ // We can not get the current time and thus can not schedule anything. break;
}
// Restrict access to the maScheduledTasks member to one, mutex // guarded, block.
SharedTimerTask pTask;
sal_Int64 nDifference = 0;
{
std::scoped_lock aGuard (maTaskContainerMutex);
// There are no more scheduled task. Leave this loop, function and // live of the TimerScheduler. if (maScheduledTasks.empty()) break;
// Acquire a reference to the current task.
{
std::scoped_lock aGuard (maCurrentTaskMutex);
mpCurrentTask = pTask;
}
if (!pTask)
{ // Wait until the first task becomes due.
TimeValue aTimeValue;
ConvertToTimeValue(aTimeValue, nDifference); // wait on condition variable, so the thread can be stopped
m_Shutdown.wait(&aTimeValue);
} else
{ // Execute task. if (pTask->maTask && !pTask->mbIsCanceled)
{
pTask->maTask(aCurrentTime);
ListenerContainer::iterator iListener (::std::find(
maListeners.begin(),
maListeners.end(),
rListener)); if (iListener != maListeners.end())
maListeners.erase(iListener); if (maListeners.empty())
{ // We have no more clients and therefore are not interested in time changes. if (mnTimerTaskId != PresenterTimer::NotAValidTaskId)
{
PresenterTimer::CancelTask(mnTimerTaskId);
mnTimerTaskId = PresenterTimer::NotAValidTaskId;
}
mpInstance = nullptr;
}
}
TimeValue aCurrentTime (rCurrentTime);
oslDateTime aDateTime; if (osl_getDateTimeFromTimeValue(&aCurrentTime, &aDateTime))
{ if (aDateTime.Seconds != maDateTime.Seconds
|| aDateTime.Minutes != maDateTime.Minutes
|| aDateTime.Hours != maDateTime.Hours)
{ // The displayed part of the current time has changed. // Prepare to call the listeners.
maDateTime = aDateTime;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.