11use crate :: Error :: { IOError , LockError } ;
22use crate :: Result ;
3+ use std:: any:: Any ;
34use std:: collections:: VecDeque ;
45use std:: sync:: atomic:: { AtomicBool , Ordering } ;
56use std:: sync:: mpsc:: { channel, Receiver , Sender } ;
@@ -9,47 +10,47 @@ use std::thread::JoinHandle;
910
1011const LOG_TAG : & str = "MMKV:IO" ;
1112
12- type Job = Box < dyn FnOnce ( & mut dyn std :: any :: Any ) + Send + ' static > ;
13+ type Job = Box < dyn FnOnce ( & mut dyn Any ) + Send + ' static > ;
1314
1415enum Signal {
1516 Normal ,
1617 Kill ( Job ) ,
1718}
1819
19- pub trait Callback : Send { }
20+ pub trait Callback : Send + Any { }
2021
21- pub struct IOLooper {
22+ pub struct IOLooper < T > {
2223 sender : Option < Sender < Signal > > ,
2324 executor : Executor ,
25+ _marker : std:: marker:: PhantomData < T > ,
2426}
2527
2628struct Executor {
2729 queue : Arc < Mutex < VecDeque < Job > > > ,
2830 join_handle : Option < JoinHandle < ( ) > > ,
2931}
3032
31- impl IOLooper {
32- pub fn new < T > ( callback : T ) -> Self
33- where
34- T : Callback + ' static ,
35- {
33+ impl < T : Callback + ' static > IOLooper < T > {
34+ pub fn new ( callback : T ) -> Self {
3635 let ( sender, receiver) = channel :: < Signal > ( ) ;
3736 let executor = Executor :: new ( receiver, callback) ;
3837 IOLooper {
3938 sender : Some ( sender) ,
4039 executor,
40+ _marker : std:: marker:: PhantomData ,
4141 }
4242 }
4343
44- pub fn post_and_kill < F > ( & mut self , task : F )
45- where
46- F : FnOnce ( & mut dyn std:: any:: Any ) + Send + ' static ,
47- {
44+ pub fn post_and_kill < F : FnOnce ( & mut T ) + Send + ' static > ( & mut self , task : F ) {
45+ let job: Job = Box :: new ( |callback| {
46+ let callback = callback. downcast_mut :: < T > ( ) . unwrap ( ) ;
47+ task ( callback)
48+ } ) ;
4849 self . executor . queue . lock ( ) . unwrap ( ) . clear ( ) ;
4950 self . sender
5051 . as_ref ( )
5152 . unwrap ( )
52- . send ( Signal :: Kill ( Box :: new ( task ) ) )
53+ . send ( Signal :: Kill ( job ) )
5354 . unwrap ( ) ;
5455 drop ( self . sender . take ( ) ) ;
5556 if let Some ( handle) = self . executor . join_handle . take ( ) {
@@ -58,14 +59,15 @@ impl IOLooper {
5859 }
5960 }
6061
61- pub fn post < F > ( & self , task : F ) -> Result < ( ) >
62- where
63- F : FnOnce ( & mut dyn std:: any:: Any ) + Send + ' static ,
64- {
62+ pub fn post < F : FnOnce ( & mut T ) + Send + ' static > ( & self , task : F ) -> Result < ( ) > {
63+ let job: Job = Box :: new ( |callback| {
64+ let callback = callback. downcast_mut :: < T > ( ) . unwrap ( ) ;
65+ task ( callback)
66+ } ) ;
6567 self . executor
6668 . queue
6769 . lock ( )
68- . map ( |mut queue| queue. push_back ( Box :: new ( task ) ) )
70+ . map ( |mut queue| queue. push_back ( job ) )
6971 . map_err ( |e| LockError ( e. to_string ( ) ) ) ?;
7072
7173 self . sender
@@ -91,7 +93,7 @@ impl IOLooper {
9193 }
9294}
9395
94- impl Drop for IOLooper {
96+ impl < T > Drop for IOLooper < T > {
9597 fn drop ( & mut self ) {
9698 drop ( self . sender . take ( ) ) ;
9799
@@ -103,10 +105,7 @@ impl Drop for IOLooper {
103105}
104106
105107impl Executor {
106- pub fn new < T > ( receiver : Receiver < Signal > , mut callback : T ) -> Self
107- where
108- T : Callback + std:: any:: Any + ' static ,
109- {
108+ pub fn new < T : Callback + ' static > ( receiver : Receiver < Signal > , mut callback : T ) -> Self {
110109 let queue: Arc < Mutex < VecDeque < Job > > > = Arc :: new ( Mutex :: new ( VecDeque :: with_capacity ( 100 ) ) ) ;
111110 let queue_clone = Arc :: clone ( & queue) ;
112111 let handle = thread:: spawn ( move || loop {
@@ -164,31 +163,20 @@ mod tests {
164163 io_looper
165164 . post ( |callback| {
166165 thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
167- callback
168- . downcast_ref :: < SimpleCallback > ( )
169- . unwrap ( )
170- . print ( "first job" )
166+ callback. print ( "first job" )
171167 } )
172168 . expect ( "failed to execute job" ) ;
173169 io_looper
174170 . post ( |callback| {
175171 thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
176- callback
177- . downcast_ref :: < SimpleCallback > ( )
178- . unwrap ( )
179- . print ( "second job" )
172+ callback. print ( "second job" )
180173 } )
181174 . expect ( "failed to execute job" ) ;
182175 assert ! ( io_looper. sender. is_some( ) ) ;
183176 assert_eq ! ( io_looper. executor. queue. lock( ) . unwrap( ) . len( ) , 2 ) ;
184177 assert ! ( io_looper. executor. join_handle. is_some( ) ) ;
185178 thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
186- io_looper. post_and_kill ( |callback| {
187- callback
188- . downcast_ref :: < SimpleCallback > ( )
189- . unwrap ( )
190- . print ( "last job" )
191- } ) ;
179+ io_looper. post_and_kill ( |callback| callback. print ( "last job" ) ) ;
192180 assert ! ( io_looper. sender. is_none( ) ) ;
193181 assert ! ( io_looper. executor. queue. lock( ) . unwrap( ) . is_empty( ) ) ;
194182 assert ! ( io_looper. executor. join_handle. is_none( ) ) ;
0 commit comments