Commits

Anonymous committed 87b5fa1

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

  • Participants
  • Parent commits bd8557c

Comments (0)

Files changed (3)

File CONTRIBUTORS.txt

     * Optimize Java serialization of strings so that UTF-8 encoding happens only
       once per string per serialization call.
     * Clean up some Java warnings.
+    * Fix bug with permanent callbacks that delete themselves when run.
   Michael Kucharski <m.kucharski@gmail.com>
     * Added CodedInputStream.getTotalBytesRead().

File src/google/protobuf/stubs/common.h

   ~FunctionClosure0();
 
   void Run() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
     function_();
-    if (self_deleting_) delete this;
+    if (needs_delete) delete this;
   }
 
  private:
   ~MethodClosure0() {}
 
   void Run() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
     (object_->*method_)();
-    if (self_deleting_) delete this;
+    if (needs_delete) delete this;
   }
 
  private:
   ~FunctionClosure1() {}
 
   void Run() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
     function_(arg1_);
-    if (self_deleting_) delete this;
+    if (needs_delete) delete this;
   }
 
  private:
   ~MethodClosure1() {}
 
   void Run() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
     (object_->*method_)(arg1_);
-    if (self_deleting_) delete this;
+    if (needs_delete) delete this;
   }
 
  private:
   ~FunctionClosure2() {}
 
   void Run() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
     function_(arg1_, arg2_);
-    if (self_deleting_) delete this;
+    if (needs_delete) delete this;
   }
 
  private:
   ~MethodClosure2() {}
 
   void Run() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
     (object_->*method_)(arg1_, arg2_);
-    if (self_deleting_) delete this;
+    if (needs_delete) delete this;
   }
 
  private:

File src/google/protobuf/stubs/common_unittest.cc

     a_ = 0;
     b_ = NULL;
     c_.clear();
+    permanent_closure_ = NULL;
+  }
+
+  void DeleteClosureInCallback() {
+    delete permanent_closure_;
   }
 
   int a_;
   const char* b_;
   string c_;
+  Closure* permanent_closure_;
 
   static ClosureTest* current_instance_;
 };
   delete closure;
 }
 
+TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
+  permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
+      &ClosureTest::DeleteClosureInCallback);
+  permanent_closure_->Run();
+}
+
 }  // anonymous namespace
 }  // namespace protobuf
 }  // namespace google