1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "fxjs/global_timer.h"
8
9 #include <map>
10
11 #include "core/fxcrt/timerhandler_iface.h"
12 #include "fxjs/cjs_app.h"
13 #include "third_party/base/no_destructor.h"
14
15 namespace {
16
17 using TimerMap = std::map<int32_t, GlobalTimer*>;
GetGlobalTimerMap()18 TimerMap& GetGlobalTimerMap() {
19 static pdfium::base::NoDestructor<TimerMap> timer_map;
20 return *timer_map;
21 }
22
23 } // namespace
24
GlobalTimer(CJS_App * pObj,CJS_Runtime * pRuntime,Type nType,const WideString & script,uint32_t dwElapse,uint32_t dwTimeOut)25 GlobalTimer::GlobalTimer(CJS_App* pObj,
26 CJS_Runtime* pRuntime,
27 Type nType,
28 const WideString& script,
29 uint32_t dwElapse,
30 uint32_t dwTimeOut)
31 : m_nType(nType),
32 m_nTimerID(pRuntime->GetTimerHandler()->SetTimer(dwElapse, Trigger)),
33 m_dwTimeOut(dwTimeOut),
34 m_swJScript(script),
35 m_pRuntime(pRuntime),
36 m_pEmbedApp(pObj) {
37 if (HasValidID())
38 GetGlobalTimerMap()[m_nTimerID] = this;
39 }
40
~GlobalTimer()41 GlobalTimer::~GlobalTimer() {
42 if (!HasValidID())
43 return;
44
45 if (m_pRuntime && m_pRuntime->GetTimerHandler())
46 m_pRuntime->GetTimerHandler()->KillTimer(m_nTimerID);
47
48 GetGlobalTimerMap().erase(m_nTimerID);
49 }
50
51 // static
Trigger(int32_t nTimerID)52 void GlobalTimer::Trigger(int32_t nTimerID) {
53 auto it = GetGlobalTimerMap().find(nTimerID);
54 if (it == GetGlobalTimerMap().end())
55 return;
56
57 GlobalTimer* pTimer = it->second;
58 if (pTimer->m_bProcessing)
59 return;
60
61 pTimer->m_bProcessing = true;
62 if (pTimer->m_pEmbedApp)
63 pTimer->m_pEmbedApp->TimerProc(pTimer);
64
65 // Timer proc may have destroyed timer, find it again.
66 it = GetGlobalTimerMap().find(nTimerID);
67 if (it == GetGlobalTimerMap().end())
68 return;
69
70 pTimer = it->second;
71 pTimer->m_bProcessing = false;
72 if (pTimer->IsOneShot())
73 pTimer->m_pEmbedApp->CancelProc(pTimer);
74 }
75
76 // static
Cancel(int32_t nTimerID)77 void GlobalTimer::Cancel(int32_t nTimerID) {
78 auto it = GetGlobalTimerMap().find(nTimerID);
79 if (it == GetGlobalTimerMap().end())
80 return;
81
82 GlobalTimer* pTimer = it->second;
83 pTimer->m_pEmbedApp->CancelProc(pTimer);
84 }
85
HasValidID() const86 bool GlobalTimer::HasValidID() const {
87 return m_nTimerID != TimerHandlerIface::kInvalidTimerID;
88 }
89