inline SameThread and CrossThread
This commit is contained in:
parent
31053484a7
commit
f601b29825
3 changed files with 40 additions and 64 deletions
|
|
@ -12,10 +12,10 @@ use crate::base::{self, *};
|
||||||
use crate::{errors, proc_macro_server};
|
use crate::{errors, proc_macro_server};
|
||||||
|
|
||||||
fn exec_strategy(sess: &Session) -> impl pm::bridge::server::ExecutionStrategy + 'static {
|
fn exec_strategy(sess: &Session) -> impl pm::bridge::server::ExecutionStrategy + 'static {
|
||||||
pm::bridge::server::MaybeCrossThread::new(
|
pm::bridge::server::MaybeCrossThread {
|
||||||
sess.opts.unstable_opts.proc_macro_execution_strategy
|
cross_thread: sess.opts.unstable_opts.proc_macro_execution_strategy
|
||||||
== ProcMacroExecutionStrategy::CrossThread,
|
== ProcMacroExecutionStrategy::CrossThread,
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BangProcMacro {
|
pub struct BangProcMacro {
|
||||||
|
|
|
||||||
|
|
@ -121,10 +121,13 @@ macro_rules! define_dispatcher {
|
||||||
}
|
}
|
||||||
with_api!(define_dispatcher, MarkedTokenStream<S>, MarkedSpan<S>, MarkedSymbol<S>);
|
with_api!(define_dispatcher, MarkedTokenStream<S>, MarkedSpan<S>, MarkedSymbol<S>);
|
||||||
|
|
||||||
|
// This trait is currently only implemented and used once, inside of this crate.
|
||||||
|
// We keep it public to allow implementing more complex execution strategies in
|
||||||
|
// the future, such as wasm proc-macros.
|
||||||
pub trait ExecutionStrategy {
|
pub trait ExecutionStrategy {
|
||||||
fn run_bridge_and_client<S: Server>(
|
fn run_bridge_and_client(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: &mut Dispatcher<S>,
|
dispatcher: &mut Dispatcher<impl Server>,
|
||||||
input: Buffer,
|
input: Buffer,
|
||||||
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
||||||
force_show_panics: bool,
|
force_show_panics: bool,
|
||||||
|
|
@ -164,82 +167,55 @@ impl Drop for RunningSameThreadGuard {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MaybeCrossThread {
|
pub struct MaybeCrossThread {
|
||||||
cross_thread: bool,
|
pub cross_thread: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MaybeCrossThread {
|
pub const SAME_THREAD: MaybeCrossThread = MaybeCrossThread { cross_thread: false };
|
||||||
pub const fn new(cross_thread: bool) -> Self {
|
pub const CROSS_THREAD: MaybeCrossThread = MaybeCrossThread { cross_thread: true };
|
||||||
MaybeCrossThread { cross_thread }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExecutionStrategy for MaybeCrossThread {
|
impl ExecutionStrategy for MaybeCrossThread {
|
||||||
fn run_bridge_and_client<S: Server>(
|
fn run_bridge_and_client(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: &mut Dispatcher<S>,
|
dispatcher: &mut Dispatcher<impl Server>,
|
||||||
input: Buffer,
|
input: Buffer,
|
||||||
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
||||||
force_show_panics: bool,
|
force_show_panics: bool,
|
||||||
) -> Buffer {
|
) -> Buffer {
|
||||||
if self.cross_thread || ALREADY_RUNNING_SAME_THREAD.get() {
|
if self.cross_thread || ALREADY_RUNNING_SAME_THREAD.get() {
|
||||||
CrossThread.run_bridge_and_client(dispatcher, input, run_client, force_show_panics)
|
let (mut server, mut client) = MessagePipe::new();
|
||||||
|
|
||||||
|
let join_handle = thread::spawn(move || {
|
||||||
|
let mut dispatch = |b: Buffer| -> Buffer {
|
||||||
|
client.send(b);
|
||||||
|
client.recv().expect("server died while client waiting for reply")
|
||||||
|
};
|
||||||
|
|
||||||
|
run_client(BridgeConfig {
|
||||||
|
input,
|
||||||
|
dispatch: (&mut dispatch).into(),
|
||||||
|
force_show_panics,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
while let Some(b) = server.recv() {
|
||||||
|
server.send(dispatcher.dispatch(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
join_handle.join().unwrap()
|
||||||
} else {
|
} else {
|
||||||
SameThread.run_bridge_and_client(dispatcher, input, run_client, force_show_panics)
|
let _guard = RunningSameThreadGuard::new();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SameThread;
|
let mut dispatch = |buf| dispatcher.dispatch(buf);
|
||||||
|
|
||||||
impl ExecutionStrategy for SameThread {
|
|
||||||
fn run_bridge_and_client<S: Server>(
|
|
||||||
&self,
|
|
||||||
dispatcher: &mut Dispatcher<S>,
|
|
||||||
input: Buffer,
|
|
||||||
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
|
||||||
force_show_panics: bool,
|
|
||||||
) -> Buffer {
|
|
||||||
let _guard = RunningSameThreadGuard::new();
|
|
||||||
|
|
||||||
let mut dispatch = |buf| dispatcher.dispatch(buf);
|
|
||||||
|
|
||||||
run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CrossThread;
|
|
||||||
|
|
||||||
impl ExecutionStrategy for CrossThread {
|
|
||||||
fn run_bridge_and_client<S: Server>(
|
|
||||||
&self,
|
|
||||||
dispatcher: &mut Dispatcher<S>,
|
|
||||||
input: Buffer,
|
|
||||||
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
|
||||||
force_show_panics: bool,
|
|
||||||
) -> Buffer {
|
|
||||||
let (mut server, mut client) = MessagePipe::new();
|
|
||||||
|
|
||||||
let join_handle = thread::spawn(move || {
|
|
||||||
let mut dispatch = |b: Buffer| -> Buffer {
|
|
||||||
client.send(b);
|
|
||||||
client.recv().expect("server died while client waiting for reply")
|
|
||||||
};
|
|
||||||
|
|
||||||
run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
|
run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
|
||||||
});
|
|
||||||
|
|
||||||
while let Some(b) = server.recv() {
|
|
||||||
server.send(dispatcher.dispatch(b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
join_handle.join().unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A message pipe used for communicating between server and client threads.
|
/// A message pipe used for communicating between server and client threads.
|
||||||
struct MessagePipe<T> {
|
struct MessagePipe<T> {
|
||||||
tx: std::sync::mpsc::SyncSender<T>,
|
tx: mpsc::SyncSender<T>,
|
||||||
rx: std::sync::mpsc::Receiver<T>,
|
rx: mpsc::Receiver<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MessagePipe<T> {
|
impl<T> MessagePipe<T> {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ impl ProcMacros {
|
||||||
if *trait_name == macro_name =>
|
if *trait_name == macro_name =>
|
||||||
{
|
{
|
||||||
let res = client.run(
|
let res = client.run(
|
||||||
&bridge::server::SameThread,
|
&bridge::server::SAME_THREAD,
|
||||||
S::make_server(call_site, def_site, mixed_site, callback),
|
S::make_server(call_site, def_site, mixed_site, callback),
|
||||||
macro_body,
|
macro_body,
|
||||||
cfg!(debug_assertions),
|
cfg!(debug_assertions),
|
||||||
|
|
@ -39,7 +39,7 @@ impl ProcMacros {
|
||||||
}
|
}
|
||||||
bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => {
|
bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => {
|
||||||
let res = client.run(
|
let res = client.run(
|
||||||
&bridge::server::SameThread,
|
&bridge::server::SAME_THREAD,
|
||||||
S::make_server(call_site, def_site, mixed_site, callback),
|
S::make_server(call_site, def_site, mixed_site, callback),
|
||||||
macro_body,
|
macro_body,
|
||||||
cfg!(debug_assertions),
|
cfg!(debug_assertions),
|
||||||
|
|
@ -48,7 +48,7 @@ impl ProcMacros {
|
||||||
}
|
}
|
||||||
bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => {
|
bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => {
|
||||||
let res = client.run(
|
let res = client.run(
|
||||||
&bridge::server::SameThread,
|
&bridge::server::SAME_THREAD,
|
||||||
S::make_server(call_site, def_site, mixed_site, callback),
|
S::make_server(call_site, def_site, mixed_site, callback),
|
||||||
parsed_attributes,
|
parsed_attributes,
|
||||||
macro_body,
|
macro_body,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue