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 28b7b57869STrung Nguyen enum class UnixFifoType { 29b7b57869STrung Nguyen Stream, 30b7b57869STrung Nguyen Datagram 31b7b57869STrung Nguyen }; 32b7b57869STrung Nguyen 33b7b57869STrung Nguyen 34ea035707SIngo Weinhold struct ring_buffer; 35ea035707SIngo Weinhold 36ea035707SIngo Weinhold class UnixRequest : public DoublyLinkedListLinkImpl<UnixRequest> { 37ea035707SIngo Weinhold public: 38ea035707SIngo Weinhold UnixRequest(const iovec* vecs, size_t count, 39b7b57869STrung Nguyen ancillary_data_container* ancillaryData, 40b7b57869STrung Nguyen struct sockaddr_storage* address); 41ea035707SIngo Weinhold TotalSize()42ea035707SIngo Weinhold off_t TotalSize() const { return fTotalSize; } BytesTransferred()43ea035707SIngo Weinhold off_t BytesTransferred() const { return fBytesTransferred; } BytesRemaining()44ea035707SIngo Weinhold off_t BytesRemaining() const { return fTotalSize - fBytesTransferred; } 45ea035707SIngo Weinhold 46ea035707SIngo Weinhold void AddBytesTransferred(size_t size); 47ea035707SIngo Weinhold bool GetCurrentChunk(void*& data, size_t& size); 48ea035707SIngo Weinhold AncillaryData()49ea035707SIngo Weinhold ancillary_data_container* AncillaryData() const { return fAncillaryData; } 50ea035707SIngo Weinhold void AddAncillaryData(ancillary_data_container* data); 513fb6cfceSAugustin Cavalier void UnsetAncillaryData(); 52ea035707SIngo Weinhold Address()53b7b57869STrung Nguyen struct sockaddr_storage* Address() const { return fAddress; } 54b7b57869STrung Nguyen 55ea035707SIngo Weinhold private: 56ea035707SIngo Weinhold const iovec* fVecs; 57ea035707SIngo Weinhold size_t fVecCount; 58ea035707SIngo Weinhold ancillary_data_container* fAncillaryData; 59ea035707SIngo Weinhold off_t fTotalSize; 60ea035707SIngo Weinhold off_t fBytesTransferred; 61ea035707SIngo Weinhold size_t fVecIndex; 62ea035707SIngo Weinhold size_t fVecOffset; 63b7b57869STrung Nguyen struct sockaddr_storage* fAddress; 64ea035707SIngo Weinhold }; 65438df7ecSIngo Weinhold 66438df7ecSIngo Weinhold 67eb8b342dSIngo Weinhold class UnixBufferQueue { 68eb8b342dSIngo Weinhold public: 69b7b57869STrung Nguyen UnixBufferQueue(size_t capacity, UnixFifoType type); 70eb8b342dSIngo Weinhold ~UnixBufferQueue(); 71eb8b342dSIngo Weinhold 72ea035707SIngo Weinhold status_t Init(); 73eb8b342dSIngo Weinhold 74ea035707SIngo Weinhold size_t Readable() const; 75ea035707SIngo Weinhold size_t Writable() const; 76ea035707SIngo Weinhold 77ea035707SIngo Weinhold status_t Read(UnixRequest& request); 78ea035707SIngo Weinhold status_t Write(UnixRequest& request); 79eb8b342dSIngo Weinhold Capacity()80eb8b342dSIngo Weinhold size_t Capacity() const { return fCapacity; } 81ea035707SIngo Weinhold status_t SetCapacity(size_t capacity); 82438df7ecSIngo Weinhold 83eb8b342dSIngo Weinhold private: 84ea035707SIngo Weinhold struct AncillaryDataEntry : DoublyLinkedListLinkImpl<AncillaryDataEntry> { 85ea035707SIngo Weinhold ancillary_data_container* data; 86ea035707SIngo Weinhold size_t offset; 87eb8b342dSIngo Weinhold }; 88eb8b342dSIngo Weinhold 89ea035707SIngo Weinhold typedef DoublyLinkedList<AncillaryDataEntry> AncillaryDataList; 90ea035707SIngo Weinhold 91b7b57869STrung Nguyen struct DatagramEntry : DoublyLinkedListLinkImpl<DatagramEntry> { 92b7b57869STrung Nguyen struct sockaddr_storage address; 93b7b57869STrung Nguyen size_t size; 94b7b57869STrung Nguyen }; 95b7b57869STrung Nguyen 96b7b57869STrung Nguyen typedef DoublyLinkedList<DatagramEntry> DatagramList; 97b7b57869STrung Nguyen 98ea035707SIngo Weinhold ring_buffer* fBuffer; 99ea035707SIngo Weinhold size_t fCapacity; 100ea035707SIngo Weinhold AncillaryDataList fAncillaryData; 101b7b57869STrung Nguyen DatagramList fDatagrams; 102b7b57869STrung Nguyen UnixFifoType fType; 103ea035707SIngo Weinhold }; 104eb8b342dSIngo Weinhold 105eb8b342dSIngo Weinhold 106*e797b484SAugustin Cavalier class UnixFifo final : public BReferenceable { 107eb8b342dSIngo Weinhold public: 108b7b57869STrung Nguyen UnixFifo(size_t capacity, UnixFifoType type); 109eb8b342dSIngo Weinhold ~UnixFifo(); 110eb8b342dSIngo Weinhold 111eb8b342dSIngo Weinhold status_t Init(); 112eb8b342dSIngo Weinhold Lock()113eb8b342dSIngo Weinhold bool Lock() 114eb8b342dSIngo Weinhold { 11539ae5e4dSIngo Weinhold return mutex_lock(&fLock) == B_OK; 116eb8b342dSIngo Weinhold } 117eb8b342dSIngo Weinhold Unlock()118eb8b342dSIngo Weinhold void Unlock() 119eb8b342dSIngo Weinhold { 12039ae5e4dSIngo Weinhold mutex_unlock(&fLock); 121eb8b342dSIngo Weinhold } 122eb8b342dSIngo Weinhold 123eb8b342dSIngo Weinhold void Shutdown(uint32 shutdown); 124eb8b342dSIngo Weinhold IsReadShutdown()125eb8b342dSIngo Weinhold bool IsReadShutdown() const 126eb8b342dSIngo Weinhold { 127eb8b342dSIngo Weinhold return (fShutdown & UNIX_FIFO_SHUTDOWN_READ); 128eb8b342dSIngo Weinhold } 129eb8b342dSIngo Weinhold IsWriteShutdown()130eb8b342dSIngo Weinhold bool IsWriteShutdown() const 131eb8b342dSIngo Weinhold { 132eb8b342dSIngo Weinhold return (fShutdown & UNIX_FIFO_SHUTDOWN_WRITE); 133eb8b342dSIngo Weinhold } 134eb8b342dSIngo Weinhold 135ea035707SIngo Weinhold ssize_t Read(const iovec* vecs, size_t vecCount, 136b7b57869STrung Nguyen ancillary_data_container** _ancillaryData, 137b7b57869STrung Nguyen struct sockaddr_storage* address, bigtime_t timeout); 138ea035707SIngo Weinhold ssize_t Write(const iovec* vecs, size_t vecCount, 139b7b57869STrung Nguyen ancillary_data_container* ancillaryData, 140b7b57869STrung Nguyen const struct sockaddr_storage* address, bigtime_t timeout); 141eb8b342dSIngo Weinhold 142eb8b342dSIngo Weinhold size_t Readable() const; 143eb8b342dSIngo Weinhold size_t Writable() const; 144eb8b342dSIngo Weinhold 145ea035707SIngo Weinhold status_t SetBufferCapacity(size_t capacity); 146eb8b342dSIngo Weinhold 147eb8b342dSIngo Weinhold private: 148ea035707SIngo Weinhold typedef DoublyLinkedList<UnixRequest> RequestList; 149eb8b342dSIngo Weinhold 150eb8b342dSIngo Weinhold private: 151ea035707SIngo Weinhold status_t _Read(UnixRequest& request, bigtime_t timeout); 152ea035707SIngo Weinhold status_t _Write(UnixRequest& request, bigtime_t timeout); 153ea035707SIngo Weinhold status_t _WriteNonBlocking(UnixRequest& request); 154b7b57869STrung Nguyen size_t _MinimumWritableSize(const UnixRequest& request) const; 155eb8b342dSIngo Weinhold 156eb8b342dSIngo Weinhold private: 15739ae5e4dSIngo Weinhold mutex fLock; 158eb8b342dSIngo Weinhold UnixBufferQueue fBuffer; 159eb8b342dSIngo Weinhold RequestList fReaders; 160eb8b342dSIngo Weinhold RequestList fWriters; 161ea035707SIngo Weinhold off_t fReadRequested; 162ea035707SIngo Weinhold off_t fWriteRequested; 1635b29b956SIngo Weinhold ConditionVariable fReadCondition; 1645b29b956SIngo Weinhold ConditionVariable fWriteCondition; 165eb8b342dSIngo Weinhold uint32 fShutdown; 166b7b57869STrung Nguyen UnixFifoType fType; 167eb8b342dSIngo Weinhold }; 168eb8b342dSIngo Weinhold 169eb8b342dSIngo Weinhold 170eb8b342dSIngo Weinhold typedef AutoLocker<UnixFifo> UnixFifoLocker; 171eb8b342dSIngo Weinhold 172eb8b342dSIngo Weinhold 173eb8b342dSIngo Weinhold #endif // UNIX_FIFO_H 174