1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
//****************************************************************************
22
// The SendBuffer is a circular buffer storing signals waiting to be sent.
23
// The signals can be of variable size and are copied into the buffer
24
// in Protocol 6 format. There will be two SendBuffer instances
25
// (priority level A and B) for each transporter using a buffer for
26
// sending. The buffering will in most cases be done to send as big
27
// packages as possible over TCP/IP.
29
//***************************************************************************/
33
#include "TransporterDefinitions.hpp"
34
#include <TransporterCallback.hpp>
36
#ifdef DEBUG_TRANSPORTER
37
#include <ndb_global.h>
41
friend class TCP_Transporter;
43
// Set member variables
44
SendBuffer(Uint32 bufSize);
46
// Deallocate the buffer memory
49
// Allocate memory for the buffer and initialize the buffer pointers
50
bool initBuffer(Uint32 aRemoteNodeId);
52
// Number of bytes remaining in the buffer
53
Uint32 bufferSizeRemaining() const;
55
// Number of bytes of data in the buffer
62
* The transporter calls updateBuffer after a retrieve followed by
63
* a successful send, to update the cirkular buffer pointers.
64
* updateBuffer is called with the number of bytes really sent,
65
* it may be that it is less than what was retrived from the buffer.
66
* If that is the case there will be an incomplete message (slack)
69
* Returns 0 if buffer empty
72
Uint32 bytesSent(Uint32 len);
74
#ifdef DEBUG_TRANSPORTER
75
// Prints the buffer status on the screen. Can be used for testing purposes.
79
Uint32* getInsertPtr(Uint32 bytes);
80
void updateInsertPtr(Uint32 bytes);
84
Uint32 sizeOfBuffer; // Length, in number of bytes, of the buffer memory
85
Uint32 dataSize; // Number of bytes in buffer
87
Uint32 * startOfBuffer; // Pointer to the start of the buffer memory
88
Uint32 * endOfBuffer; // Pointer to end of buffer
90
Uint32 * insertPtr; // Where to insert next
92
char * sendPtr; // Where data to send starts
93
Uint32 sendDataSize; // Num bytes to send
95
Uint32 theRemoteNodeId;
100
SendBuffer::bytesSent(Uint32 bytes) {
102
if(bytes > dataSize){
103
#ifdef DEBUG_TRANSPORTER
104
printf("bytes(%d) > dataSize(%d)\n", bytes, dataSize);
107
// reportError(0 ,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
111
if(bytes > sendDataSize){
112
#ifdef DEBUG_TRANSPORTER
113
printf("bytes(%d) > sendDataSize(%d)\n", bytes, sendDataSize);
116
//reportError(0,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
122
sendDataSize -= bytes;
124
if(sendDataSize == 0){
125
if(sendPtr > (char*)insertPtr){
126
sendPtr = (char *)startOfBuffer;
127
sendDataSize = dataSize;
129
sendPtr = ((char*)insertPtr) - dataSize;
130
sendDataSize = dataSize;
141
SendBuffer::getInsertPtr(Uint32 len){
142
if (bufferSizeRemaining() < len){
146
const char * const tmpInsertPtr = (char *) insertPtr;
148
if(tmpInsertPtr >= sendPtr){
149
// Is there enough space at the end of the buffer?
150
if ((tmpInsertPtr + len) < (char*)endOfBuffer){
154
// We have passed the end of the cirkular buffer,
155
// must start from the beginning
156
// Is there enough space in the beginning of the buffer?
157
if ((Uint32)(sendPtr - (char *)startOfBuffer) <= len){
158
// Not enough space available, insert failed
161
// There is space available at the beginning of the buffer
162
// We start from the beginning, set endOfData and insertPtr
163
insertPtr = startOfBuffer;
164
if(sendDataSize != 0){
167
sendPtr = (char *)startOfBuffer;
173
// sendPtr > insertPtr
174
// Is there enought room
175
if((tmpInsertPtr + len) < sendPtr){
184
SendBuffer::updateInsertPtr(Uint32 lenBytes){
185
dataSize += lenBytes;
186
insertPtr += (lenBytes / 4);
189
#endif // Define of SendBuffer_H