@@ -748,59 +748,51 @@ impl Drop for XtraResource {
748
748
749
749
pub mod c_api {
750
750
use super :: XtraResource ;
751
- use std :: panic :: catch_unwind;
751
+ use std :: panic :: { catch_unwind, AssertUnwindSafe } ;
752
752
use std :: sync :: atomic :: {AtomicU32 , Ordering };
753
753
754
754
const INVALID_TAG : u32 = 0 ;
755
755
const VALID_TAG : u32 = 0xDEAD_BEEF ;
756
756
const ERR_TAG : u32 = 0xDEAF_CAFE ;
757
757
758
- static COUNTER : AtomicU32 = AtomicU32 :: new (0 );
759
-
760
758
pub struct CXtraResource {
761
759
tag : AtomicU32 , // pour prévenir d'une réutilisation accidentelle
762
- id : AtomicU32 , // pour quasi-identifier l'objet
763
760
inner : XtraResource ,
764
761
}
765
762
766
763
#[no_mangle]
767
764
pub unsafe extern " C" fn xtra_with (cb : unsafe extern " C" fn (* mut CXtraResource ) -> ()) {
768
- let inner = if let Ok (res ) = catch_unwind (XtraResource :: new ) {
765
+ let inner = if let Ok (res ) = catch_unwind (AssertUnwindSafe ( XtraResource :: new ) ) {
769
766
res
770
767
} else {
771
768
# println! (" impossible d'allouer la ressource" );
772
769
return ;
773
770
};
774
- let id = COUNTER . fetch_add (1 , Ordering :: SeqCst );
775
771
let tag = VALID_TAG ;
776
772
777
- // Utilisation de la mémoire du tas pour ne pas fournir de pointeur de
778
- // pile au code C!
779
- let mut boxed = Box :: new (CXtraResource {
773
+ let mut wrapped = CXtraResource {
780
774
tag : AtomicU32 :: new (tag ),
781
- id : AtomicU32 :: new (id ),
782
775
inner
783
- }) ;
776
+ };
784
777
785
- # println! (" appel du callback sur {:p}" , boxed );
786
- cb (boxed . as_mut () as * mut CXtraResource );
778
+ # println! (" appel du callback sur {:p}" , & wrapped );
779
+ cb (& mut wrapped as * mut CXtraResource );
787
780
788
- let new_id = boxed . id. load (Ordering :: SeqCst );
789
781
// pour éviter de réutilisation accidentelle
790
- let new_tag = boxed . tag. swap (INVALID_TAG , Ordering :: SeqCst );
791
- if new_id == id && ( new_tag == VALID_TAG || new_tag == ERR_TAG ) {
792
- # println! (" libération de {:p}" , boxed );
782
+ let new_tag = wrapped . tag. swap (INVALID_TAG , Ordering :: SeqCst );
783
+ if new_tag == VALID_TAG || new_tag == ERR_TAG {
784
+ # println! (" libération de {:p}" , & wrapped );
793
785
// drop implicite de la `box`
794
786
} else {
795
- # println! (" oubli de {:p}" , boxed );
787
+ # println! (" oubli de {:p}" , & wrapped );
796
788
// (...) gestion des erreurs (partie critique)
797
- std :: mem :: forget (boxed ); // la boîte est corrompu, ne pas libérer!
789
+ std :: mem :: forget (wrapped ); // la boîte est corrompu, ne pas libérer!
798
790
}
799
791
}
800
792
801
793
#[no_mangle]
802
794
pub unsafe extern " C" fn xtra_dosthg (cxtra : * mut CXtraResource , arg : u32 ) {
803
- let do_it = || {
795
+ let do_it = move || {
804
796
if let Some (cxtra ) = cxtra . as_mut () {
805
797
if cxtra . tag. load (Ordering :: SeqCst ) == VALID_TAG {
806
798
# println! (" fait quelque chose avec {:p}" , cxtra );
0 commit comments