From 7599d2dd51eb76892c929404dd7b49265e9f7c8f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 20 Feb 2012 21:41:24 -0800 Subject: [PATCH] rustdoc: Implement astsrv in a dedicated task This allows the srv type to be sendable so we can parallelize all the rustdoc passes --- src/rustdoc/astsrv.rs | 79 ++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/src/rustdoc/astsrv.rs b/src/rustdoc/astsrv.rs index 7c5d435504ed..60ba854a537b 100644 --- a/src/rustdoc/astsrv.rs +++ b/src/rustdoc/astsrv.rs @@ -21,7 +21,7 @@ import rustc::middle::resolve; export ctxt; export ctxt_handler; -export srv; +export srv::{}; export from_str; export from_file; export exec; @@ -34,31 +34,71 @@ type ctxt = { type srv_owner = fn(srv: srv) -> T; type ctxt_handler = fn~(ctxt: ctxt) -> T; +type parser = fn~(session::session, str) -> @ast::crate; -type srv = { - ctxt: ctxt +enum msg { + handle_request(fn~(ctxt)), + exit +} + +enum srv = { + ch: comm::chan }; fn from_str(source: str, owner: srv_owner) -> T { - let (sess, ignore_errors) = build_session(); - - let srv = { - ctxt: build_ctxt(sess, parse::from_str_sess(sess, source), - ignore_errors) - }; - - owner(srv) + run(owner, source, parse::from_str_sess) } fn from_file(file: str, owner: srv_owner) -> T { + run(owner, file, parse::from_file_sess) +} + +fn run(owner: srv_owner, source: str, parse: parser) -> T { + + let srv_ = srv({ + ch: task::spawn_listener {|po| + act(po, source, parse); + } + }); + + let res = owner(srv_); + comm::send(srv_.ch, exit); + ret res; +} + +fn act(po: comm::port, source: str, parse: parser) { let (sess, ignore_errors) = build_session(); - let srv = { - ctxt: build_ctxt(sess, parse::from_file_sess(sess, file), - ignore_errors) - }; + let ctxt = build_ctxt( + sess, + parse(sess, source), + ignore_errors + ); - owner(srv) + let keep_going = true; + while keep_going { + alt comm::recv(po) { + handle_request(f) { + f(ctxt); + } + exit { + keep_going = false; + } + } + } +} + +fn exec( + srv: srv, + +f: fn~(ctxt: ctxt) -> T +) -> T { + let po = comm::port(); + let ch = comm::chan(po); + let msg = handle_request(fn~[move f](ctxt: ctxt) { + comm::send(ch, f(ctxt)) + }); + comm::send(srv.ch, msg); + comm::recv(po) } fn build_ctxt(sess: session::session, ast: @ast::crate, @@ -242,13 +282,6 @@ fn should_ignore_external_import_paths_that_dont_exist() { from_str(source) {|_srv| } } -fn exec( - srv: srv, - f: fn~(ctxt: ctxt) -> T -) -> T { - f(srv.ctxt) -} - #[test] fn srv_should_return_request_result() { let source = "fn a() { }";