summaryrefslogtreecommitdiff
path: root/src/node_watchdog.cc
diff options
context:
space:
mode:
authorAlexis Campailla <alexis@janeasystems.com>2013-12-17 07:43:38 -0800
committerTimothy J Fontaine <tjfontaine@gmail.com>2013-12-18 15:16:36 -0800
commitcdc038ceb60cbdd14e98b69e5afc0671ff07c6fc (patch)
tree0a716a1d3de0a7e129beee6b3e218c0126977dc3 /src/node_watchdog.cc
parent95ee84fabe0b028ef964cc1032cd56a6cf89cb0e (diff)
downloadandroid-node-v8-cdc038ceb60cbdd14e98b69e5afc0671ff07c6fc.tar.gz
android-node-v8-cdc038ceb60cbdd14e98b69e5afc0671ff07c6fc.tar.bz2
android-node-v8-cdc038ceb60cbdd14e98b69e5afc0671ff07c6fc.zip
vm: fix race condition in timeout
Eliminate a race condition between uv_async_send and the closing of the corresponding handle. Also made errors in Watchdog constructor call abort() Fixes #6088
Diffstat (limited to 'src/node_watchdog.cc')
-rw-r--r--src/node_watchdog.cc39
1 files changed, 16 insertions, 23 deletions
diff --git a/src/node_watchdog.cc b/src/node_watchdog.cc
index 32c36ce1b5..d5ad88f63b 100644
--- a/src/node_watchdog.cc
+++ b/src/node_watchdog.cc
@@ -20,6 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "node_watchdog.h"
+#include "util.h"
#include <assert.h>
namespace node {
@@ -27,27 +28,21 @@ namespace node {
using v8::V8;
-Watchdog::Watchdog(uint64_t ms) : thread_created_(false), destroyed_(false) {
+Watchdog::Watchdog(uint64_t ms) : destroyed_(false) {
loop_ = uv_loop_new();
- if (!loop_)
- return;
+ CHECK(loop_);
int rc = uv_async_init(loop_, &async_, &Watchdog::Async);
- assert(rc == 0);
+ CHECK(0 == rc); // NOLINT(readability/check)
rc = uv_timer_init(loop_, &timer_);
- assert(rc == 0);
+ CHECK(0 == rc); // NOLINT(readability/check)
rc = uv_timer_start(&timer_, &Watchdog::Timer, ms, 0);
- if (rc) {
- return;
- }
+ CHECK(0 == rc); // NOLINT(readability/check)
rc = uv_thread_create(&thread_, &Watchdog::Run, this);
- if (rc) {
- return;
- }
- thread_created_ = true;
+ CHECK(0 == rc); // NOLINT(readability/check)
}
@@ -66,14 +61,15 @@ void Watchdog::Destroy() {
return;
}
- if (thread_created_) {
- uv_async_send(&async_);
- uv_thread_join(&thread_);
- }
+ uv_async_send(&async_);
+ uv_thread_join(&thread_);
- if (loop_) {
- uv_loop_delete(loop_);
- }
+ uv_close(reinterpret_cast<uv_handle_t*>(&async_), NULL);
+
+ // UV_RUN_DEFAULT so that libuv has a chance to clean up.
+ uv_run(loop_, UV_RUN_DEFAULT);
+
+ uv_loop_delete(loop_);
destroyed_ = true;
}
@@ -86,11 +82,8 @@ void Watchdog::Run(void* arg) {
uv_run(wd->loop_, UV_RUN_ONCE);
// Loop ref count reaches zero when both handles are closed.
- uv_close(reinterpret_cast<uv_handle_t*>(&wd->async_), NULL);
+ // Close the timer handle on this side and let Destroy() close async_
uv_close(reinterpret_cast<uv_handle_t*>(&wd->timer_), NULL);
-
- // UV_RUN_DEFAULT so that libuv has a chance to clean up.
- uv_run(wd->loop_, UV_RUN_DEFAULT);
}