In case of delta editor, commit callback is provided at the time of the editor
creation and used during the close_edit() call. For that there is a need to
keep a global reference to the underlying java object so that it does not get
GCed meanwhile.

Attached please find the patch that adds such capabilities.

Thank you,

Vladimir

[[[
JavaHL: Support keeping global reference to the callback java object for cases
when callback is being used across method calls

[ in subversion/bindings/javahl/native ]

* CommitCallback.cpp,
  CommitCallback.h
  (CommitCallback, ~CommitCallback): Add handling of additional parameter and
    state when requesting a global reference to be kept
]]]
Index: subversion/bindings/javahl/native/CommitCallback.h
===================================================================
--- subversion/bindings/javahl/native/CommitCallback.h  (revision 1353380)
+++ subversion/bindings/javahl/native/CommitCallback.h  (working copy)
@@ -37,7 +37,7 @@
 class CommitCallback
 {
  public:
-  CommitCallback(jobject jcallback);
+  CommitCallback(jobject jcallback, bool keepGlobalRef = false);
   ~CommitCallback();
 
   static svn_error_t *callback(const svn_commit_info_t *commit_info,
@@ -49,9 +49,14 @@
 
  private:
   /**
-   * This a local reference to the Java object.
+   * This a reference to the Java object.
    */
   jobject m_callback;
+
+  /**
+   * Is the reference we are keeping global or local
+   */
+  bool globalRef;
 };
 
 #endif  // COMMITCALLBACK_H
Index: subversion/bindings/javahl/native/CommitCallback.cpp
===================================================================
--- subversion/bindings/javahl/native/CommitCallback.cpp        (revision 
1353380)
+++ subversion/bindings/javahl/native/CommitCallback.cpp        (working copy)
@@ -36,9 +36,24 @@
  * Create a CommitCallback object
  * @param jcallback the Java callback object.
  */
-CommitCallback::CommitCallback(jobject jcallback)
+CommitCallback::CommitCallback(jobject jcallback, bool keepGlobalRef)
 {
-  m_callback = jcallback;
+  globalRef = false;
+
+  if(!keepGlobalRef)
+    {
+      m_callback = jcallback;
+      return;
+    }
+
+  JNIEnv *env = JNIUtil::getEnv();
+  m_callback = env->NewGlobalRef(jcallback);
+  if (JNIUtil::isJavaExceptionThrown())
+    {
+      return;
+    }
+
+  globalRef = true;
 }
 
 /**
@@ -46,9 +61,13 @@
  */
 CommitCallback::~CommitCallback()
 {
-  // The m_callback does not need to be destroyed because it is the
-  // passed in parameter to the Java SVNClientInterface.logMessages
-  // method.
+  // If we are holding global reference to the callback object
+  // we need to destroy it
+  if(globalRef && m_callback != NULL)
+    {
+      JNIEnv *env = JNIUtil::getEnv();
+      env->DeleteGlobalRef(m_callback);
+    }
 }
 
 svn_error_t *

Reply via email to