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