Merge branch 'pingany-director_local_jstring_leak'

* pingany-director_local_jstring_leak:
  Use more conventional naming for generated Java LocalRefGuard variables
  Make more use of LocalRefGuard in Java
  fixup! Patch of http://sourceforge.net/p/swig/mailman/message/29816385
  Patch of http://sourceforge.net/p/swig/mailman/message/29816385
This commit is contained in:
William S Fulton 2014-09-27 14:33:31 +01:00
commit 0d34a0f0bf
3 changed files with 25 additions and 5 deletions

View file

@ -100,6 +100,22 @@ namespace Swig {
bool weak_global_; bool weak_global_;
}; };
/* Local JNI reference deleter */
class LocalRefGuard {
JNIEnv *jenv_;
jobject jobj_;
// non-copyable
LocalRefGuard(const LocalRefGuard &);
LocalRefGuard &operator=(const LocalRefGuard &);
public:
LocalRefGuard(JNIEnv *jenv, jobject jobj): jenv_(jenv), jobj_(jobj) {}
~LocalRefGuard() {
if (jobj_)
jenv_->DeleteLocalRef(jobj_);
}
};
/* director base class */ /* director base class */
class Director { class Director {
/* pointer to Java virtual machine */ /* pointer to Java virtual machine */
@ -152,6 +168,7 @@ namespace Swig {
JNIEnvWrapper jnienv(this) ; JNIEnvWrapper jnienv(this) ;
JNIEnv *jenv = jnienv.getJNIEnv() ; JNIEnv *jenv = jnienv.getJNIEnv() ;
jobject jobj = swig_self_.get(jenv); jobject jobj = swig_self_.get(jenv);
LocalRefGuard ref_deleter(jenv, jobj);
#if defined(DEBUG_DIRECTOR_OWNED) #if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl; std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
#endif #endif
@ -164,7 +181,6 @@ namespace Swig {
jenv->CallVoidMethod(jobj, disconn_meth); jenv->CallVoidMethod(jobj, disconn_meth);
} }
} }
jenv->DeleteLocalRef(jobj);
} }
public: public:
@ -379,6 +395,5 @@ namespace Swig {
} }
return matches; return matches;
} }
} }

View file

@ -400,11 +400,13 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
} }
%typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char * { %typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char * {
$input = 0; $input = 0;
if ($1) { if ($1) {
$input = JCALL1(NewStringUTF, jenv, (const char *)$1); $input = JCALL1(NewStringUTF, jenv, (const char *)$1);
if (!$input) return $null; if (!$input) return $null;
} }
Swig::LocalRefGuard $1_refguard(jenv, $input);
// boohoo
} }
%typemap(freearg, noblock=1) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); } %typemap(freearg, noblock=1) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); }
@ -731,6 +733,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
$input = JCALL1(NewStringUTF, jenv, (const char *)$1); $input = JCALL1(NewStringUTF, jenv, (const char *)$1);
if (!$input) return $null; if (!$input) return $null;
} }
Swig::LocalRefGuard $1_refguard(jenv, $input);
} }
%typemap(argout) char[ANY], char[] "" %typemap(argout) char[ANY], char[] ""

View file

@ -49,7 +49,8 @@ class string;
jenv->ReleaseStringUTFChars($input, $1_pstr); %} jenv->ReleaseStringUTFChars($input, $1_pstr); %}
%typemap(directorin,descriptor="Ljava/lang/String;") string %typemap(directorin,descriptor="Ljava/lang/String;") string
%{ $input = jenv->NewStringUTF($1.c_str()); %} %{ $input = jenv->NewStringUTF($1.c_str());
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(out) string %typemap(out) string
%{ $result = jenv->NewStringUTF($1.c_str()); %} %{ $result = jenv->NewStringUTF($1.c_str()); %}
@ -98,7 +99,8 @@ class string;
jenv->ReleaseStringUTFChars($input, $1_pstr); %} jenv->ReleaseStringUTFChars($input, $1_pstr); %}
%typemap(directorin,descriptor="Ljava/lang/String;") const string & %typemap(directorin,descriptor="Ljava/lang/String;") const string &
%{ $input = jenv->NewStringUTF($1.c_str()); %} %{ $input = jenv->NewStringUTF($1.c_str());
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
%typemap(out) const string & %typemap(out) const string &
%{ $result = jenv->NewStringUTF($1->c_str()); %} %{ $result = jenv->NewStringUTF($1->c_str()); %}