xref: /haiku/src/add-ons/kernel/network/protocols/unix/UnixFifo.h (revision e797b484d0a37fdb48a1e065264f91a57822c002)
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