async-llvm(5): Do continuous error handling on main thread.

This commit is contained in:
Michael Woerister 2017-07-24 14:51:00 +02:00
parent df6be33d84
commit b18a61a15b

View File

@ -32,6 +32,7 @@ use rustc_demangle;
use std::cmp;
use std::ffi::CString;
use std::fmt;
use std::fs;
use std::io;
use std::io::Write;
@ -777,7 +778,33 @@ pub fn run_passes(sess: &Session,
Client::new(num_workers).expect("failed to create jobserver")
});
execute_work(sess, work_items, client, trans.exported_symbols.clone());
let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
let (trans_worker_send, trans_worker_receive) = channel();
let coordinator_thread = start_executing_work(sess,
work_items,
shared_emitter,
trans_worker_send,
client,
trans.exported_symbols.clone());
loop {
shared_emitter_main.check(sess);
match trans_worker_receive.recv() {
Ok(Message::AllWorkDone) |
Err(_) => break,
Ok(Message::CheckErrorMessages) => continue,
Ok(msg) => {
bug!("unexpected message {:?}", msg);
}
}
}
coordinator_thread.join().unwrap();
// Just in case, check this on the way out.
sess.diagnostic().abort_if_errors();
// If in incr. comp. mode, preserve the `.o` files for potential re-use
for mtrans in modules.iter() {
@ -975,12 +1002,18 @@ pub fn dump_incremental_data(trans: &CrateTranslation) {
eprintln!("incremental: re-using {} out of {} modules", reuse, trans.modules.len());
}
struct WorkItem {
pub struct WorkItem {
mtrans: ModuleTranslation,
config: ModuleConfig,
output_names: OutputFilenames
}
impl fmt::Debug for WorkItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "WorkItem({})", self.mtrans.name)
}
}
fn build_work_item(sess: &Session,
mtrans: ModuleTranslation,
config: ModuleConfig,
@ -1041,21 +1074,29 @@ fn execute_work_item(cgcx: &CodegenContext, work_item: WorkItem)
Ok(())
}
#[derive(Debug)]
pub enum Message {
Token(io::Result<Acquired>),
Done { success: bool },
WorkItem(WorkItem),
CheckErrorMessages,
AllWorkDone,
}
pub struct Diagnostic {
msg: String,
code: Option<String>,
lvl: Level,
}
fn execute_work(sess: &Session,
mut work_items: Vec<WorkItem>,
jobserver: Client,
exported_symbols: Arc<ExportedSymbols>) {
fn start_executing_work(sess: &Session,
mut work_items: Vec<WorkItem>,
shared_emitter: SharedEmitter,
trans_worker_send: Sender<Message>,
jobserver: Client,
exported_symbols: Arc<ExportedSymbols>)
-> thread::JoinHandle<()> {
let (tx, rx) = channel();
let tx2 = tx.clone();
@ -1076,8 +1117,6 @@ fn execute_work(sess: &Session,
helper.request_token();
}
let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
let mut each_linked_rlib_for_lto = Vec::new();
drop(link::each_linked_rlib(sess, &mut |cnum, path| {
if link::ignored_for_lto(sess, cnum) {
@ -1200,18 +1239,20 @@ fn execute_work(sess: &Session,
Message::Done { success: true } => {
drop(tokens.pop());
running -= 1;
trans_worker_send.send(Message::CheckErrorMessages).unwrap();
}
Message::Done { success: false } => {
shared_emitter.fatal("aborting due to worker thread panic".to_string());
trans_worker_send.send(Message::CheckErrorMessages).unwrap();
}
msg @ Message::WorkItem(_) |
msg @ Message::AllWorkDone |
msg @ Message::CheckErrorMessages => {
bug!("unexpected message: {:?}", msg);
}
}
}
}).join().unwrap();
shared_emitter_main.check(sess);
// Just in case, check this on the way out.
sess.diagnostic().abort_if_errors();
})
}
fn spawn_work(cgcx: CodegenContext, work: WorkItem) {