@@ -14,7 +14,7 @@ use crate::*;
1414
1515/// A unique id for file descriptions. While we could use the address, considering that
1616/// is definitely unique, the address would expose interpreter internal state when used
17- /// for sorting things. So instead we generate a unique id per file description is the name
17+ /// for sorting things. So instead we generate a unique id per file description which is the same
1818/// for all `dup`licates and is never reused.
1919#[ derive( Debug , Copy , Clone , Default , Eq , PartialEq , Ord , PartialOrd ) ]
2020pub struct FdId ( usize ) ;
@@ -48,6 +48,12 @@ impl<T: ?Sized> FileDescriptionRef<T> {
4848 pub fn id ( & self ) -> FdId {
4949 self . 0 . id
5050 }
51+
52+ /// Returns the raw address of this file description. Useful for equality comparisons.
53+ /// Use `id` instead if this can affect user-visible behavior!
54+ pub fn addr ( & self ) -> usize {
55+ Rc :: as_ptr ( & self . 0 ) . addr ( )
56+ }
5157}
5258
5359/// Holds a weak reference to the actual file description.
@@ -70,6 +76,11 @@ impl<T: ?Sized> WeakFileDescriptionRef<T> {
7076 pub fn upgrade ( & self ) -> Option < FileDescriptionRef < T > > {
7177 self . 0 . upgrade ( ) . map ( FileDescriptionRef )
7278 }
79+
80+ /// Returns the raw address of this file description. Useful for equality comparisons.
81+ pub fn addr ( & self ) -> usize {
82+ self . 0 . as_ptr ( ) . addr ( )
83+ }
7384}
7485
7586impl < T > VisitProvenance for WeakFileDescriptionRef < T > {
@@ -105,12 +116,13 @@ impl<T: FileDescription + 'static> FileDescriptionExt for T {
105116 communicate_allowed : bool ,
106117 ecx : & mut MiriInterpCx < ' tcx > ,
107118 ) -> InterpResult < ' tcx , io:: Result < ( ) > > {
119+ let addr = self . addr ( ) ;
108120 match Rc :: into_inner ( self . 0 ) {
109121 Some ( fd) => {
110- // Remove entry from the global epoll_event_interest table .
111- ecx. machine . epoll_interests . remove ( fd. id ) ;
122+ // There might have been epolls interested in this FD. Remove that .
123+ ecx. machine . epoll_interests . remove_epolls ( fd. id ) ;
112124
113- fd. inner . close ( communicate_allowed, ecx)
125+ fd. inner . destroy ( addr , communicate_allowed, ecx)
114126 }
115127 None => {
116128 // Not the last reference.
@@ -183,9 +195,12 @@ pub trait FileDescription: std::fmt::Debug + FileDescriptionExt {
183195 throw_unsup_format ! ( "cannot seek on {}" , self . name( ) ) ;
184196 }
185197
186- /// Close the file descriptor.
187- fn close < ' tcx > (
198+ /// Destroys the file description. Only called when the last duplicate file descriptor is closed.
199+ ///
200+ /// `self_addr` is the address that this file description used to be stored at.
201+ fn destroy < ' tcx > (
188202 self ,
203+ _self_addr : usize ,
189204 _communicate_allowed : bool ,
190205 _ecx : & mut MiriInterpCx < ' tcx > ,
191206 ) -> InterpResult < ' tcx , io:: Result < ( ) > >
@@ -362,8 +377,9 @@ impl FileDescription for FileHandle {
362377 interp_ok ( ( & mut & self . file ) . seek ( offset) )
363378 }
364379
365- fn close < ' tcx > (
380+ fn destroy < ' tcx > (
366381 self ,
382+ _self_addr : usize ,
367383 communicate_allowed : bool ,
368384 _ecx : & mut MiriInterpCx < ' tcx > ,
369385 ) -> InterpResult < ' tcx , io:: Result < ( ) > > {
0 commit comments