diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index f762cf65a014818f4387a74640da0c0b7afadfa7..c0dece69cf866a82eaf91446073d66de9477f936 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -414,7 +414,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage,
 
 	if (node.space->purpose == FIL_TYPE_TEMPORARY
 	    && innodb_encrypt_temporary_tables) {
-		slot = buf_pool.io_buf_reserve();
+		slot = buf_pool.io_buf_reserve(false);
 		ut_a(slot);
 		slot->allocate();
 
@@ -444,7 +444,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage,
 			return false;
 		}
 
-		slot = buf_pool.io_buf_reserve();
+		slot = buf_pool.io_buf_reserve(false);
 		slot->allocate();
 
 decompress_with_slot:
@@ -471,7 +471,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage,
 			return false;
 		}
 
-		slot = buf_pool.io_buf_reserve();
+		slot = buf_pool.io_buf_reserve(false);
 		slot->allocate();
 		ut_d(fil_page_type_validate(node.space, dst_frame));
 
@@ -1513,14 +1513,17 @@ void buf_pool_t::io_buf_t::close()
   n_slots= 0;
 }
 
-buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve()
+buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads)
 {
   for (;;)
   {
     for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
       if (s->acquire())
         return s;
+    buf_dblwr.flush_buffered_writes();
     os_aio_wait_until_no_pending_writes();
+    if (!wait_for_reads)
+      continue;
     for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
       if (s->acquire())
         return s;
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 770083127276a652e27386aadb2a49aae3a26884..186fb89ddced4f8ca0fad6b16505794d0b51eedd 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -702,7 +702,7 @@ static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s,
 
   ut_ad(!bpage->zip_size() || !page_compressed);
   /* Find free slot from temporary memory array */
-  buf_tmp_buffer_t *slot= buf_pool.io_buf_reserve();
+  buf_tmp_buffer_t *slot= buf_pool.io_buf_reserve(true);
   ut_a(slot);
   slot->allocate();
   slot->out_buf= NULL;
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index def7641db1d1636a01f07de4f1d1102158cbf2b6..0e1a4c27f35e6013108ff0f764cf37461b742d5e 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -2030,7 +2030,8 @@ class buf_pool_t
   a delete-buffering operation is pending. Protected by mutex. */
   buf_page_t watch[innodb_purge_threads_MAX + 1];
   /** Reserve a buffer. */
-  buf_tmp_buffer_t *io_buf_reserve() { return io_buf.reserve(); }
+  buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads)
+  { return io_buf.reserve(wait_for_reads); }
 
   /** @return whether any I/O is pending */
   bool any_io_pending()
@@ -2083,7 +2084,7 @@ class buf_pool_t
     void close();
 
     /** Reserve a buffer */
-    buf_tmp_buffer_t *reserve();
+    buf_tmp_buffer_t *reserve(bool wait_for_reads);
   } io_buf;
 
   /** whether resize() is in the critical path */
diff --git a/tpool/tpool_structs.h b/tpool/tpool_structs.h
index b49204f2d75ac190a79f63aac2f6b3db68302853..96c250ebd59bf2f0706642af7282177379bacf7a 100644
--- a/tpool/tpool_structs.h
+++ b/tpool/tpool_structs.h
@@ -138,12 +138,13 @@ template<typename T> class cache
   {
     std::unique_lock<std::mutex> lk(m_mtx);
     assert(!is_full());
+    const bool was_empty= is_empty();
     // put element to the logical end of the array
     m_cache[--m_pos] = ele;
 
     /* Notify waiters  when the cache becomes
      not empty, or when it becomes full */
-    if (m_pos == 1 || (m_waiters && is_full()))
+    if (was_empty || (is_full() && m_waiters))
       m_cv.notify_all();
   }