1eb8b342dSIngo Weinhold /* 2eb8b342dSIngo Weinhold * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3eb8b342dSIngo Weinhold * Distributed under the terms of the MIT License. 4eb8b342dSIngo Weinhold */ 5eb8b342dSIngo Weinhold #ifndef UNIX_FIFO_H 6eb8b342dSIngo Weinhold #define UNIX_FIFO_H 7eb8b342dSIngo Weinhold 8eb8b342dSIngo Weinhold #include <Referenceable.h> 9eb8b342dSIngo Weinhold 105b29b956SIngo Weinhold #include <condition_variable.h> 11eb8b342dSIngo Weinhold #include <lock.h> 12eb8b342dSIngo Weinhold #include <util/AutoLock.h> 13eb8b342dSIngo Weinhold #include <util/DoublyLinkedList.h> 14eb8b342dSIngo Weinhold 15eb8b342dSIngo Weinhold #include <net_buffer.h> 16eb8b342dSIngo Weinhold 17eb8b342dSIngo Weinhold 18eb8b342dSIngo Weinhold #define UNIX_FIFO_SHUTDOWN_READ 1 19eb8b342dSIngo Weinhold #define UNIX_FIFO_SHUTDOWN_WRITE 2 20eb8b342dSIngo Weinhold 21eb8b342dSIngo Weinhold #define UNIX_FIFO_SHUTDOWN 1 22eb8b342dSIngo Weinhold // error code returned by Read()/Write() 23eb8b342dSIngo Weinhold 24eb8b342dSIngo Weinhold #define UNIX_FIFO_MINIMAL_CAPACITY 1024 25eb8b342dSIngo Weinhold #define UNIX_FIFO_MAXIMAL_CAPACITY (128 * 1024) 26eb8b342dSIngo Weinhold 27eb8b342dSIngo Weinhold 28*6057b5eeSIngo Weinhold #define TRACE_BUFFER_QUEUE 0 29438df7ecSIngo Weinhold 30438df7ecSIngo Weinhold 31eb8b342dSIngo Weinhold class UnixBufferQueue { 32eb8b342dSIngo Weinhold public: 33eb8b342dSIngo Weinhold UnixBufferQueue(size_t capacity); 34eb8b342dSIngo Weinhold ~UnixBufferQueue(); 35eb8b342dSIngo Weinhold 36eb8b342dSIngo Weinhold size_t Readable() const { return fSize; } 37eb8b342dSIngo Weinhold size_t Writable() const 38eb8b342dSIngo Weinhold { return fCapacity >= fSize ? fCapacity - fSize : 0; } 39eb8b342dSIngo Weinhold 40eb8b342dSIngo Weinhold status_t Read(size_t size, net_buffer** _buffer); 41cfb0e473SIngo Weinhold status_t Write(net_buffer* buffer, size_t maxSize); 42eb8b342dSIngo Weinhold 43eb8b342dSIngo Weinhold size_t Capacity() const { return fCapacity; } 44eb8b342dSIngo Weinhold void SetCapacity(size_t capacity); 45eb8b342dSIngo Weinhold 46438df7ecSIngo Weinhold #if TRACE_BUFFER_QUEUE 47438df7ecSIngo Weinhold void ParanoiaReadCheck(net_buffer* buffer); 48438df7ecSIngo Weinhold void PostReadWrite(); 49438df7ecSIngo Weinhold #endif 50438df7ecSIngo Weinhold 51eb8b342dSIngo Weinhold private: 52eb8b342dSIngo Weinhold typedef DoublyLinkedList<net_buffer, DoublyLinkedListCLink<net_buffer> > 53eb8b342dSIngo Weinhold BufferList; 54eb8b342dSIngo Weinhold 55eb8b342dSIngo Weinhold BufferList fBuffers; 56eb8b342dSIngo Weinhold size_t fSize; 57eb8b342dSIngo Weinhold size_t fCapacity; 58438df7ecSIngo Weinhold #if TRACE_BUFFER_QUEUE 59438df7ecSIngo Weinhold off_t fWritten; 60438df7ecSIngo Weinhold off_t fRead; 61438df7ecSIngo Weinhold uint8* fParanoiaCheckBuffer; 62438df7ecSIngo Weinhold uint8* fParanoiaCheckBuffer2; 63438df7ecSIngo Weinhold #endif 64eb8b342dSIngo Weinhold }; 65eb8b342dSIngo Weinhold 66eb8b342dSIngo Weinhold 67eb8b342dSIngo Weinhold 68eb8b342dSIngo Weinhold class UnixFifo : public Referenceable { 69eb8b342dSIngo Weinhold public: 70eb8b342dSIngo Weinhold UnixFifo(size_t capacity); 71eb8b342dSIngo Weinhold ~UnixFifo(); 72eb8b342dSIngo Weinhold 73eb8b342dSIngo Weinhold status_t Init(); 74eb8b342dSIngo Weinhold 75eb8b342dSIngo Weinhold bool Lock() 76eb8b342dSIngo Weinhold { 77eb8b342dSIngo Weinhold return benaphore_lock(&fLock) == B_OK; 78eb8b342dSIngo Weinhold } 79eb8b342dSIngo Weinhold 80eb8b342dSIngo Weinhold void Unlock() 81eb8b342dSIngo Weinhold { 82eb8b342dSIngo Weinhold benaphore_unlock(&fLock); 83eb8b342dSIngo Weinhold } 84eb8b342dSIngo Weinhold 85eb8b342dSIngo Weinhold void Shutdown(uint32 shutdown); 86eb8b342dSIngo Weinhold 87eb8b342dSIngo Weinhold bool IsReadShutdown() const 88eb8b342dSIngo Weinhold { 89eb8b342dSIngo Weinhold return (fShutdown & UNIX_FIFO_SHUTDOWN_READ); 90eb8b342dSIngo Weinhold } 91eb8b342dSIngo Weinhold 92eb8b342dSIngo Weinhold bool IsWriteShutdown() const 93eb8b342dSIngo Weinhold { 94eb8b342dSIngo Weinhold return (fShutdown & UNIX_FIFO_SHUTDOWN_WRITE); 95eb8b342dSIngo Weinhold } 96eb8b342dSIngo Weinhold 97eb8b342dSIngo Weinhold status_t Read(size_t numBytes, bigtime_t timeout, net_buffer** _buffer); 98eb8b342dSIngo Weinhold status_t Write(net_buffer* buffer, bigtime_t timeout); 99eb8b342dSIngo Weinhold 100eb8b342dSIngo Weinhold size_t Readable() const; 101eb8b342dSIngo Weinhold size_t Writable() const; 102eb8b342dSIngo Weinhold 103eb8b342dSIngo Weinhold void SetBufferCapacity(size_t capacity); 104eb8b342dSIngo Weinhold 105eb8b342dSIngo Weinhold private: 106eb8b342dSIngo Weinhold struct Request : DoublyLinkedListLinkImpl<Request> { 107eb8b342dSIngo Weinhold Request(size_t size) 108eb8b342dSIngo Weinhold : 109eb8b342dSIngo Weinhold size(size) 110eb8b342dSIngo Weinhold { 111eb8b342dSIngo Weinhold } 112eb8b342dSIngo Weinhold 113eb8b342dSIngo Weinhold size_t size; 114eb8b342dSIngo Weinhold }; 115eb8b342dSIngo Weinhold 116eb8b342dSIngo Weinhold typedef DoublyLinkedList<Request> RequestList; 117eb8b342dSIngo Weinhold 118eb8b342dSIngo Weinhold private: 119eb8b342dSIngo Weinhold status_t _Read(Request& request, size_t numBytes, bigtime_t timeout, 120eb8b342dSIngo Weinhold net_buffer** _buffer); 121cfb0e473SIngo Weinhold status_t _Write(Request& request, net_buffer* buffer, bigtime_t timeout, 122cfb0e473SIngo Weinhold size_t& bytesWritten); 123cfb0e473SIngo Weinhold status_t _WriteNonBlocking(Request& request, net_buffer* buffer, 124cfb0e473SIngo Weinhold size_t& bytesWritten); 125eb8b342dSIngo Weinhold 126eb8b342dSIngo Weinhold private: 127eb8b342dSIngo Weinhold benaphore fLock; 128eb8b342dSIngo Weinhold UnixBufferQueue fBuffer; 129eb8b342dSIngo Weinhold RequestList fReaders; 130eb8b342dSIngo Weinhold RequestList fWriters; 131eb8b342dSIngo Weinhold size_t fReadRequested; 132eb8b342dSIngo Weinhold size_t fWriteRequested; 1335b29b956SIngo Weinhold ConditionVariable fReadCondition; 1345b29b956SIngo Weinhold ConditionVariable fWriteCondition; 135eb8b342dSIngo Weinhold uint32 fShutdown; 136eb8b342dSIngo Weinhold }; 137eb8b342dSIngo Weinhold 138eb8b342dSIngo Weinhold 139eb8b342dSIngo Weinhold typedef AutoLocker<UnixFifo> UnixFifoLocker; 140eb8b342dSIngo Weinhold 141eb8b342dSIngo Weinhold 142eb8b342dSIngo Weinhold #endif // UNIX_FIFO_H 143