18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2009, The Android Open Source Project 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Google Inc. All rights reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 83298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * * Redistributions of source code must retain the above copyright 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 103298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * * Redistributions in binary form must reproduce the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 143298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 173298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 243298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginTimer.h" 297e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger#include "RefPtr.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33c02eba192362e2ea83fdfbe0be51a08429ec4123Ben Murdoch static uint32_t gTimerID; 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PluginTimer::PluginTimer(PluginTimer** list, NPP instance, bool repeat, 36c02eba192362e2ea83fdfbe0be51a08429ec4123Ben Murdoch void (*timerFunc)(NPP npp, uint32_t timerID)) 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_list(list), 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_instance(instance), 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timerFunc(timerFunc), 4081b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard m_repeat(repeat), 4181b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard m_unscheduled(false) 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timerID = ++gTimerID; 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_next = *list; 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_next) { 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_next->m_prev = this; 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_prev = 0; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *list = this; 511a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott relaxAdoptionRequirement(); 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PluginTimer::~PluginTimer() 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_next) { 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_next->m_prev = m_prev; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_prev) { 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_prev->m_next = m_next; 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *m_list = m_next; 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project void PluginTimer::fired() 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 687e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger // ensure the timer cannot be deleted until this method completes 697e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger RefPtr<PluginTimer> protector(this); 707e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger 7181b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard if (!m_unscheduled) 7281b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard m_timerFunc(m_instance, m_timerID); 7381b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard 74d1f25a8a55bba56cdfbe6275a04028e5f85d6bdaDerek Sollenberger // remove the timer if it is a one-shot timer (!m_repeat) or if is a 75d1f25a8a55bba56cdfbe6275a04028e5f85d6bdaDerek Sollenberger // repeating timer that has been unscheduled. In either case we must 76d1f25a8a55bba56cdfbe6275a04028e5f85d6bdaDerek Sollenberger // ensure that the refcount is 2 or greater since the PluginTimerList 77d1f25a8a55bba56cdfbe6275a04028e5f85d6bdaDerek Sollenberger // could have been deleted by the timerFunc and we must ensure that we 78d1f25a8a55bba56cdfbe6275a04028e5f85d6bdaDerek Sollenberger // do not double delete. 79d1f25a8a55bba56cdfbe6275a04028e5f85d6bdaDerek Sollenberger if ((!m_repeat || m_unscheduled) && refCount() > 1) 807e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger deref(); // mark the timer for deletion as it is no longer needed 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // may return null if timerID is not found 84c02eba192362e2ea83fdfbe0be51a08429ec4123Ben Murdoch PluginTimer* PluginTimer::Find(PluginTimer* list, uint32_t timerID) 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PluginTimer* curr = list; 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (curr) { 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (curr->m_timerID == timerID) { 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project curr = curr->m_next; 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return curr; 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /////////////////////////////////////////////////////////////////////////// 977e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PluginTimerList::~PluginTimerList() 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1007e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger PluginTimer* curr = m_list; 1017e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger PluginTimer* next; 1027e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger while (curr) { 1037e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger next = curr->next(); 1047e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger curr->deref(); 1057e336d32d9c3465ff9792faa8ccc8613b7849e4cDerek Sollenberger curr = next; 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 109c02eba192362e2ea83fdfbe0be51a08429ec4123Ben Murdoch uint32_t PluginTimerList::schedule(NPP instance, uint32_t interval, bool repeat, 110c02eba192362e2ea83fdfbe0be51a08429ec4123Ben Murdoch void (*proc)(NPP npp, uint32_t timerID)) 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PluginTimer* timer = new PluginTimer(&m_list, instance, repeat, proc); 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double dinterval = interval * 0.001; // milliseconds to seconds 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (repeat) { 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project timer->startRepeating(dinterval); 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project timer->startOneShot(dinterval); 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return timer->timerID(); 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 123c02eba192362e2ea83fdfbe0be51a08429ec4123Ben Murdoch void PluginTimerList::unschedule(NPP instance, uint32_t timerID) 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 12581b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard // Although it looks like simply deleting the timer would work here 12681b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard // (stop() will be executed by the dtor), we cannot do this, as 12781b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard // the plugin can call us while we are in the fired() method, 12881b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard // (when we execute the timerFunc callback). Deleting the object 12981b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard // we are in would then be a rather bad move... 13081b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard PluginTimer* timer = PluginTimer::Find(m_list, timerID); 13181b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard if (timer) 13281b3dad72dd3fbc96e1128fc3d011272c4c27b91Nicolas Roard timer->unschedule(); 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 136