@@ -4,7 +4,7 @@ use alloc::sync::Arc;
4
4
use core:: sync:: atomic:: { AtomicBool , Ordering } ;
5
5
use kernel:: {
6
6
io_buffer:: IoBufferWriter , linked_list:: Links , prelude:: * , sync:: Ref ,
7
- user_ptr:: UserSlicePtrWriter ,
7
+ user_ptr:: UserSlicePtrWriter , ScopeGuard ,
8
8
} ;
9
9
10
10
use crate :: {
@@ -144,6 +144,10 @@ impl DeliverToRead for Transaction {
144
144
pub sender_pid: pid_t,
145
145
pub sender_euid: uid_t,
146
146
*/
147
+ let send_failed_reply = ScopeGuard :: new ( || {
148
+ let reply = Either :: Right ( BR_FAILED_REPLY ) ;
149
+ self . from . deliver_reply ( reply, & self ) ;
150
+ } ) ;
147
151
let mut tr = BinderTransactionData :: default ( ) ;
148
152
149
153
if let Some ( nref) = & self . node_ref {
@@ -171,13 +175,13 @@ impl DeliverToRead for Transaction {
171
175
BR_TRANSACTION
172
176
} ;
173
177
174
- // Write the transaction code and data to the user buffer. On failure we complete the
175
- // transaction with an error.
176
- if let Err ( err ) = writer. write ( & code ) . and_then ( |_| writer . write ( & tr) ) {
177
- let reply = Either :: Right ( BR_FAILED_REPLY ) ;
178
- self . from . deliver_reply ( reply , & self ) ;
179
- return Err ( err ) ;
180
- }
178
+ // Write the transaction code and data to the user buffer.
179
+ writer . write ( & code ) ? ;
180
+ writer. write ( & tr) ? ;
181
+
182
+ // Dismiss the completion of transaction with a failure. No failure paths are allowed from
183
+ // here on out.
184
+ send_failed_reply . dismiss ( ) ;
181
185
182
186
// When this is not a reply and not an async transaction, update `current_transaction`. If
183
187
// it's a reply, `current_transaction` has already been updated appropriately.
0 commit comments