@@ -161,39 +161,39 @@ Php::Value Context::evaluate(Php::Parameters ¶ms)
161
161
v8::Local<v8::String> source (v8::String::NewFromUtf8 (Isolate::get (), params[0 ]));
162
162
v8::Local<v8::Script> script (v8::Script::Compile (source));
163
163
164
- // we create an atomic_flag and condition_variable so we can use wait_until on
164
+ // we create a mutex and a condition_variable so we can use wait_until on
165
165
// another thread which we can stop from our main thread. We use this to maybe abort
166
166
// execution of javascript after a certain amount of time.
167
- std::atomic_flag busy = ATOMIC_FLAG_INIT;
167
+ bool busy = true ;
168
+ std::mutex mutex;
168
169
std::condition_variable condition;
169
170
170
- // we are not yet finished
171
- busy.test_and_set ();
172
-
173
171
// create a temporary thread which will mostly just sleep, but kill the script after a certain time period
174
172
std::thread aborter;
175
173
176
174
// only create this thread if our timeout is higher than 0
177
- if (timeout > 0 ) aborter = std::move (std::thread ([this , &busy, &condition, timeout]() {
178
-
179
- // create a lock
180
- std::mutex mutex;
181
- std::unique_lock<std::mutex> lock (mutex);
175
+ if (timeout > 0 ) aborter = std::move (std::thread ([this , &busy, &mutex, &condition, timeout]() {
182
176
183
177
// time we want to terminate execution
184
178
auto end = std::chrono::system_clock::now () + std::chrono::seconds (timeout);
185
179
186
180
// has the execution timed out?
187
181
std::cv_status status = std::cv_status::no_timeout;
188
182
183
+ // obtain a lock around busy
184
+ std::unique_lock<std::mutex> lock (mutex);
185
+
189
186
// check to prevent a spurious wakeup from removing the timeout
190
187
// additionally, the main thread might have finished before we even start
191
- while (busy. test_and_set () && status != std::cv_status::timeout)
188
+ while (busy && status != std::cv_status::timeout)
192
189
{
193
190
// we wait until some point in the future (this unlocks the lock until it returns)
194
191
status = condition.wait_until (lock, end);
195
192
}
196
193
194
+ // unlock the lock
195
+ lock.unlock ();
196
+
197
197
// in case we timeout we must terminate execution
198
198
if (status != std::cv_status::timeout) return ;
199
199
@@ -207,8 +207,14 @@ Php::Value Context::evaluate(Php::Parameters ¶ms)
207
207
// execute the script
208
208
v8::Local<v8::Value> result (script->Run ());
209
209
210
+ // obtain a lock around busy
211
+ std::unique_lock<std::mutex> lock (mutex);
212
+
210
213
// we are no longer busy
211
- busy.clear ();
214
+ busy = false ;
215
+
216
+ // unlock the lock
217
+ lock.unlock ();
212
218
213
219
// notify the aborter thread
214
220
condition.notify_one ();
0 commit comments