Skip to content

Commit ddaa808

Browse files
committed
Fix memory access violation when using decoder threaded
1 parent dc6c5df commit ddaa808

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

rust/src/lame/decoder.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ struct DecoderWrapper {
1313
}
1414

1515
#[no_mangle]
16-
pub extern "C" fn Java_de_maxhenkel_lame4j_Mp3Decoder_createDecoder(env: JNIEnv<'static>, _class: JClass) -> jlong {
16+
pub extern "C" fn Java_de_maxhenkel_lame4j_Mp3Decoder_createDecoder(_env: JNIEnv, _class: JClass) -> jlong {
1717
let stream_wrapper = JavaInputStream {
18-
env,
18+
env: None,
1919
input_stream: None,
2020
};
2121

@@ -41,8 +41,18 @@ pub extern "C" fn Java_de_maxhenkel_lame4j_Mp3Decoder_decodeNextFrame<'a>(mut en
4141
};
4242

4343
decoder_wrapper.decoder.reader_mut().input_stream = Some(stream);
44+
decoder_wrapper.decoder.reader_mut().env = Some(env);
4445

45-
let frame = match decoder_wrapper.decoder.next_frame() {
46+
let decode_result = decoder_wrapper.decoder.next_frame();
47+
48+
let mut env = match decoder_wrapper.decoder.reader_mut().env.take() {
49+
Some(env) => env,
50+
None => {
51+
panic!("Cannot get Java environment");
52+
}
53+
};
54+
55+
let frame = match decode_result {
4656
Ok(frame) => frame,
4757
Err(Error::Eof) => {
4858
return JShortArray::from(JObject::null());
@@ -131,7 +141,7 @@ pub extern "C" fn Java_de_maxhenkel_lame4j_Mp3Decoder_destroyDecoder(mut env: JN
131141
}
132142

133143
struct JavaInputStream {
134-
env: JNIEnv<'static>,
144+
env: Option<JNIEnv<'static>>,
135145
input_stream: Option<JObject<'static>>,
136146
}
137147

@@ -141,9 +151,17 @@ impl Read for JavaInputStream {
141151
return Ok(0);
142152
}
143153

144-
let byte_array = match self.env.new_byte_array(buf.len() as i32) {
154+
let mut env = match self.env.take() {
155+
Some(env) => env,
156+
None => {
157+
return Err(std::io::Error::new(ErrorKind::Other, "Environment unavailable"));
158+
}
159+
};
160+
161+
let byte_array = match env.new_byte_array(buf.len() as i32) {
145162
Ok(byte_array) => byte_array,
146163
Err(e) => {
164+
self.env = Some(env);
147165
return Err(std::io::Error::new(ErrorKind::Other, e));
148166
}
149167
};
@@ -154,36 +172,43 @@ impl Read for JavaInputStream {
154172
let input_stream = match &self.input_stream {
155173
Some(input_stream) => input_stream,
156174
None => {
175+
self.env = Some(env);
157176
return Err(std::io::Error::new(ErrorKind::Other, "Input stream unavailable"));
158177
}
159178
};
160179

161-
let value = match self.env.call_method(input_stream, "read", "([B)I", &[jvalue]) {
180+
let value = match env.call_method(input_stream, "read", "([B)I", &[jvalue]) {
162181
Ok(value) => value,
163182
Err(e) => {
183+
self.env = Some(env);
164184
return Err(std::io::Error::new(ErrorKind::Other, e));
165185
}
166186
};
167187
let num_bytes_read = match value.i() {
168188
Ok(num_bytes_read) => num_bytes_read,
169189
Err(e) => {
190+
self.env = Some(env);
170191
return Err(std::io::Error::new(ErrorKind::Other, e));
171192
}
172193
};
173194

174195
if num_bytes_read <= 0 {
196+
self.env = Some(env);
175197
return Ok(0);
176198
}
177199

178-
let vec = match self.env.convert_byte_array(byte_array) {
200+
let vec = match env.convert_byte_array(byte_array) {
179201
Ok(vec) => vec,
180202
Err(e) => {
203+
self.env = Some(env);
181204
return Err(std::io::Error::new(ErrorKind::Other, e));
182205
}
183206
};
184207

185208
buf[..num_bytes_read as usize].copy_from_slice(&vec[..num_bytes_read as usize]);
186209

210+
self.env = Some(env);
211+
187212
return Ok(num_bytes_read as usize);
188213
}
189214
}

0 commit comments

Comments
 (0)