@@ -130,6 +130,8 @@ fn anonsocket_write<'tcx>(
130
130
return ecx. return_write_success ( 0 , & dest) ;
131
131
}
132
132
133
+ // If this fd is closed while blocking on `write`, any subsequent `read` on peer_fd will never
134
+ // wake up this thread. So the `unwrap` here is safe.
133
135
let self_ref = weak_self_ref. upgrade ( ) . unwrap ( ) ;
134
136
let self_anonsocket = self_ref. downcast :: < AnonSocket > ( ) . unwrap ( ) ;
135
137
let Some ( peer_fd) = self_anonsocket. peer_fd ( ) . upgrade ( ) else {
@@ -149,24 +151,25 @@ fn anonsocket_write<'tcx>(
149
151
if self_anonsocket. is_nonblock {
150
152
// Non-blocking socketpair with a full buffer.
151
153
return ecx. set_last_error_and_return ( ErrorKind :: WouldBlock , & dest) ;
154
+ } else {
155
+ // Blocking socketpair with a full buffer.
156
+ self_anonsocket. blocked_write_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
157
+ ecx. block_thread (
158
+ BlockReason :: UnnamedSocket ,
159
+ None ,
160
+ callback ! (
161
+ @capture<' tcx> {
162
+ weak_self_ref: WeakFileDescriptionRef ,
163
+ ptr: Pointer ,
164
+ len: usize ,
165
+ dest: MPlaceTy <' tcx>,
166
+ }
167
+ @unblock = |this| {
168
+ anonsocket_write( weak_self_ref, ptr, len, dest, this)
169
+ }
170
+ ) ,
171
+ ) ;
152
172
}
153
- // Blocking socketpair with a full buffer.
154
- self_anonsocket. blocked_write_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
155
- ecx. block_thread (
156
- BlockReason :: UnnamedSocket ,
157
- None ,
158
- callback ! (
159
- @capture<' tcx> {
160
- weak_self_ref: WeakFileDescriptionRef ,
161
- ptr: Pointer ,
162
- len: usize ,
163
- dest: MPlaceTy <' tcx>,
164
- }
165
- @unblock = |this| {
166
- anonsocket_write( weak_self_ref, ptr, len, dest, this)
167
- }
168
- ) ,
169
- ) ;
170
173
} else {
171
174
let mut writebuf = writebuf. borrow_mut ( ) ;
172
175
// Remember this clock so `read` can synchronize with us.
@@ -210,6 +213,8 @@ fn anonsocket_read<'tcx>(
210
213
return ecx. return_read_success ( ptr, & [ ] , 0 , & dest) ;
211
214
}
212
215
216
+ // If this fd is closed while blocking, it is impossible to unblock this `read` through
217
+ // another `write` in peer_fd, so the `unwrap` here is fine.
213
218
let self_ref = weak_self_ref. upgrade ( ) . unwrap ( ) ;
214
219
let self_anonsocket = self_ref. downcast :: < AnonSocket > ( ) . unwrap ( ) ;
215
220
@@ -227,9 +232,7 @@ fn anonsocket_read<'tcx>(
227
232
// POSIX.1-2001 allows either error to be returned for this case.
228
233
// Since there is no ErrorKind for EAGAIN, WouldBlock is used.
229
234
return ecx. set_last_error_and_return ( ErrorKind :: WouldBlock , & dest) ;
230
- }
231
-
232
- if self_anonsocket. peer_fd ( ) . upgrade ( ) . is_none ( ) {
235
+ } else if self_anonsocket. peer_fd ( ) . upgrade ( ) . is_none ( ) {
233
236
// Socketpair with no peer and empty buffer.
234
237
// 0 bytes successfully read indicates end-of-file.
235
238
return ecx. return_read_success ( ptr, & [ ] , 0 , & dest) ;
0 commit comments