From 5d2ed0326ed27f32c4a8ec5e95ec9fc57139c7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 12 Feb 2015 17:21:22 -0800 Subject: [PATCH] fix double-free in race conditions when notify() was called twice --- src/mbgl/storage/request.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mbgl/storage/request.cpp b/src/mbgl/storage/request.cpp index c1a57e725..02c2822d7 100644 --- a/src/mbgl/storage/request.cpp +++ b/src/mbgl/storage/request.cpp @@ -19,7 +19,7 @@ Request::Request(const Resource &resource_, uv_loop_t *loop, Callback callback_) // thread (the thread notify() is called from) rather than kicking back to the calling thread. if (loop) { notify_async = new uv_async_t; - notify_async->data = this; + notify_async->data = nullptr; #if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 uv_async_init(loop, notify_async, [](uv_async_t *async, int) { notifyCallback(async); }); #else @@ -57,6 +57,8 @@ Request::~Request() { void Request::notify(const std::shared_ptr &response_) { response = response_; if (notify_async) { + assert(!notify_async->data); + notify_async->data = this; uv_async_send(notify_async); } else { assert(response); @@ -70,7 +72,7 @@ void Request::cancel() { assert(notify_async); assert(!destruct_async); destruct_async = new uv_async_t; - destruct_async->data = this; + destruct_async->data = nullptr; #if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10 uv_async_init(notify_async->loop, destruct_async, [](uv_async_t *async, int) { cancelCallback(async); }); #else @@ -88,11 +90,9 @@ void Request::cancelCallback(uv_async_t *async) { // This gets called from the FileSource thread, and will only ever be invoked after cancel() was called // in the original requesting thread. void Request::destruct() { - if (notify_async) { - notify(nullptr); - } - assert(destruct_async); + assert(!destruct_async->data); + destruct_async->data = this; uv_async_send(destruct_async); }