Count threads at shutdown and warn if not all finished

This commit is contained in:
Paul Rouget 2018-11-02 10:40:59 +01:00
parent cc0ac89e1a
commit 2718675191
6 changed files with 67 additions and 1 deletions

1
Cargo.lock generated
View file

@ -3210,6 +3210,7 @@ version = "0.0.1"
dependencies = [
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -226,6 +226,9 @@ pub struct Opts {
/// Print Progressive Web Metrics to console.
pub print_pwm: bool,
/// Only shutdown once all theads are finished.
pub clean_shutdown: bool,
}
fn print_usage(app: &str, opts: &Options) {
@ -600,6 +603,7 @@ pub fn default_opts() -> Opts {
certificate_path: None,
unminify_js: false,
print_pwm: false,
clean_shutdown: false,
}
}
@ -752,6 +756,11 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
"config directory following xdg spec on linux platform",
"",
);
opts.optflag(
"",
"clean-shutdown",
"Do not shutdown until all threads have finished (macos only)",
);
opts.optflag("v", "version", "Display servo version information");
opts.optflag("", "unminify-js", "Unminify Javascript");
opts.optopt("", "profiler-db-user", "Profiler database user", "");
@ -1035,6 +1044,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
certificate_path: opt_match.opt_str("certificate-path"),
unminify_js: opt_match.opt_present("unminify-js"),
print_pwm: opt_match.opt_present("print-pwm"),
clean_shutdown: opt_match.opt_present("clean-shutdown"),
};
set_defaults(opts);

View file

@ -16,6 +16,9 @@ bench = false
[target.'cfg(windows)'.build-dependencies]
winres = "0.1"
[target.'cfg(target_os = "macos")'.build-dependencies]
cc = "1.0"
[package.metadata.winres]
FileDescription = "Servo"
LegalCopyright = "© The Servo Project Developers"

View file

@ -2,6 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[cfg(target_os = "macos")]
extern crate cc;
#[cfg(windows)]
extern crate winres;
@ -13,4 +16,10 @@ fn main() {
res.set_manifest_file("platform/windows/servo.exe.manifest");
res.compile().unwrap();
}
#[cfg(target_os = "macos")]
{
cc::Build::new()
.file("platform/macos/count_threads.c")
.compile("count_threads");
}
}

View file

@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mach/mach.h>
int macos_count_running_threads() {
task_t task = current_task();
thread_act_array_t threads;
mach_msg_type_number_t tcnt;
task_threads(task, &threads, &tcnt);
return tcnt;
}

View file

@ -2,7 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use servo::config::opts;
use std::ptr;
use std::thread;
use std::time::Duration;
pub fn deinit() {
// An unfortunate hack to make sure the linker's dead code stripping doesn't strip our
@ -10,9 +13,36 @@ pub fn deinit() {
unsafe {
ptr::read_volatile(&INFO_PLIST[0]);
}
let thread_count = unsafe {
macos_count_running_threads()
};
if thread_count != 1 {
println!("{} threads are still running after shutdown (bad).", thread_count);
if opts::get().clean_shutdown {
println!("Waiting until all threads have shutdown");
loop {
let thread_count = unsafe {
macos_count_running_threads()
};
if thread_count == 1 {
break;
}
thread::sleep(Duration::from_millis(1000));
println!("{} threads are still running.", thread_count);
}
}
} else {
println!("All threads have shutdown (good).");
}
}
#[cfg(target_os = "macos")]
#[link_section = "__TEXT,__info_plist"]
#[no_mangle]
pub static INFO_PLIST: [u8; 619] = *include_bytes!("Info.plist");
#[link(name = "count_threads")]
extern {
fn macos_count_running_threads() -> i32;
}