11use std:: {
22 io:: { self , ErrorKind , SeekFrom } ,
3- ops:: DerefMut ,
43 pin:: Pin ,
5- sync:: { Arc , Mutex } ,
64 task:: { Context , Poll } ,
75} ;
86
@@ -17,7 +15,7 @@ use crate::api::{
1715pub struct Reader {
1816 blobs : Blobs ,
1917 options : ReaderOptions ,
20- state : Arc < Mutex < ReaderState > > ,
18+ state : ReaderState ,
2119}
2220
2321#[ derive( Default , derive_more:: Debug ) ]
@@ -42,7 +40,7 @@ impl Reader {
4240 Self {
4341 blobs,
4442 options,
45- state : Arc :: new ( Mutex :: new ( ReaderState :: Idle { position : 0 } ) ) ,
43+ state : ReaderState :: Idle { position : 0 } ,
4644 }
4745 }
4846}
@@ -56,8 +54,8 @@ impl tokio::io::AsyncRead for Reader {
5654 let this = self . get_mut ( ) ;
5755 let mut position1 = None ;
5856 loop {
59- let mut guard = this. state . lock ( ) . unwrap ( ) ;
60- match std:: mem:: take ( guard. deref_mut ( ) ) {
57+ let guard = & mut this. state ;
58+ match std:: mem:: take ( guard) {
6159 ReaderState :: Idle { position } => {
6260 // todo: read until next page boundary instead of fixed size
6361 let len = buf. remaining ( ) as u64 ;
@@ -78,6 +76,9 @@ impl tokio::io::AsyncRead for Reader {
7876 ReaderState :: Reading { position, mut op } => {
7977 let position1 = position1. get_or_insert ( position) ;
8078 match op. poll_next ( cx) {
79+ Poll :: Ready ( Some ( ExportRangesItem :: Size ( _) ) ) => {
80+ * guard = ReaderState :: Reading { position, op } ;
81+ }
8182 Poll :: Ready ( Some ( ExportRangesItem :: Data ( data) ) ) => {
8283 if data. offset != * position1 {
8384 break Poll :: Ready ( Err ( io:: Error :: other (
@@ -96,13 +97,9 @@ impl tokio::io::AsyncRead for Reader {
9697 }
9798 Poll :: Ready ( Some ( ExportRangesItem :: Error ( err) ) ) => {
9899 * guard = ReaderState :: Idle { position } ;
99- break Poll :: Ready ( Err ( io:: Error :: other (
100- format ! ( "Error reading data: {err}" ) ,
101- ) ) ) ;
102- }
103- Poll :: Ready ( Some ( ExportRangesItem :: Size ( _size) ) ) => {
104- // put back the state and continue reading
105- * guard = ReaderState :: Reading { position, op } ;
100+ break Poll :: Ready ( Err ( io:: Error :: other ( format ! (
101+ "Error reading data: {err}"
102+ ) ) ) ) ;
106103 }
107104 Poll :: Ready ( None ) => {
108105 // done with the stream, go back in idle.
@@ -134,10 +131,9 @@ impl tokio::io::AsyncRead for Reader {
134131 }
135132 }
136133 state @ ReaderState :: Seeking { .. } => {
137- * this. state . lock ( ) . unwrap ( ) = state;
138- break Poll :: Ready ( Err ( io:: Error :: other (
139- "Can't read while seeking" ,
140- ) ) ) ;
134+ // should I try to recover from this or just keep it poisoned?
135+ this. state = state;
136+ break Poll :: Ready ( Err ( io:: Error :: other ( "Can't read while seeking" ) ) ) ;
141137 }
142138 ReaderState :: Poisoned => {
143139 break Poll :: Ready ( Err ( io:: Error :: other ( "Reader is poisoned" ) ) ) ;
@@ -153,8 +149,8 @@ impl tokio::io::AsyncSeek for Reader {
153149 seek_from : tokio:: io:: SeekFrom ,
154150 ) -> io:: Result < ( ) > {
155151 let this = self . get_mut ( ) ;
156- let mut guard = this. state . lock ( ) . unwrap ( ) ;
157- match std:: mem:: take ( guard. deref_mut ( ) ) {
152+ let guard = & mut this. state ;
153+ match std:: mem:: take ( guard) {
158154 ReaderState :: Idle { position } => {
159155 let position1 = match seek_from {
160156 SeekFrom :: Start ( pos) => pos,
@@ -187,8 +183,8 @@ impl tokio::io::AsyncSeek for Reader {
187183
188184 fn poll_complete ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > ) -> Poll < io:: Result < u64 > > {
189185 let this = self . get_mut ( ) ;
190- let mut guard = this. state . lock ( ) . unwrap ( ) ;
191- Poll :: Ready ( match std:: mem:: take ( guard. deref_mut ( ) ) {
186+ let guard = & mut this. state ;
187+ Poll :: Ready ( match std:: mem:: take ( guard) {
192188 ReaderState :: Seeking { position } => {
193189 * guard = ReaderState :: Idle { position } ;
194190 Ok ( position)
@@ -199,7 +195,11 @@ impl tokio::io::AsyncSeek for Reader {
199195 * guard = ReaderState :: Idle { position } ;
200196 Ok ( position)
201197 }
202- ReaderState :: Reading { .. } => Err ( io:: Error :: other ( "Can't seek while reading" ) ) ,
198+ state @ ReaderState :: Reading { .. } => {
199+ // should I try to recover from this or just keep it poisoned?
200+ * guard = state;
201+ Err ( io:: Error :: other ( "Can't seek while reading" ) )
202+ }
203203 ReaderState :: Poisoned => Err ( io:: Error :: other ( "Reader is poisoned" ) ) ,
204204 } )
205205 }
0 commit comments