@@ -72,6 +72,33 @@ impl Mapping {
7272const PROC_DEFER_FLUSH : u8 = 1 ;
7373const PROC_DEFER_RELEASE : u8 = 2 ;
7474
75+ #[ derive( Copy , Clone ) ]
76+ pub ( crate ) enum IsFrozen {
77+ Yes ,
78+ No ,
79+ InProgress ,
80+ }
81+
82+ impl IsFrozen {
83+ /// Whether incoming transactions should be rejected due to freeze.
84+ pub ( crate ) fn is_frozen ( self ) -> bool {
85+ match self {
86+ IsFrozen :: Yes => true ,
87+ IsFrozen :: No => false ,
88+ IsFrozen :: InProgress => true ,
89+ }
90+ }
91+
92+ /// Whether freeze notifications consider this process frozen.
93+ pub ( crate ) fn is_fully_frozen ( self ) -> bool {
94+ match self {
95+ IsFrozen :: Yes => true ,
96+ IsFrozen :: No => false ,
97+ IsFrozen :: InProgress => false ,
98+ }
99+ }
100+ }
101+
75102/// The fields of `Process` protected by the spinlock.
76103pub ( crate ) struct ProcessInner {
77104 is_manager : bool ,
@@ -98,7 +125,7 @@ pub(crate) struct ProcessInner {
98125 /// are woken up.
99126 outstanding_txns : u32 ,
100127 /// Process is frozen and unable to service binder transactions.
101- pub ( crate ) is_frozen : bool ,
128+ pub ( crate ) is_frozen : IsFrozen ,
102129 /// Process received sync transactions since last frozen.
103130 pub ( crate ) sync_recv : bool ,
104131 /// Process received async transactions since last frozen.
@@ -124,7 +151,7 @@ impl ProcessInner {
124151 started_thread_count : 0 ,
125152 defer_work : 0 ,
126153 outstanding_txns : 0 ,
127- is_frozen : false ,
154+ is_frozen : IsFrozen :: No ,
128155 sync_recv : false ,
129156 async_recv : false ,
130157 binderfs_file : None ,
@@ -1260,7 +1287,7 @@ impl Process {
12601287 let is_manager = {
12611288 let mut inner = self . inner . lock ( ) ;
12621289 inner. is_dead = true ;
1263- inner. is_frozen = false ;
1290+ inner. is_frozen = IsFrozen :: No ;
12641291 inner. sync_recv = false ;
12651292 inner. async_recv = false ;
12661293 inner. is_manager
@@ -1367,7 +1394,7 @@ impl Process {
13671394 return ;
13681395 }
13691396 inner. outstanding_txns -= 1 ;
1370- inner. is_frozen && inner. outstanding_txns == 0
1397+ inner. is_frozen . is_frozen ( ) && inner. outstanding_txns == 0
13711398 } ;
13721399
13731400 if wake {
@@ -1381,7 +1408,7 @@ impl Process {
13811408 let mut inner = self . inner . lock ( ) ;
13821409 inner. sync_recv = false ;
13831410 inner. async_recv = false ;
1384- inner. is_frozen = false ;
1411+ inner. is_frozen = IsFrozen :: No ;
13851412 drop ( inner) ;
13861413 msgs. send_messages ( ) ;
13871414 return Ok ( ( ) ) ;
@@ -1390,7 +1417,7 @@ impl Process {
13901417 let mut inner = self . inner . lock ( ) ;
13911418 inner. sync_recv = false ;
13921419 inner. async_recv = false ;
1393- inner. is_frozen = true ;
1420+ inner. is_frozen = IsFrozen :: InProgress ;
13941421
13951422 if info. timeout_ms > 0 {
13961423 let mut jiffies = kernel:: time:: msecs_to_jiffies ( info. timeout_ms ) ;
@@ -1404,7 +1431,7 @@ impl Process {
14041431 . wait_interruptible_timeout ( & mut inner, jiffies)
14051432 {
14061433 CondVarTimeoutResult :: Signal { .. } => {
1407- inner. is_frozen = false ;
1434+ inner. is_frozen = IsFrozen :: No ;
14081435 return Err ( ERESTARTSYS ) ;
14091436 }
14101437 CondVarTimeoutResult :: Woken { jiffies : remaining } => {
@@ -1418,17 +1445,18 @@ impl Process {
14181445 }
14191446
14201447 if inner. txns_pending_locked ( ) {
1421- inner. is_frozen = false ;
1448+ inner. is_frozen = IsFrozen :: No ;
14221449 Err ( EAGAIN )
14231450 } else {
14241451 drop ( inner) ;
14251452 match self . prepare_freeze_messages ( ) {
14261453 Ok ( batch) => {
1454+ self . inner . lock ( ) . is_frozen = IsFrozen :: Yes ;
14271455 batch. send_messages ( ) ;
14281456 Ok ( ( ) )
14291457 }
14301458 Err ( kernel:: alloc:: AllocError ) => {
1431- self . inner . lock ( ) . is_frozen = false ;
1459+ self . inner . lock ( ) . is_frozen = IsFrozen :: No ;
14321460 Err ( ENOMEM )
14331461 }
14341462 }
0 commit comments