FIFO.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <Kernel/FileSystem/FIFO.h>
  2. #include <Kernel/FileSystem/FileDescriptor.h>
  3. #include <Kernel/Lock.h>
  4. #include <AK/StdLibExtras.h>
  5. #include <AK/HashTable.h>
  6. //#define FIFO_DEBUG
  7. Lockable<HashTable<FIFO*>>& all_fifos()
  8. {
  9. static Lockable<HashTable<FIFO*>>* s_table;
  10. if (!s_table)
  11. s_table = new Lockable<HashTable<FIFO*>>;
  12. return *s_table;
  13. }
  14. RetainPtr<FIFO> FIFO::from_fifo_id(dword id)
  15. {
  16. auto* ptr = reinterpret_cast<FIFO*>(id);
  17. LOCKER(all_fifos().lock());
  18. if (auto it = all_fifos().resource().find(ptr); it == all_fifos().resource().end())
  19. return nullptr;
  20. return ptr;
  21. }
  22. Retained<FIFO> FIFO::create(uid_t uid)
  23. {
  24. return adopt(*new FIFO(uid));
  25. }
  26. Retained<FileDescriptor> FIFO::open_direction(FIFO::Direction direction)
  27. {
  28. auto descriptor = FileDescriptor::create(this);
  29. attach(direction);
  30. descriptor->set_fifo_direction({ }, direction);
  31. return descriptor;
  32. }
  33. FIFO::FIFO(uid_t uid)
  34. : m_uid(uid)
  35. {
  36. LOCKER(all_fifos().lock());
  37. all_fifos().resource().set(this);
  38. }
  39. FIFO::~FIFO()
  40. {
  41. LOCKER(all_fifos().lock());
  42. all_fifos().resource().remove(this);
  43. }
  44. void FIFO::attach(Direction direction)
  45. {
  46. if (direction == Direction::Reader) {
  47. ++m_readers;
  48. #ifdef FIFO_DEBUG
  49. kprintf("open reader (%u)\n", m_readers);
  50. #endif
  51. } else if (direction == Direction::Writer) {
  52. ++m_writers;
  53. #ifdef FIFO_DEBUG
  54. kprintf("open writer (%u)\n", m_writers);
  55. #endif
  56. }
  57. }
  58. void FIFO::detach(Direction direction)
  59. {
  60. if (direction == Direction::Reader) {
  61. #ifdef FIFO_DEBUG
  62. kprintf("close reader (%u - 1)\n", m_readers);
  63. #endif
  64. ASSERT(m_readers);
  65. --m_readers;
  66. } else if (direction == Direction::Writer) {
  67. #ifdef FIFO_DEBUG
  68. kprintf("close writer (%u - 1)\n", m_writers);
  69. #endif
  70. ASSERT(m_writers);
  71. --m_writers;
  72. }
  73. }
  74. bool FIFO::can_read(FileDescriptor&) const
  75. {
  76. return !m_buffer.is_empty() || !m_writers;
  77. }
  78. bool FIFO::can_write(FileDescriptor&) const
  79. {
  80. return m_buffer.bytes_in_write_buffer() < 4096;
  81. }
  82. ssize_t FIFO::read(FileDescriptor&, byte* buffer, ssize_t size)
  83. {
  84. if (!m_writers && m_buffer.is_empty())
  85. return 0;
  86. #ifdef FIFO_DEBUG
  87. dbgprintf("fifo: read(%u)\n",size);
  88. #endif
  89. ssize_t nread = m_buffer.read(buffer, size);
  90. #ifdef FIFO_DEBUG
  91. dbgprintf(" -> read (%c) %u\n", buffer[0], nread);
  92. #endif
  93. return nread;
  94. }
  95. ssize_t FIFO::write(FileDescriptor&, const byte* buffer, ssize_t size)
  96. {
  97. if (!m_readers)
  98. return 0;
  99. #ifdef FIFO_DEBUG
  100. dbgprintf("fifo: write(%p, %u)\n", buffer, size);
  101. #endif
  102. return m_buffer.write(buffer, size);
  103. }
  104. String FIFO::absolute_path(const FileDescriptor&) const
  105. {
  106. return String::format("fifo:%u", this);
  107. }