1 // Copyright 2017 The PDFium Authors
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/cfx_timer.h"
12 #include "core/fxcrt/check.h"
13 #include "core/fxcrt/containers/contains.h"
14 #include "fxjs/cjs_app.h"
15
16 namespace {
17
18 using TimerMap = std::map<int32_t, GlobalTimer*>;
19 TimerMap* g_global_timer_map = nullptr;
20
21 } // namespace
22
23 // static
InitializeGlobals()24 void GlobalTimer::InitializeGlobals() {
25 CHECK(!g_global_timer_map);
26 g_global_timer_map = new TimerMap();
27 }
28
29 // static
DestroyGlobals()30 void GlobalTimer::DestroyGlobals() {
31 delete g_global_timer_map;
32 g_global_timer_map = nullptr;
33 }
34
GlobalTimer(CJS_App * pObj,CJS_Runtime * pRuntime,Type nType,const WideString & script,uint32_t dwElapse,uint32_t dwTimeOut)35 GlobalTimer::GlobalTimer(CJS_App* pObj,
36 CJS_Runtime* pRuntime,
37 Type nType,
38 const WideString& script,
39 uint32_t dwElapse,
40 uint32_t dwTimeOut)
41 : m_nType(nType),
42 m_nTimerID(pRuntime->GetTimerHandler()->SetTimer(dwElapse, Trigger)),
43 m_dwTimeOut(dwTimeOut),
44 m_swJScript(script),
45 m_pRuntime(pRuntime),
46 m_pEmbedApp(pObj) {
47 if (HasValidID()) {
48 DCHECK(!pdfium::Contains((*g_global_timer_map), m_nTimerID));
49 (*g_global_timer_map)[m_nTimerID] = this;
50 }
51 }
52
~GlobalTimer()53 GlobalTimer::~GlobalTimer() {
54 if (!HasValidID())
55 return;
56
57 if (m_pRuntime && m_pRuntime->GetTimerHandler())
58 m_pRuntime->GetTimerHandler()->KillTimer(m_nTimerID);
59
60 DCHECK(pdfium::Contains((*g_global_timer_map), m_nTimerID));
61 g_global_timer_map->erase(m_nTimerID);
62 }
63
64 // static
Trigger(int32_t nTimerID)65 void GlobalTimer::Trigger(int32_t nTimerID) {
66 auto it = g_global_timer_map->find(nTimerID);
67 if (it == g_global_timer_map->end()) {
68 return;
69 }
70
71 GlobalTimer* pTimer = it->second;
72 if (pTimer->m_bProcessing)
73 return;
74
75 pTimer->m_bProcessing = true;
76 if (pTimer->m_pEmbedApp)
77 pTimer->m_pEmbedApp->TimerProc(pTimer);
78
79 // Timer proc may have destroyed timer, find it again.
80 it = g_global_timer_map->find(nTimerID);
81 if (it == g_global_timer_map->end()) {
82 return;
83 }
84
85 pTimer = it->second;
86 pTimer->m_bProcessing = false;
87 if (pTimer->IsOneShot())
88 pTimer->m_pEmbedApp->CancelProc(pTimer);
89 }
90
91 // static
Cancel(int32_t nTimerID)92 void GlobalTimer::Cancel(int32_t nTimerID) {
93 auto it = g_global_timer_map->find(nTimerID);
94 if (it == g_global_timer_map->end()) {
95 return;
96 }
97
98 GlobalTimer* pTimer = it->second;
99 pTimer->m_pEmbedApp->CancelProc(pTimer);
100 }
101
HasValidID() const102 bool GlobalTimer::HasValidID() const {
103 return m_nTimerID != CFX_Timer::HandlerIface::kInvalidTimerID;
104 }
105