mirror of
https://github.com/servo/servo.git
synced 2025-07-03 05:23:38 +01:00
Use Rust stdlib threads for android logging.
This commit is contained in:
parent
38d3f59170
commit
f402dd9ecf
1 changed files with 48 additions and 68 deletions
|
@ -10,14 +10,14 @@ use gl_glue;
|
||||||
use jni::{JNIEnv, JavaVM};
|
use jni::{JNIEnv, JavaVM};
|
||||||
use jni::objects::{GlobalRef, JClass, JObject, JString, JValue};
|
use jni::objects::{GlobalRef, JClass, JObject, JString, JValue};
|
||||||
use jni::sys::{jboolean, jfloat, jint, jstring, JNI_TRUE};
|
use jni::sys::{jboolean, jfloat, jint, jstring, JNI_TRUE};
|
||||||
|
use libc::{pipe, dup2, read};
|
||||||
use log::Level;
|
use log::Level;
|
||||||
use std;
|
use std;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem;
|
use std::os::raw::{c_char, c_int, c_void};
|
||||||
use std::os::raw::{c_char, c_int, c_long, c_void};
|
|
||||||
use std::ptr;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
struct HostCallbacks {
|
struct HostCallbacks {
|
||||||
callbacks: GlobalRef,
|
callbacks: GlobalRef,
|
||||||
|
@ -447,91 +447,71 @@ fn initialize_android_glue(env: &JNIEnv, activity: JObject) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type pthread_t = c_long;
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type pthread_mutexattr_t = c_long;
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type pthread_attr_t = c_void; // FIXME: wrong
|
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn pipe(_: *mut c_int) -> c_int;
|
|
||||||
fn dup2(fildes: c_int, fildes2: c_int) -> c_int;
|
|
||||||
fn read(fd: c_int, buf: *mut c_void, count: usize) -> isize;
|
|
||||||
fn pthread_create(_: *mut pthread_t, _: *const pthread_attr_t,
|
|
||||||
_: extern fn(*mut c_void) -> *mut c_void, _: *mut c_void) -> c_int;
|
|
||||||
fn pthread_detach(thread: pthread_t) -> c_int;
|
|
||||||
|
|
||||||
pub fn __android_log_write(prio: c_int, tag: *const c_char, text: *const c_char) -> c_int;
|
pub fn __android_log_write(prio: c_int, tag: *const c_char, text: *const c_char) -> c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn redirect_stdout_to_logcat() {
|
fn redirect_stdout_to_logcat() {
|
||||||
// The first step is to redirect stdout and stderr to the logs.
|
// The first step is to redirect stdout and stderr to the logs.
|
||||||
|
// We redirect stdout and stderr to a custom descriptor.
|
||||||
|
let mut pfd: [c_int; 2] = [0, 0];
|
||||||
unsafe {
|
unsafe {
|
||||||
// We redirect stdout and stderr to a custom descriptor.
|
|
||||||
let mut pfd: [c_int; 2] = [0, 0];
|
|
||||||
pipe(pfd.as_mut_ptr());
|
pipe(pfd.as_mut_ptr());
|
||||||
dup2(pfd[1], 1);
|
dup2(pfd[1], 1);
|
||||||
dup2(pfd[1], 2);
|
dup2(pfd[1], 2);
|
||||||
|
}
|
||||||
|
|
||||||
// Then we spawn a thread whose only job is to read from the other side of the
|
let descriptor = pfd[0];
|
||||||
// pipe and redirect to the logs.
|
|
||||||
extern fn logging_thread(descriptor: *mut c_void) -> *mut c_void {
|
|
||||||
unsafe {
|
|
||||||
let descriptor = descriptor as usize as c_int;
|
|
||||||
let mut buf: Vec<c_char> = Vec::with_capacity(512);
|
|
||||||
let mut cursor = 0_usize;
|
|
||||||
|
|
||||||
// TODO: shouldn't use Rust stdlib
|
// Then we spawn a thread whose only job is to read from the other side of the
|
||||||
let tag = CString::new("simpleservo").unwrap();
|
// pipe and redirect to the logs.
|
||||||
let tag = tag.as_ptr();
|
let _detached = thread::spawn(move || {
|
||||||
|
unsafe {
|
||||||
|
let mut buf: Vec<c_char> = Vec::with_capacity(512);
|
||||||
|
let mut cursor = 0_usize;
|
||||||
|
|
||||||
loop {
|
// TODO: shouldn't use Rust stdlib
|
||||||
let result = read(descriptor, buf.as_mut_ptr().offset(cursor as isize) as *mut _,
|
let tag = CString::new("simpleservo").unwrap();
|
||||||
buf.capacity() - 1 - cursor);
|
let tag = tag.as_ptr();
|
||||||
|
|
||||||
let len = if result == 0 {
|
loop {
|
||||||
return ptr::null_mut();
|
let result = read(descriptor, buf.as_mut_ptr().offset(cursor as isize) as *mut _,
|
||||||
} else if result < 0 {
|
buf.capacity() - 1 - cursor);
|
||||||
return ptr::null_mut(); /* TODO: report problem */
|
|
||||||
} else {
|
|
||||||
result as usize + cursor
|
|
||||||
};
|
|
||||||
|
|
||||||
buf.set_len(len);
|
let len = if result == 0 {
|
||||||
|
return;
|
||||||
|
} else if result < 0 {
|
||||||
|
return; /* TODO: report problem */
|
||||||
|
} else {
|
||||||
|
result as usize + cursor
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(last_newline_pos) = buf.iter().rposition(|&c| c == b'\n' as c_char) {
|
buf.set_len(len);
|
||||||
buf[last_newline_pos] = b'\0' as c_char;
|
|
||||||
__android_log_write(3, tag, buf.as_ptr());
|
if let Some(last_newline_pos) = buf.iter().rposition(|&c| c == b'\n' as c_char) {
|
||||||
if last_newline_pos < buf.len() - 1 {
|
buf[last_newline_pos] = b'\0' as c_char;
|
||||||
let last_newline_pos = last_newline_pos + 1;
|
__android_log_write(3, tag, buf.as_ptr());
|
||||||
cursor = buf.len() - last_newline_pos;
|
if last_newline_pos < buf.len() - 1 {
|
||||||
debug_assert!(cursor < buf.capacity());
|
let last_newline_pos = last_newline_pos + 1;
|
||||||
for j in 0..cursor as usize {
|
cursor = buf.len() - last_newline_pos;
|
||||||
buf[j] = buf[last_newline_pos + j];
|
debug_assert!(cursor < buf.capacity());
|
||||||
}
|
for j in 0..cursor as usize {
|
||||||
buf[cursor] = b'\0' as c_char;
|
buf[j] = buf[last_newline_pos + j];
|
||||||
buf.set_len(cursor + 1);
|
|
||||||
} else {
|
|
||||||
cursor = 0;
|
|
||||||
}
|
}
|
||||||
|
buf[cursor] = b'\0' as c_char;
|
||||||
|
buf.set_len(cursor + 1);
|
||||||
} else {
|
} else {
|
||||||
cursor = buf.len();
|
|
||||||
}
|
|
||||||
if cursor == buf.capacity() - 1 {
|
|
||||||
__android_log_write(3, tag, buf.as_ptr());
|
|
||||||
buf.set_len(0);
|
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cursor = buf.len();
|
||||||
|
}
|
||||||
|
if cursor == buf.capacity() - 1 {
|
||||||
|
__android_log_write(3, tag, buf.as_ptr());
|
||||||
|
buf.set_len(0);
|
||||||
|
cursor = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
let mut thread = mem::uninitialized();
|
|
||||||
let result = pthread_create(&mut thread, ptr::null(), logging_thread,
|
|
||||||
pfd[0] as usize as *mut c_void);
|
|
||||||
assert_eq!(result, 0);
|
|
||||||
let result = pthread_detach(thread);
|
|
||||||
assert_eq!(result, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue