Created
October 25, 2016 21:52
-
-
Save trevnorris/0e130c6c8f0aa1336725e8e41c38cf14 to your computer and use it in GitHub Desktop.
Fix when the reference of a TLSWrap instance is kept, but the StreamBase stream_ is free'd.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/stream_base.h b/src/stream_base.h | |
index faddee8..3592975 100644 | |
--- a/src/stream_base.h | |
+++ b/src/stream_base.h | |
@@ -146,10 +146,14 @@ class StreamResource { | |
const uv_buf_t* buf, | |
uv_handle_type pending, | |
void* ctx); | |
+ typedef void (*DestructCb)(void* ctx); | |
StreamResource() : bytes_read_(0) { | |
} | |
- virtual ~StreamResource() = default; | |
+ virtual ~StreamResource() { | |
+ if (!destruct_cb_.is_empty()) | |
+ destruct_cb_.fn(destruct_cb_.ctx); | |
+ } | |
virtual int DoShutdown(ShutdownWrap* req_wrap) = 0; | |
virtual int DoTryWrite(uv_buf_t** bufs, size_t* count); | |
@@ -186,15 +190,18 @@ class StreamResource { | |
inline void set_alloc_cb(Callback<AllocCb> c) { alloc_cb_ = c; } | |
inline void set_read_cb(Callback<ReadCb> c) { read_cb_ = c; } | |
+ inline void set_destruct_cb(Callback<DestructCb> c) { destruct_cb_ = c; } | |
inline Callback<AfterWriteCb> after_write_cb() { return after_write_cb_; } | |
inline Callback<AllocCb> alloc_cb() { return alloc_cb_; } | |
inline Callback<ReadCb> read_cb() { return read_cb_; } | |
+ inline Callback<DestructCb> destruct_cb() { return destruct_cb_; } | |
private: | |
Callback<AfterWriteCb> after_write_cb_; | |
Callback<AllocCb> alloc_cb_; | |
Callback<ReadCb> read_cb_; | |
+ Callback<DestructCb> destruct_cb_; | |
uint64_t bytes_read_; | |
friend class StreamBase; | |
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc | |
index d1b1aec..39642cf 100644 | |
--- a/src/tls_wrap.cc | |
+++ b/src/tls_wrap.cc | |
@@ -64,6 +64,7 @@ TLSWrap::TLSWrap(Environment* env, | |
stream_->set_after_write_cb({ OnAfterWriteImpl, this }); | |
stream_->set_alloc_cb({ OnAllocImpl, this }); | |
stream_->set_read_cb({ OnReadImpl, this }); | |
+ stream_->set_destruct_cb({ OnDestructImpl, this }); | |
set_alloc_cb({ OnAllocSelf, this }); | |
set_read_cb({ OnReadSelf, this }); | |
@@ -522,7 +523,7 @@ int TLSWrap::GetFD() { | |
bool TLSWrap::IsAlive() { | |
- return ssl_ != nullptr && stream_->IsAlive(); | |
+ return ssl_ != nullptr && stream_ != nullptr && stream_->IsAlive(); | |
} | |
@@ -660,6 +661,12 @@ void TLSWrap::OnReadImpl(ssize_t nread, | |
} | |
+void TLSWrap::OnDestructImpl(void* ctx) { | |
+ TLSWrap* wrap = static_cast<TLSWrap*>(ctx); | |
+ wrap->clear_stream(); | |
+} | |
+ | |
+ | |
void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) { | |
buf->base = static_cast<char*>(node::Malloc(suggested_size)); | |
CHECK_NE(buf->base, nullptr); | |
diff --git a/src/tls_wrap.h b/src/tls_wrap.h | |
index f390c9f..fbf664e 100644 | |
--- a/src/tls_wrap.h | |
+++ b/src/tls_wrap.h | |
@@ -54,6 +54,8 @@ class TLSWrap : public AsyncWrap, | |
size_t self_size() const override { return sizeof(*this); } | |
+ void clear_stream() { stream_ = nullptr; } | |
+ | |
protected: | |
static const int kClearOutChunkSize = 16384; | |
@@ -121,6 +123,7 @@ class TLSWrap : public AsyncWrap, | |
const uv_buf_t* buf, | |
uv_handle_type pending, | |
void* ctx); | |
+ static void OnDestructImpl(void* ctx); | |
void DoRead(ssize_t nread, const uv_buf_t* buf, uv_handle_type pending); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment