1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## bts770690_java_jni_thread_detach.dpatch by Florian Forster <octo@google.com>
3 ##
4 ## DP: java plugin: Make sure cjni_thread_detach() is called on all paths.
5 ## DP: Each call to cjni_thread_attach() much be accompanied by a call to
6 ## DP: cjni_thread_detach(). Some error handling cases were missing the call,
7 ## DP: potentially locking the plugin up.
8 ## DP:
9 ## DP: Also ensure that cjni_thread_detach() does not hide the status of other
10 ## DP: operations.
11 ## DP:
12 ## DP: Upstream commit:
13 ## DP: https://github.com/collectd/collectd/commit/513a5ca
15 @DPATCH@
17 diff a/src/java.c b/src/java.c
18 --- a/src/java.c
19 +++ b/src/java.c
20 @@ -2115,7 +2115,7 @@ static int cjni_thread_detach (void) /* {{{ */
21 cjni_env->jvm_env = NULL;
23 return (0);
24 -} /* }}} JNIEnv *cjni_thread_attach */
25 +} /* }}} int cjni_thread_detach */
27 static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */
28 {
29 @@ -2468,7 +2468,6 @@ static int cjni_read (user_data_t *ud) /* {{{ */
30 {
31 JNIEnv *jvm_env;
32 cjni_callback_info_t *cbi;
33 - int status;
34 int ret_status;
36 if (jvm == NULL)
37 @@ -2492,13 +2491,7 @@ static int cjni_read (user_data_t *ud) /* {{{ */
38 ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object,
39 cbi->method);
41 - status = cjni_thread_detach ();
42 - if (status != 0)
43 - {
44 - ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
45 - return (-1);
46 - }
47 -
48 + cjni_thread_detach ();
49 return (ret_status);
50 } /* }}} int cjni_read */
52 @@ -2509,7 +2502,6 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
53 JNIEnv *jvm_env;
54 cjni_callback_info_t *cbi;
55 jobject vl_java;
56 - int status;
57 int ret_status;
59 if (jvm == NULL)
60 @@ -2534,6 +2526,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
61 if (vl_java == NULL)
62 {
63 ERROR ("java plugin: cjni_write: ctoj_value_list failed.");
64 + cjni_thread_detach ();
65 return (-1);
66 }
68 @@ -2542,13 +2535,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
70 (*jvm_env)->DeleteLocalRef (jvm_env, vl_java);
72 - status = cjni_thread_detach ();
73 - if (status != 0)
74 - {
75 - ERROR ("java plugin: cjni_write: cjni_thread_detach failed.");
76 - return (-1);
77 - }
78 -
79 + cjni_thread_detach ();
80 return (ret_status);
81 } /* }}} int cjni_write */
83 @@ -2560,7 +2547,6 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
84 cjni_callback_info_t *cbi;
85 jobject o_timeout;
86 jobject o_identifier;
87 - int status;
88 int ret_status;
90 if (jvm == NULL)
91 @@ -2587,6 +2573,7 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
92 {
93 ERROR ("java plugin: cjni_flush: Converting double "
94 "to Number object failed.");
95 + cjni_thread_detach ();
96 return (-1);
97 }
99 @@ -2598,6 +2585,7 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
100 {
101 (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
102 ERROR ("java plugin: cjni_flush: NewStringUTF failed.");
103 + cjni_thread_detach ();
104 return (-1);
105 }
106 }
107 @@ -2608,13 +2596,7 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
108 (*jvm_env)->DeleteLocalRef (jvm_env, o_identifier);
109 (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
111 - status = cjni_thread_detach ();
112 - if (status != 0)
113 - {
114 - ERROR ("java plugin: cjni_flush: cjni_thread_detach failed.");
115 - return (-1);
116 - }
117 -
118 + cjni_thread_detach ();
119 return (ret_status);
120 } /* }}} int cjni_flush */
122 @@ -2640,7 +2622,10 @@ static void cjni_log (int severity, const char *message, /* {{{ */
124 o_message = (*jvm_env)->NewStringUTF (jvm_env, message);
125 if (o_message == NULL)
126 + {
127 + cjni_thread_detach ();
128 return;
129 + }
131 (*jvm_env)->CallVoidMethod (jvm_env,
132 cbi->object, cbi->method, (jint) severity, o_message);
133 @@ -2658,7 +2643,6 @@ static int cjni_notification (const notification_t *n, /* {{{ */
134 JNIEnv *jvm_env;
135 cjni_callback_info_t *cbi;
136 jobject o_notification;
137 - int status;
138 int ret_status;
140 if (jvm == NULL)
141 @@ -2683,6 +2667,7 @@ static int cjni_notification (const notification_t *n, /* {{{ */
142 if (o_notification == NULL)
143 {
144 ERROR ("java plugin: cjni_notification: ctoj_notification failed.");
145 + cjni_thread_detach ();
146 return (-1);
147 }
149 @@ -2691,13 +2676,7 @@ static int cjni_notification (const notification_t *n, /* {{{ */
151 (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
153 - status = cjni_thread_detach ();
154 - if (status != 0)
155 - {
156 - ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
157 - return (-1);
158 - }
159 -
160 + cjni_thread_detach ();
161 return (ret_status);
162 } /* }}} int cjni_notification */
164 @@ -2725,24 +2704,20 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */
165 (*jvm_env)->DeleteLocalRef (jvm_env, cbi_ret->object); \
166 } \
167 free (cbi_ret); \
168 - if (jvm_env != NULL) { \
169 - if (o_ci != NULL) \
170 - (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \
171 - cjni_thread_detach (); \
172 - } \
173 + if (o_ci != NULL) \
174 + (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \
175 + cjni_thread_detach (); \
176 return (status)
178 if (jvm == NULL)
179 {
180 ERROR ("java plugin: cjni_read: jvm == NULL");
181 - BAIL_OUT (-1);
182 + return (-1);
183 }
185 jvm_env = cjni_thread_attach ();
186 if (jvm_env == NULL)
187 - {
188 - BAIL_OUT (-1);
189 - }
190 + return (-1);
192 /* Find out whether to create a match or a target. */
193 if (strcasecmp ("Match", ci->key) == 0)
194 @@ -2936,10 +2911,7 @@ static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */
195 }
196 } /* if (cbi->type == CB_TYPE_TARGET) */
198 - status = cjni_thread_detach ();
199 - if (status != 0)
200 - ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
201 -
202 + cjni_thread_detach ();
203 return (ret_status);
204 } /* }}} int cjni_match_target_invoke */