Sto lavorando su un Rust wrapper for the Duktape JavaScript interpreter. In un normale caso d'uso, lo stack di chiamate sarà simile al seguente:Cattura il panico! quando Rust ha chiamato da C FFI, senza generare i thread
- Ruggine: codice applicazione arbitrario.
- Rust: il mio wrapper della libreria.
- C: l'interprete Duktape.
- Rust: My Rust code.
- Rust: callback arbitrari nel codice dell'applicazione.
Cosa succede se (5) chiama panic!
? Secondo vari sviluppatori di Rust su IRC, tentare di eseguire il panic!
da callframes non-ruggine come (3) può comportare un comportamento indefinito.
Tuttavia, secondo la documentazione di Rust, l'unico modo per catturare uno panic!
è l'utilizzo di std::task::try
, che genera un thread aggiuntivo. C'è anche rustrt::unwind::try
, che non può essere annidato due volte in un singolo thread, tra le altre restrizioni.
Una soluzione, proposta da Benjamin Herr, è interrompere il processo se il codice in (5) va in panico. Ho confezionato la sua soluzione come abort_on_panic
, e sembra funzionare, per i valori di "lavoro" che includono "crash l'intero programma, ma le cose almeno non corrompere sottilmente":
abort_on_panic!("cannot panic inside this block", {
panic!("something went wrong!");
});
ma è un modo per emulare std::task::try
senza l'overhead della creazione di thread/attività?
Grazie! È effettivamente necessario per 'std :: task :: try' per generare un nuovo thread del SO? Sembra che potrebbe essere implementato per salvare alcuni stati di runtime, richiamare il "task" nello stesso thread del sistema operativo e ripristinare lo stato di runtime al termine. Ciò manterrebbe la stessa API pubblica della versione corrente, ma potrebbe risparmiare il costo di chiamare 'pthread_new' tutto ciò che JavaScript chiama a Rust. – emk
Questo è un po 'più alto di quello di Rust. –