preface
swoole
Receiving and sending of data (e.greactor
The thread accepts the client message, sends the message to the client, receives the message from the clientworker
Message to send toworker
The buffer is involved,swoole
The buffer implementation in isswBuffer
It’s actually a single linked list.
swBuffer
Data structure of
-
swBuffer
In data structuretrunk_num
Is the number of linked list elements,trunk_size
yesswBuffer
When the buffer is created, the specified size of the linked list element (the actual size is not necessarily this value),length
Is the total amount of memory actually occupied by the buffer. -
swBuffer_trunk
Intype
There are three scenarios: caching data, sending files and reminding the connection to close.length
Refers to the memory size of the element.
enum swBufferChunk
{
SW_CHUNK_DATA,
SW_CHUNK_SENDFILE,
SW_CHUNK_CLOSE,
};
typedef struct _swBuffer_trunk
{
uint32_t type;
uint32_t length;
uint32_t offset;
union
{
void *ptr;
struct
{
uint32_t val1;
uint32_t val2;
} data;
} store;
uint32_t size;
void (*destroy)(struct _swBuffer_trunk *chunk);
struct _swBuffer_trunk *next;
} swBuffer_trunk;
typedef struct _swBuffer
{
int fd;
uint8_ t trunk_ Num; // number of trunk
uint16_t trunk_size;
uint32_t length;
swBuffer_trunk *head;
swBuffer_trunk *tail;
} swBuffer;
swBuffer
Creation of
swBuffer
The creation of is simple, just initializing the entire systemswBuffer
Ofheader
Head element only:
swBuffer* swBuffer_new(int trunk_size)
{
swBuffer *buffer = sw_malloc(sizeof(swBuffer));
if (buffer == NULL)
{
swWarn("malloc for buffer failed. Error: %s[%d]", strerror(errno), errno);
return NULL;
}
bzero(buffer, sizeof(swBuffer));
buffer->trunk_size = trunk_size;
return buffer;
}
swBuffer
Memory application
swBuffer
Memory application logic is also very simple, according to the incomingsize
Parameters apply memory for linked list elements, initialize member variables, and then put linked list elements at the end of the linked list
int swBuffer_append(swBuffer *buffer, void *data, uint32_t size)
{
swBuffer_trunk *chunk = swBuffer_new_trunk(buffer, SW_CHUNK_DATA, size);
if (chunk == NULL)
{
return SW_ERR;
}
buffer->length += size;
chunk->length = size;
memcpy(chunk->store.ptr, data, size);
swTraceLog(SW_TRACE_BUFFER, "trunk_n=%d|size=%d|trunk_len=%d|trunk=%p", buffer->trunk_num, size,
chunk->length, chunk);
return SW_OK;
}
swBuffer_trunk *swBuffer_new_trunk(swBuffer *buffer, uint32_t type, uint32_t size)
{
swBuffer_trunk *chunk = sw_malloc(sizeof(swBuffer_trunk));
if (chunk == NULL)
{
swWarn("malloc for trunk failed. Error: %s[%d]", strerror(errno), errno);
return NULL;
}
bzero(chunk, sizeof(swBuffer_trunk));
//require alloc memory
if (type == SW_CHUNK_DATA && size > 0)
{
void *buf = sw_malloc(size);
if (buf == NULL)
{
swWarn("malloc(%d) for data failed. Error: %s[%d]", size, strerror(errno), errno);
sw_free(chunk);
return NULL;
}
chunk->size = size;
chunk->store.ptr = buf;
}
chunk->type = type;
buffer->trunk_num ++;
if (buffer->head == NULL)
{
buffer->tail = buffer->head = chunk;
}
else
{
buffer->tail->next = chunk;
buffer->tail = chunk;
}
return chunk;
}
obtainswBuffer
The elements of
fromswBuffer
The buffer can only get data fromhead
From the
#define swBuffer_get_trunk(buffer) (buffer->head)
swBuffer
Elementalpop
After getting the elements of the buffer, delete them accordinglyhead
Linked list element:
void swBuffer_pop_trunk(swBuffer *buffer, swBuffer_trunk *chunk)
{
if (chunk->next == NULL)
{
buffer->head = NULL;
buffer->tail = NULL;
buffer->length = 0;
buffer->trunk_num = 0;
}
else
{
buffer->head = chunk->next;
buffer->length -= chunk->length;
buffer->trunk_num--;
}
if (chunk->type == SW_CHUNK_DATA)
{
sw_free(chunk->store.ptr);
}
if (chunk->destroy)
{
chunk->destroy(chunk);
}
sw_free(chunk);
}
swBuffer
Destruction of buffer
int swBuffer_free(swBuffer *buffer)
{
volatile swBuffer_trunk *chunk = buffer->head;
void * *will_free_trunk; //free the point
while (chunk != NULL)
{
if (chunk->type == SW_CHUNK_DATA)
{
sw_free(chunk->store.ptr);
}
will_free_trunk = (void *) chunk;
chunk = chunk->next;
sw_free(will_free_trunk);
}
sw_free(buffer);
return SW_OK;
}