@@ -191,6 +191,25 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, void* ptr) {
191191}
192192
193193
194+ void NodeBIO::TryMoveReadHead () {
195+ // `read_pos_` and `write_pos_` means the position of the reader and writer
196+ // inside the buffer, respectively. When they're equal - its safe to reset
197+ // them, because both reader and writer will continue doing their stuff
198+ // from new (zero) positions.
199+ if (read_head_->read_pos_ != read_head_->write_pos_ )
200+ return ;
201+
202+ // Reset positions
203+ read_head_->read_pos_ = 0 ;
204+ read_head_->write_pos_ = 0 ;
205+
206+ // Move read_head_ forward, just in case if there're still some data to
207+ // read in the next buffer.
208+ if (read_head_ != write_head_)
209+ read_head_ = read_head_->next_ ;
210+ }
211+
212+
194213size_t NodeBIO::Read (char * out, size_t size) {
195214 size_t bytes_read = 0 ;
196215 size_t expected = Length () > size ? size : Length ();
@@ -213,16 +232,7 @@ size_t NodeBIO::Read(char* out, size_t size) {
213232 offset += avail;
214233 left -= avail;
215234
216- // Move to next buffer
217- if (read_head_->read_pos_ == read_head_->write_pos_ ) {
218- read_head_->read_pos_ = 0 ;
219- read_head_->write_pos_ = 0 ;
220-
221- // But not get beyond write_head_
222- if (length_ != bytes_read && read_head_ != write_head_) {
223- read_head_ = read_head_->next_ ;
224- }
225- }
235+ TryMoveReadHead ();
226236 }
227237 assert (expected == bytes_read);
228238 length_ -= bytes_read;
@@ -331,6 +341,10 @@ void NodeBIO::Write(const char* data, size_t size) {
331341 assert (write_head_->write_pos_ == kBufferLength );
332342 TryAllocateForWrite ();
333343 write_head_ = write_head_->next_ ;
344+
345+ // Additionally, since we're moved to the next buffer, read head
346+ // may be moved as well.
347+ TryMoveReadHead ();
334348 }
335349 }
336350 assert (left == 0 );
0 commit comments