Commit eeb8fd7d authored by kenton@google.com's avatar kenton@google.com

Fix bug with permanent callbacks that delete themselves when run. Patch from Evan Jones.

parent 20363749
...@@ -83,5 +83,6 @@ Patch contributors: ...@@ -83,5 +83,6 @@ Patch contributors:
* Optimize Java serialization of strings so that UTF-8 encoding happens only * Optimize Java serialization of strings so that UTF-8 encoding happens only
once per string per serialization call. once per string per serialization call.
* Clean up some Java warnings. * Clean up some Java warnings.
* Fix bug with permanent callbacks that delete themselves when run.
Michael Kucharski <m.kucharski@gmail.com> Michael Kucharski <m.kucharski@gmail.com>
* Added CodedInputStream.getTotalBytesRead(). * Added CodedInputStream.getTotalBytesRead().
...@@ -843,8 +843,9 @@ class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { ...@@ -843,8 +843,9 @@ class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
~FunctionClosure0(); ~FunctionClosure0();
void Run() { void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
function_(); function_();
if (self_deleting_) delete this; if (needs_delete) delete this;
} }
private: private:
...@@ -862,8 +863,9 @@ class MethodClosure0 : public Closure { ...@@ -862,8 +863,9 @@ class MethodClosure0 : public Closure {
~MethodClosure0() {} ~MethodClosure0() {}
void Run() { void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(); (object_->*method_)();
if (self_deleting_) delete this; if (needs_delete) delete this;
} }
private: private:
...@@ -884,8 +886,9 @@ class FunctionClosure1 : public Closure { ...@@ -884,8 +886,9 @@ class FunctionClosure1 : public Closure {
~FunctionClosure1() {} ~FunctionClosure1() {}
void Run() { void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
function_(arg1_); function_(arg1_);
if (self_deleting_) delete this; if (needs_delete) delete this;
} }
private: private:
...@@ -906,8 +909,9 @@ class MethodClosure1 : public Closure { ...@@ -906,8 +909,9 @@ class MethodClosure1 : public Closure {
~MethodClosure1() {} ~MethodClosure1() {}
void Run() { void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_); (object_->*method_)(arg1_);
if (self_deleting_) delete this; if (needs_delete) delete this;
} }
private: private:
...@@ -929,8 +933,9 @@ class FunctionClosure2 : public Closure { ...@@ -929,8 +933,9 @@ class FunctionClosure2 : public Closure {
~FunctionClosure2() {} ~FunctionClosure2() {}
void Run() { void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
function_(arg1_, arg2_); function_(arg1_, arg2_);
if (self_deleting_) delete this; if (needs_delete) delete this;
} }
private: private:
...@@ -952,8 +957,9 @@ class MethodClosure2 : public Closure { ...@@ -952,8 +957,9 @@ class MethodClosure2 : public Closure {
~MethodClosure2() {} ~MethodClosure2() {}
void Run() { void Run() {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_, arg2_); (object_->*method_)(arg1_, arg2_);
if (self_deleting_) delete this; if (needs_delete) delete this;
} }
private: private:
......
...@@ -182,11 +182,17 @@ class ClosureTest : public testing::Test { ...@@ -182,11 +182,17 @@ class ClosureTest : public testing::Test {
a_ = 0; a_ = 0;
b_ = NULL; b_ = NULL;
c_.clear(); c_.clear();
permanent_closure_ = NULL;
}
void DeleteClosureInCallback() {
delete permanent_closure_;
} }
int a_; int a_;
const char* b_; const char* b_;
string c_; string c_;
Closure* permanent_closure_;
static ClosureTest* current_instance_; static ClosureTest* current_instance_;
}; };
...@@ -340,6 +346,12 @@ TEST_F(ClosureTest, TestPermanentClosureMethod2) { ...@@ -340,6 +346,12 @@ TEST_F(ClosureTest, TestPermanentClosureMethod2) {
delete closure; delete closure;
} }
TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
&ClosureTest::DeleteClosureInCallback);
permanent_closure_->Run();
}
} // anonymous namespace } // anonymous namespace
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment