15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/plugin_thread_task_runner.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta CalcTimeDelta(base::TimeTicks when) { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::max(when - base::TimeTicks::Now(), base::TimeDelta()); 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadTaskRunner::Delegate::~Delegate() { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadTaskRunner::PluginThreadTaskRunner(Delegate* delegate) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : plugin_thread_id_(base::PlatformThread::CurrentId()), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_(false, false), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(delegate), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_sequence_num_(0), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_received_(false), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stopped_(false) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadTaskRunner::~PluginThreadTaskRunner() { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_ == NULL); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(stopped_); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::DetachAndRunShutdownLoop() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BelongsToCurrentThread()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Detach from the plugin thread and redirect all tasks posted after this 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // point to the shutdown task loop. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(delegate_ != NULL); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!stopped_); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = NULL; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stopped_ = quit_received_; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When DetachAndRunShutdownLoop() is called from NPP_Destroy() all scheduled 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timers are cancelled. It is OK to clear |scheduled_timers_| even if 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the timers weren't actually cancelled (i.e. DetachAndRunShutdownLoop() is 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called before NPP_Destroy()). 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduled_timers_.clear(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run all tasks that are due. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessIncomingTasks(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunDueTasks(base::TimeTicks::Now()); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!stopped_) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delayed_queue_.empty()) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Wait(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.TimedWait(CalcTimeDelta(delayed_queue_.top().delayed_run_time)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run all tasks that are due. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessIncomingTasks(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunDueTasks(base::TimeTicks::Now()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stopped_ = quit_received_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::Quit() { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!quit_received_) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_received_ = true; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Signal(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginThreadTaskRunner::PostDelayedTask( 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delay) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap the task into |base::PendingTask|. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks delayed_run_time; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delay > base::TimeDelta()) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_run_time = base::TimeTicks::Now() + delay; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(delay.InMilliseconds(), 0) << "delay should not be negative"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PendingTask pending_task(from_here, task, delayed_run_time, false); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Push the task to the incoming queue. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the sequence number. The sequence number provides FIFO ordering 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for tasks with the same |delayed_run_time|. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_task.sequence_num = next_sequence_num_++; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post an asynchronous call on the plugin thread to process the task. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (incoming_queue_.empty()) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostRunTasks(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming_queue_.push(pending_task); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_task.task.Reset(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No tasks should be posted after Quit() has been called. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!quit_received_); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginThreadTaskRunner::PostNonNestableDelayedTask( 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delay) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All tasks running on this task loop are non-nestable. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PostDelayedTask(from_here, task, delay); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginThreadTaskRunner::RunsTasksOnCurrentThread() const { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In pepper plugins ideally we should use pp::Core::IsMainThread, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but it is problematic because we would need to keep reference to 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Core somewhere, e.g. make the delegate ref-counted. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::PlatformThread::CurrentId() == plugin_thread_id_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::PostRunTasks() { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post tasks to the plugin thread when it is availabe or spin the shutdown 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // task loop. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_ != NULL) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure closure = base::Bind(&PluginThreadTaskRunner::RunTasks, this); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->RunOnPluginThread( 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta(), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &PluginThreadTaskRunner::TaskSpringboard, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::Closure(closure)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Signal(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::PostDelayedRunTasks(base::TimeTicks when) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BelongsToCurrentThread()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |delegate_| is updated from the plugin thread only, so it is safe to access 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it here without taking the lock. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_ != NULL) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule RunDelayedTasks() to be called at |when| if it hasn't been 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scheduled already. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scheduled_timers_.insert(when).second) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delay = CalcTimeDelta(when); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure closure = 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PluginThreadTaskRunner::RunDelayedTasks, this, when); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->RunOnPluginThread( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &PluginThreadTaskRunner::TaskSpringboard, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::Closure(closure)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spin the shutdown loop if the task runner has already been detached. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The shutdown loop will pick the tasks to run itself. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_.Signal(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::ProcessIncomingTasks() { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BelongsToCurrentThread()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Grab all unsorted tasks accomulated so far. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TaskQueue work_queue; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming_queue_.Swap(&work_queue); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!work_queue.empty()) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PendingTask pending_task = work_queue.front(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_queue.pop(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_task.delayed_run_time.is_null()) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_task.task.Run(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_queue_.push(pending_task); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::RunDelayedTasks(base::TimeTicks when) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BelongsToCurrentThread()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduled_timers_.erase(when); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |stopped_| is updated by the plugin thread only, so it is safe to access 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it here without taking the lock. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!stopped_) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessIncomingTasks(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunDueTasks(base::TimeTicks::Now()); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::RunDueTasks(base::TimeTicks now) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BelongsToCurrentThread()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run all due tasks. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!delayed_queue_.empty() && 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_queue_.top().delayed_run_time <= now) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_queue_.top().task.Run(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_queue_.pop(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a delayed asynchronous call to the plugin thread to process tasks from 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the delayed queue. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delayed_queue_.empty()) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks when = delayed_queue_.top().delayed_run_time; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scheduled_timers_.empty() || when < *scheduled_timers_.begin()) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostDelayedRunTasks(when); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::RunTasks() { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BelongsToCurrentThread()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |stopped_| is updated by the plugin thread only, so it is safe to access 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it here without taking the lock. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!stopped_) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessIncomingTasks(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunDueTasks(base::TimeTicks::Now()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadTaskRunner::TaskSpringboard(void* data) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure* task = reinterpret_cast<base::Closure*>(data); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task->Run(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete task; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 248