Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/Timeout.cpp

Issue 29370876: Issue #4692, #3595 - Stop sleeping in the implementation of `SetTimeout`
Patch Set: Created Jan. 9, 2017, 1:22 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/Timeout.h ('k') | test/PausePoint.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 Eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "JsEngineInternal.h"
19 #include "JsEngineTransition.h"
20 #include "Scheduler.h"
21 #include "Timeout.h"
22 #include "Utils.h"
23
24 namespace
25 {
26 class TimeoutTask
27 : public TaskFunctionInterface
28 {
29 typedef int64_t delayType; // return type of v8::Value::GetInteger()
30 /**
31 * shared_ptr ensures the engine remains in existence
32 * while we're waiting for the task to complete.
33 * The scheduler ought to undertake this responsibility,
34 * but until then we must do it ourselves.
35 */
36 JsEngineInternal* engine;
37 V8PersistentNG<v8::Function> function;
38 delayType delay;
39 PersistentValueArray functionArguments;
40 DelayedExecutor executor;
41
42 void body()
43 {
44 V8ExecutionScope sentry(engine);
45 auto isolate = engine->GetIsolate();
46 engine->ApplyFunction(function.Get(isolate), functionArguments.GetAsLocal( isolate));
47 }
48
49 public:
50 TimeoutTask(
51 JsEngineInternal *engine,
52 V8PersistentNG<v8::Function> function,
53 delayType delay,
54 PersistentValueArray functionArguments
55 ) :
56 engine(engine),
57 function(function),
58 delay(delay),
59 functionArguments(std::move(functionArguments)),
60 executor([this]() { body(); })
61 {}
62
63 void operator()() override
64 {
65 executor.RunWithDelay(std::chrono::milliseconds(delay));
66 }
67
68 void Interrupt() override
69 {
70 executor.ForestallExecution();
71 }
72 };
73 }
74
75 /**
76 * Callback function registered to v8 to implement `SetTimeout`
77 *
78 * Note that this implementation does not support the "evaluate code" version
79 * of `SetTimeout`, only the "apply function" version.
80 *
81 * \par Reference
82 * https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
83 */
84 v8::Handle<v8::Value> CallbackForSetTimeout(const v8::Arguments& arguments)
85 {
86 auto engine = JsEngineInternal::ExtractEngine(arguments);
87 try
88 {
89 if (arguments.Length() < 2)
90 {
91 throw std::runtime_error("setTimeout: must have at least 2 arguments");
92 }
93 if (!arguments[0]->IsFunction())
94 {
95 throw std::runtime_error("setTimeout: argument 1 must be a function");
96 }
97 auto isolate = engine->GetIsolate();
98 size_t n = arguments.Length() - 2;
99 PersistentValueArray functionArguments(n);
100 for (size_t i = 0; i < n; i++)
101 {
102 functionArguments[i] = V8PersistentNG<v8::Value>(isolate, arguments[i + 2] );
103 }
104 /*
105 * Run the task
106 */
107 auto task(std::make_shared<TimeoutTask>(engine,
108 V8PersistentNG<v8::Function>(isolate, v8::Local<v8::Function>::Cast(argume nts[0])),
109 arguments[1]->IntegerValue(), std::move(functionArguments)));
110 engine->ScheduleTask(std::move(task), ImmediateSingleUseThread);
111 // We should actually return the timer ID here, which could be
112 // used via clearTimeout(). But since we don't seem to need
113 // clearTimeout(), we can save that for later.
114 return v8::Undefined();
115 }
116 catch (const std::exception& e)
117 {
118 return v8::ThrowException(engine->ToV8String(e.what()));
119 }
120 }
OLDNEW
« no previous file with comments | « src/Timeout.h ('k') | test/PausePoint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld