فهرست منبع

Add internal locking to DoubleBuffer.

Andreas Kling 6 سال پیش
والد
کامیت
52c004eb53
2فایلهای تغییر یافته به همراه16 افزوده شده و 2 حذف شده
  1. 10 1
      Kernel/DoubleBuffer.cpp
  2. 6 1
      Kernel/DoubleBuffer.h

+ 10 - 1
Kernel/DoubleBuffer.cpp

@@ -1,8 +1,12 @@
 #include "DoubleBuffer.h"
 
+inline void DoubleBuffer::compute_emptiness()
+{
+    m_empty = m_read_buffer_index >= m_read_buffer->size() && m_write_buffer->is_empty();
+}
+
 void DoubleBuffer::flip()
 {
-    InterruptDisabler disabler;
     ASSERT(m_read_buffer_index == m_read_buffer->size());
     swap(m_read_buffer, m_write_buffer);
     if (m_write_buffer->capacity() < 32)
@@ -10,16 +14,20 @@ void DoubleBuffer::flip()
     else
         m_write_buffer->clear();
     m_read_buffer_index = 0;
+    compute_emptiness();
 }
 
 ssize_t DoubleBuffer::write(const byte* data, size_t size)
 {
+    LOCKER(m_lock);
     m_write_buffer->append(data, size);
+    compute_emptiness();
     return size;
 }
 
 ssize_t DoubleBuffer::read(byte* data, size_t size)
 {
+    LOCKER(m_lock);
     if (m_read_buffer_index >= m_read_buffer->size() && !m_write_buffer->is_empty())
         flip();
     if (m_read_buffer_index >= m_read_buffer->size())
@@ -27,5 +35,6 @@ ssize_t DoubleBuffer::read(byte* data, size_t size)
     ssize_t nread = min(m_read_buffer->size() - m_read_buffer_index, size);
     memcpy(data, m_read_buffer->data() + m_read_buffer_index, nread);
     m_read_buffer_index += nread;
+    compute_emptiness();
     return nread;
 }

+ 6 - 1
Kernel/DoubleBuffer.h

@@ -2,6 +2,7 @@
 
 #include <AK/Types.h>
 #include <AK/Vector.h>
+#include <AK/Lock.h>
 
 class DoubleBuffer {
 public:
@@ -14,16 +15,20 @@ public:
     ssize_t write(const byte*, size_t);
     ssize_t read(byte*, size_t);
 
-    bool is_empty() const { return m_read_buffer_index >= m_read_buffer->size() && m_write_buffer->is_empty(); }
+    bool is_empty() const { return m_empty; }
 
+    // FIXME: Isn't this racy? What if we get interrupted between getting the buffer pointer and dereferencing it?
     size_t bytes_in_write_buffer() const { return m_write_buffer->size(); }
 
 private:
     void flip();
+    void compute_emptiness();
 
     Vector<byte>* m_write_buffer { nullptr };
     Vector<byte>* m_read_buffer { nullptr };
     Vector<byte> m_buffer1;
     Vector<byte> m_buffer2;
     size_t m_read_buffer_index { 0 };
+    bool m_empty { true };
+    SpinLock m_lock;
 };