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