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 21ea035707SIngo Weinhold #define UNIX_FIFO_SHUTDOWN (B_ERRORS_END + 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 28ea035707SIngo Weinhold struct ring_buffer; 29ea035707SIngo Weinhold 30ea035707SIngo Weinhold class UnixRequest : public DoublyLinkedListLinkImpl<UnixRequest> { 31ea035707SIngo Weinhold public: 32ea035707SIngo Weinhold UnixRequest(const iovec* vecs, size_t count, 33ea035707SIngo Weinhold ancillary_data_container* ancillaryData); 34ea035707SIngo Weinhold 35ea035707SIngo Weinhold off_t TotalSize() const { return fTotalSize; } 36ea035707SIngo Weinhold off_t BytesTransferred() const { return fBytesTransferred; } 37ea035707SIngo Weinhold off_t BytesRemaining() const { return fTotalSize - fBytesTransferred; } 38ea035707SIngo Weinhold 39ea035707SIngo Weinhold void AddBytesTransferred(size_t size); 40ea035707SIngo Weinhold bool GetCurrentChunk(void*& data, size_t& size); 41ea035707SIngo Weinhold 42ea035707SIngo Weinhold ancillary_data_container* AncillaryData() const { return fAncillaryData; } 43ea035707SIngo Weinhold void SetAncillaryData(ancillary_data_container* data); 44ea035707SIngo Weinhold void AddAncillaryData(ancillary_data_container* data); 45ea035707SIngo Weinhold 46ea035707SIngo Weinhold private: 47ea035707SIngo Weinhold const iovec* fVecs; 48ea035707SIngo Weinhold size_t fVecCount; 49ea035707SIngo Weinhold ancillary_data_container* fAncillaryData; 50ea035707SIngo Weinhold off_t fTotalSize; 51ea035707SIngo Weinhold off_t fBytesTransferred; 52ea035707SIngo Weinhold size_t fVecIndex; 53ea035707SIngo Weinhold size_t fVecOffset; 54ea035707SIngo Weinhold }; 55438df7ecSIngo Weinhold 56438df7ecSIngo Weinhold 57eb8b342dSIngo Weinhold class UnixBufferQueue { 58eb8b342dSIngo Weinhold public: 59eb8b342dSIngo Weinhold UnixBufferQueue(size_t capacity); 60eb8b342dSIngo Weinhold ~UnixBufferQueue(); 61eb8b342dSIngo Weinhold 62ea035707SIngo Weinhold status_t Init(); 63eb8b342dSIngo Weinhold 64ea035707SIngo Weinhold size_t Readable() const; 65ea035707SIngo Weinhold size_t Writable() const; 66ea035707SIngo Weinhold 67ea035707SIngo Weinhold status_t Read(UnixRequest& request); 68ea035707SIngo Weinhold status_t Write(UnixRequest& request); 69eb8b342dSIngo Weinhold 70eb8b342dSIngo Weinhold size_t Capacity() const { return fCapacity; } 71ea035707SIngo Weinhold status_t SetCapacity(size_t capacity); 72438df7ecSIngo Weinhold 73eb8b342dSIngo Weinhold private: 74ea035707SIngo Weinhold struct AncillaryDataEntry : DoublyLinkedListLinkImpl<AncillaryDataEntry> { 75ea035707SIngo Weinhold ancillary_data_container* data; 76ea035707SIngo Weinhold size_t offset; 77eb8b342dSIngo Weinhold }; 78eb8b342dSIngo Weinhold 79ea035707SIngo Weinhold typedef DoublyLinkedList<AncillaryDataEntry> AncillaryDataList; 80ea035707SIngo Weinhold 81ea035707SIngo Weinhold ring_buffer* fBuffer; 82ea035707SIngo Weinhold size_t fCapacity; 83ea035707SIngo Weinhold AncillaryDataList fAncillaryData; 84ea035707SIngo Weinhold }; 85eb8b342dSIngo Weinhold 86eb8b342dSIngo Weinhold 87*88e38c17SIngo Weinhold class UnixFifo : public BReferenceable { 88eb8b342dSIngo Weinhold public: 89eb8b342dSIngo Weinhold UnixFifo(size_t capacity); 90eb8b342dSIngo Weinhold ~UnixFifo(); 91eb8b342dSIngo Weinhold 92eb8b342dSIngo Weinhold status_t Init(); 93eb8b342dSIngo Weinhold 94eb8b342dSIngo Weinhold bool Lock() 95eb8b342dSIngo Weinhold { 9639ae5e4dSIngo Weinhold return mutex_lock(&fLock) == B_OK; 97eb8b342dSIngo Weinhold } 98eb8b342dSIngo Weinhold 99eb8b342dSIngo Weinhold void Unlock() 100eb8b342dSIngo Weinhold { 10139ae5e4dSIngo Weinhold mutex_unlock(&fLock); 102eb8b342dSIngo Weinhold } 103eb8b342dSIngo Weinhold 104eb8b342dSIngo Weinhold void Shutdown(uint32 shutdown); 105eb8b342dSIngo Weinhold 106eb8b342dSIngo Weinhold bool IsReadShutdown() const 107eb8b342dSIngo Weinhold { 108eb8b342dSIngo Weinhold return (fShutdown & UNIX_FIFO_SHUTDOWN_READ); 109eb8b342dSIngo Weinhold } 110eb8b342dSIngo Weinhold 111eb8b342dSIngo Weinhold bool IsWriteShutdown() const 112eb8b342dSIngo Weinhold { 113eb8b342dSIngo Weinhold return (fShutdown & UNIX_FIFO_SHUTDOWN_WRITE); 114eb8b342dSIngo Weinhold } 115eb8b342dSIngo Weinhold 116ea035707SIngo Weinhold ssize_t Read(const iovec* vecs, size_t vecCount, 117ea035707SIngo Weinhold ancillary_data_container** _ancillaryData, bigtime_t timeout); 118ea035707SIngo Weinhold ssize_t Write(const iovec* vecs, size_t vecCount, 119ea035707SIngo Weinhold ancillary_data_container* ancillaryData, bigtime_t timeout); 120eb8b342dSIngo Weinhold 121eb8b342dSIngo Weinhold size_t Readable() const; 122eb8b342dSIngo Weinhold size_t Writable() const; 123eb8b342dSIngo Weinhold 124ea035707SIngo Weinhold status_t SetBufferCapacity(size_t capacity); 125eb8b342dSIngo Weinhold 126eb8b342dSIngo Weinhold private: 127ea035707SIngo Weinhold typedef DoublyLinkedList<UnixRequest> RequestList; 128eb8b342dSIngo Weinhold 129eb8b342dSIngo Weinhold private: 130ea035707SIngo Weinhold status_t _Read(UnixRequest& request, bigtime_t timeout); 131ea035707SIngo Weinhold status_t _Write(UnixRequest& request, bigtime_t timeout); 132ea035707SIngo Weinhold status_t _WriteNonBlocking(UnixRequest& request); 133eb8b342dSIngo Weinhold 134eb8b342dSIngo Weinhold private: 13539ae5e4dSIngo Weinhold mutex fLock; 136eb8b342dSIngo Weinhold UnixBufferQueue fBuffer; 137eb8b342dSIngo Weinhold RequestList fReaders; 138eb8b342dSIngo Weinhold RequestList fWriters; 139ea035707SIngo Weinhold off_t fReadRequested; 140ea035707SIngo Weinhold off_t fWriteRequested; 1415b29b956SIngo Weinhold ConditionVariable fReadCondition; 1425b29b956SIngo Weinhold ConditionVariable fWriteCondition; 143eb8b342dSIngo Weinhold uint32 fShutdown; 144eb8b342dSIngo Weinhold }; 145eb8b342dSIngo Weinhold 146eb8b342dSIngo Weinhold 147eb8b342dSIngo Weinhold typedef AutoLocker<UnixFifo> UnixFifoLocker; 148eb8b342dSIngo Weinhold 149eb8b342dSIngo Weinhold 150eb8b342dSIngo Weinhold #endif // UNIX_FIFO_H 151