xref: /haiku/src/add-ons/kernel/network/protocols/unix/UnixFifo.h (revision 4b3b81da9e459443d75329cfd08bc9a57ad02653)
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 <lock.h>
11 #include <util/AutoLock.h>
12 #include <util/DoublyLinkedList.h>
13 
14 #include <net_buffer.h>
15 
16 
17 #define UNIX_FIFO_SHUTDOWN_READ		1
18 #define UNIX_FIFO_SHUTDOWN_WRITE	2
19 
20 #define UNIX_FIFO_SHUTDOWN			1
21 	// error code returned by Read()/Write()
22 
23 #define UNIX_FIFO_MINIMAL_CAPACITY	1024
24 #define UNIX_FIFO_MAXIMAL_CAPACITY	(128 * 1024)
25 
26 
27 class UnixBufferQueue {
28 public:
29 	UnixBufferQueue(size_t capacity);
30 	~UnixBufferQueue();
31 
32 	size_t	Readable() const	{ return fSize; }
33 	size_t	Writable() const
34 		{ return fCapacity >= fSize ? fCapacity - fSize : 0; }
35 
36 	status_t Read(size_t size, net_buffer** _buffer);
37 	status_t Write(net_buffer* buffer);
38 
39 	size_t Capacity() const		{ return fCapacity; }
40 	void SetCapacity(size_t capacity);
41 
42 private:
43 	typedef DoublyLinkedList<net_buffer, DoublyLinkedListCLink<net_buffer> >
44 		BufferList;
45 
46 	BufferList	fBuffers;
47 	size_t		fSize;
48 	size_t		fCapacity;
49 };
50 
51 
52 
53 class UnixFifo : public Referenceable {
54 public:
55 	UnixFifo(size_t capacity);
56 	~UnixFifo();
57 
58 	status_t Init();
59 
60 	bool Lock()
61 	{
62 		return benaphore_lock(&fLock) == B_OK;
63 	}
64 
65 	void Unlock()
66 	{
67 		benaphore_unlock(&fLock);
68 	}
69 
70 	void Shutdown(uint32 shutdown);
71 
72 	bool IsReadShutdown() const
73 	{
74 		return (fShutdown & UNIX_FIFO_SHUTDOWN_READ);
75 	}
76 
77 	bool IsWriteShutdown() const
78 	{
79 		return (fShutdown & UNIX_FIFO_SHUTDOWN_WRITE);
80 	}
81 
82 	status_t Read(size_t numBytes, bigtime_t timeout, net_buffer** _buffer);
83 	status_t Write(net_buffer* buffer, bigtime_t timeout);
84 
85 	size_t Readable() const;
86 	size_t Writable() const;
87 
88 	void SetBufferCapacity(size_t capacity);
89 
90 private:
91 	struct Request : DoublyLinkedListLinkImpl<Request> {
92 		Request(size_t size)
93 			:
94 			size(size)
95 		{
96 		}
97 
98 		size_t		size;
99 	};
100 
101 	typedef DoublyLinkedList<Request> RequestList;
102 
103 private:
104 	status_t _Read(Request& request, size_t numBytes, bigtime_t timeout,
105 		net_buffer** _buffer);
106 	status_t _Write(Request& request, net_buffer* buffer, bigtime_t timeout);
107 
108 private:
109 	benaphore			fLock;
110 	UnixBufferQueue		fBuffer;
111 	RequestList			fReaders;
112 	RequestList			fWriters;
113 	size_t				fReadRequested;
114 	size_t				fWriteRequested;
115 	sem_id				fReaderSem;
116 	sem_id				fWriterSem;
117 	uint32				fShutdown;
118 };
119 
120 
121 typedef AutoLocker<UnixFifo> UnixFifoLocker;
122 
123 
124 #endif	// UNIX_FIFO_H
125