xref: /haiku/src/add-ons/kernel/file_systems/netfs/shared/PortChannel.cpp (revision 5a1d355fdf2747f80f8c46e2539f844a0b813346)
1*5a1d355fSStephan Aßmus // PortChannel.cpp
2*5a1d355fSStephan Aßmus 
3*5a1d355fSStephan Aßmus #include <new>
4*5a1d355fSStephan Aßmus #include <string.h>
5*5a1d355fSStephan Aßmus 
6*5a1d355fSStephan Aßmus #include "PortChannel.h"
7*5a1d355fSStephan Aßmus #include "Utils.h"
8*5a1d355fSStephan Aßmus 
9*5a1d355fSStephan Aßmus static const int32 kMaxPortMessageSize = 102400;	// 100 KB
10*5a1d355fSStephan Aßmus static const int32 kDefaultBufferSize	= 10240;	// 10 KB
11*5a1d355fSStephan Aßmus 
12*5a1d355fSStephan Aßmus // constructor
PortChannel()13*5a1d355fSStephan Aßmus PortChannel::PortChannel()
14*5a1d355fSStephan Aßmus 	: Channel(),
15*5a1d355fSStephan Aßmus 	  fSendPort(-1),
16*5a1d355fSStephan Aßmus 	  fReceivePort(-1),
17*5a1d355fSStephan Aßmus 	  fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]),
18*5a1d355fSStephan Aßmus 	  fBufferSize(kDefaultBufferSize),
19*5a1d355fSStephan Aßmus 	  fBufferOffset(0),
20*5a1d355fSStephan Aßmus 	  fBufferContentSize(0)
21*5a1d355fSStephan Aßmus {
22*5a1d355fSStephan Aßmus 	fSendPort = create_port(10, "port connection send port");
23*5a1d355fSStephan Aßmus 	fReceivePort = create_port(10, "port connection receive port");
24*5a1d355fSStephan Aßmus }
25*5a1d355fSStephan Aßmus 
26*5a1d355fSStephan Aßmus // constructor
PortChannel(const Info * info,bool inverse)27*5a1d355fSStephan Aßmus PortChannel::PortChannel(const Info* info, bool inverse)
28*5a1d355fSStephan Aßmus 	: Channel(),
29*5a1d355fSStephan Aßmus 	  fSendPort(inverse ? info->receivePort : info->sendPort),
30*5a1d355fSStephan Aßmus 	  fReceivePort(inverse ? info->sendPort : info->receivePort),
31*5a1d355fSStephan Aßmus 	  fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]),
32*5a1d355fSStephan Aßmus 	  fBufferSize(kDefaultBufferSize),
33*5a1d355fSStephan Aßmus 	  fBufferOffset(0),
34*5a1d355fSStephan Aßmus 	  fBufferContentSize(0)
35*5a1d355fSStephan Aßmus {
36*5a1d355fSStephan Aßmus }
37*5a1d355fSStephan Aßmus 
38*5a1d355fSStephan Aßmus // constructor
PortChannel(port_id sendPort,port_id receivePort)39*5a1d355fSStephan Aßmus PortChannel::PortChannel(port_id sendPort, port_id receivePort)
40*5a1d355fSStephan Aßmus 	: Channel(),
41*5a1d355fSStephan Aßmus 	  fSendPort(sendPort),
42*5a1d355fSStephan Aßmus 	  fReceivePort(receivePort),
43*5a1d355fSStephan Aßmus 	  fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]),
44*5a1d355fSStephan Aßmus 	  fBufferSize(kDefaultBufferSize),
45*5a1d355fSStephan Aßmus 	  fBufferOffset(0),
46*5a1d355fSStephan Aßmus 	  fBufferContentSize(0)
47*5a1d355fSStephan Aßmus {
48*5a1d355fSStephan Aßmus }
49*5a1d355fSStephan Aßmus 
50*5a1d355fSStephan Aßmus // destructor
~PortChannel()51*5a1d355fSStephan Aßmus PortChannel::~PortChannel()
52*5a1d355fSStephan Aßmus {
53*5a1d355fSStephan Aßmus 	delete[] fBuffer;
54*5a1d355fSStephan Aßmus }
55*5a1d355fSStephan Aßmus 
56*5a1d355fSStephan Aßmus // InitCheck
57*5a1d355fSStephan Aßmus status_t
InitCheck() const58*5a1d355fSStephan Aßmus PortChannel::InitCheck() const
59*5a1d355fSStephan Aßmus {
60*5a1d355fSStephan Aßmus 	if (fSendPort < 0)
61*5a1d355fSStephan Aßmus 		return fSendPort;
62*5a1d355fSStephan Aßmus 	if (fReceivePort < 0)
63*5a1d355fSStephan Aßmus 		return fReceivePort;
64*5a1d355fSStephan Aßmus 	if (!fBuffer)
65*5a1d355fSStephan Aßmus 		return B_NO_MEMORY;
66*5a1d355fSStephan Aßmus 	return B_OK;
67*5a1d355fSStephan Aßmus }
68*5a1d355fSStephan Aßmus 
69*5a1d355fSStephan Aßmus // GetInfo
70*5a1d355fSStephan Aßmus void
GetInfo(Info * info) const71*5a1d355fSStephan Aßmus PortChannel::GetInfo(Info* info) const
72*5a1d355fSStephan Aßmus {
73*5a1d355fSStephan Aßmus 	if (info) {
74*5a1d355fSStephan Aßmus 		info->sendPort = fSendPort;
75*5a1d355fSStephan Aßmus 		info->receivePort = fReceivePort;
76*5a1d355fSStephan Aßmus 	}
77*5a1d355fSStephan Aßmus }
78*5a1d355fSStephan Aßmus 
79*5a1d355fSStephan Aßmus // Close
80*5a1d355fSStephan Aßmus void
Close()81*5a1d355fSStephan Aßmus PortChannel::Close()
82*5a1d355fSStephan Aßmus {
83*5a1d355fSStephan Aßmus 	if (fSendPort >= 0) {
84*5a1d355fSStephan Aßmus 		delete_port(fSendPort);
85*5a1d355fSStephan Aßmus 		fSendPort = -1;
86*5a1d355fSStephan Aßmus 	}
87*5a1d355fSStephan Aßmus 	if (fReceivePort >= 0) {
88*5a1d355fSStephan Aßmus 		delete_port(fReceivePort);
89*5a1d355fSStephan Aßmus 		fReceivePort = -1;
90*5a1d355fSStephan Aßmus 	}
91*5a1d355fSStephan Aßmus }
92*5a1d355fSStephan Aßmus 
93*5a1d355fSStephan Aßmus // Send
94*5a1d355fSStephan Aßmus status_t
Send(const void * _buffer,int32 size)95*5a1d355fSStephan Aßmus PortChannel::Send(const void* _buffer, int32 size)
96*5a1d355fSStephan Aßmus {
97*5a1d355fSStephan Aßmus 	if (size == 0)
98*5a1d355fSStephan Aßmus 		return B_OK;
99*5a1d355fSStephan Aßmus 	if (!_buffer || size < 0)
100*5a1d355fSStephan Aßmus 		return B_BAD_VALUE;
101*5a1d355fSStephan Aßmus 	const uint8* buffer = static_cast<const uint8*>(_buffer);
102*5a1d355fSStephan Aßmus 	while (size > 0) {
103*5a1d355fSStephan Aßmus 		int32 sendSize = min(size, fBufferSize);
104*5a1d355fSStephan Aßmus 		status_t error = write_port(fSendPort, 0, buffer, size);
105*5a1d355fSStephan Aßmus 		if (error != B_OK)
106*5a1d355fSStephan Aßmus 			return error;
107*5a1d355fSStephan Aßmus 		size -= sendSize;
108*5a1d355fSStephan Aßmus 		buffer += sendSize;
109*5a1d355fSStephan Aßmus 	}
110*5a1d355fSStephan Aßmus 	return B_OK;
111*5a1d355fSStephan Aßmus }
112*5a1d355fSStephan Aßmus 
113*5a1d355fSStephan Aßmus // Receive
114*5a1d355fSStephan Aßmus status_t
Receive(void * _buffer,int32 size)115*5a1d355fSStephan Aßmus PortChannel::Receive(void* _buffer, int32 size)
116*5a1d355fSStephan Aßmus {
117*5a1d355fSStephan Aßmus 	if (size == 0)
118*5a1d355fSStephan Aßmus 		return B_OK;
119*5a1d355fSStephan Aßmus 	if (!_buffer || size < 0)
120*5a1d355fSStephan Aßmus 		return B_BAD_VALUE;
121*5a1d355fSStephan Aßmus 	uint8* buffer = static_cast<uint8*>(_buffer);
122*5a1d355fSStephan Aßmus 	while (size > 0) {
123*5a1d355fSStephan Aßmus 		if (fBufferContentSize > 0) {
124*5a1d355fSStephan Aßmus 			// there's something in our buffer: just read from there
125*5a1d355fSStephan Aßmus 			int32 bytesRead = min(size, fBufferContentSize);
126*5a1d355fSStephan Aßmus 			memcpy(buffer, fBuffer + fBufferOffset, bytesRead);
127*5a1d355fSStephan Aßmus 			fBufferOffset += bytesRead;
128*5a1d355fSStephan Aßmus 			fBufferContentSize -= bytesRead;
129*5a1d355fSStephan Aßmus 			size -= bytesRead;
130*5a1d355fSStephan Aßmus 			buffer += bytesRead;
131*5a1d355fSStephan Aßmus 		} else {
132*5a1d355fSStephan Aßmus 			// nothing left in the buffer: we read from the port
133*5a1d355fSStephan Aßmus 			if (size > fBufferSize) {
134*5a1d355fSStephan Aßmus 				// we shall read more than what would fit into our buffer, so
135*5a1d355fSStephan Aßmus 				// we can directly read into the user buffer
136*5a1d355fSStephan Aßmus 				ssize_t bytesRead = read_port(fReceivePort, 0, buffer, size);
137*5a1d355fSStephan Aßmus 				if (bytesRead < 0)
138*5a1d355fSStephan Aßmus 					return bytesRead;
139*5a1d355fSStephan Aßmus 				size -= bytesRead;
140*5a1d355fSStephan Aßmus 				buffer += bytesRead;
141*5a1d355fSStephan Aßmus 			} else {
142*5a1d355fSStephan Aßmus 				// we read into our buffer
143*5a1d355fSStephan Aßmus 				ssize_t bytesRead = read_port(fReceivePort, 0, fBuffer,
144*5a1d355fSStephan Aßmus 					fBufferSize);
145*5a1d355fSStephan Aßmus 				if (bytesRead < 0)
146*5a1d355fSStephan Aßmus 					return bytesRead;
147*5a1d355fSStephan Aßmus 				fBufferOffset = 0;
148*5a1d355fSStephan Aßmus 				fBufferContentSize = bytesRead;
149*5a1d355fSStephan Aßmus 			}
150*5a1d355fSStephan Aßmus 		}
151*5a1d355fSStephan Aßmus 	}
152*5a1d355fSStephan Aßmus 	return B_OK;
153*5a1d355fSStephan Aßmus }
154*5a1d355fSStephan Aßmus 
155