1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/base/delayed_unique_notifier.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind_helpers.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/location.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/sequenced_task_runner.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace cc { 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DelayedUniqueNotifier::DelayedUniqueNotifier( 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SequencedTaskRunner* task_runner, 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::Closure& closure, 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::TimeDelta& delay) 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : task_runner_(task_runner), 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) closure_(closure), 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delay_(delay), 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) notification_pending_(false), 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_(this) { 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DelayedUniqueNotifier::~DelayedUniqueNotifier() { 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DelayedUniqueNotifier::Schedule() { 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (notification_pending_) { 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) next_notification_time_ = Now() + delay_; 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) next_notification_time_ = Now() + delay_; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) task_runner_->PostDelayedTask(FROM_HERE, 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&DelayedUniqueNotifier::NotifyIfTime, 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delay_); 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) notification_pending_ = true; 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DelayedUniqueNotifier::Cancel() { 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) next_notification_time_ = base::TimeTicks(); 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DelayedUniqueNotifier::HasPendingNotification() const { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return notification_pending_ && !next_notification_time_.is_null(); 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::TimeTicks DelayedUniqueNotifier::Now() const { 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::TimeTicks::Now(); 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DelayedUniqueNotifier::NotifyIfTime() { 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If next notifiaction time is not valid, then this schedule was canceled. 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (next_notification_time_.is_null()) { 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) notification_pending_ = false; 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If the notification was rescheduled or arrived too early for any other 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // reason, then post another task instead of running the callback. 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeTicks now = Now(); 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (next_notification_time_ > now) { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) task_runner_->PostDelayedTask( 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&DelayedUniqueNotifier::NotifyIfTime, 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) next_notification_time_ - now); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Note the order here is important since closure might schedule another run. 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) notification_pending_ = false; 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) closure_.Run(); 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace cc 79