Swoole 源码分析——内存模块之 swBuffer

栏目: IT技术 · 发布时间: 5年前

内容简介:Swoole 源码分析——内存模块之 swBuffer

前言

swoole 中数据的接受与发送(例如 reactor 线程接受客户端消息、发送给客户端的消息、接受到的来自 worker 的消息、要发送给 worker 的消息等等)都要涉及到缓冲区,swoole 中的缓冲区实现是 swBuffer,实际上是一个单链表。

swBuffer 的数据结构

  • swBuffer 数据结构中 trunk_num 是链表元素的个数,trunk_sizeswBuffer 缓冲区创建时,链表元素约定的大小(实际大小不一定是这个值),length 是实际上缓冲区占用的内存总大小。
  • swBuffer_trunk 中的 type 有三种,分别应用于:缓存数据、发送文件、提醒连接关闭三种情景。length 指的是元素的内存大小。
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; //trunk数量
    uint16_t trunk_size;
    uint32_t length;
    swBuffer_trunk *head;
    swBuffer_trunk *tail;
} swBuffer;

swBuffer 的创建

swBuffer 的创建很简单,只是初始化整个 swBufferheader 头元素而已:

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 内存的申请

swBuffer 内存的申请逻辑也很简单,按照传入的 size 参数为链表元素申请内存,初始化成员变量,然后将链表元素放到链表的尾部即可:

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;
}

获取 swBuffer 的元素

swBuffer 缓冲区拿数据只能从 head 中获取:

#define swBuffer_get_trunk(buffer)   (buffer->head)

swBuffer 元素的 pop

获取了缓冲区的元素之后,就要相应删除 head 链表元素:

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 缓冲区的销毁

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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

面向对象分析与设计

面向对象分析与设计

Grady Booch、Robert A. Maksimchuk、Michael W. Engel、Bobbi J. Young、Jim Conallen、Kelli A. Houston / 王海鹏、潘加宇 / 人民邮电出版社 / 2009-8 / 79.00元

《面向对象分析与设计(第3版)》是UML创始人Grady Booch的代表作之一,书中介绍的概念都基于牢固的理论基础。同时,《面向对象分析与设计(第3版)》又是一本注重实效的书,面向架构师和软件开发者等软件工程实践者的实际需要。《面向对象分析与设计(第3版)》通过大量例子说明了基本概念,解释了方法,并展示了在不同领域的成功应用。全书分为理论和应用两部分。理论部分深刻剖析了面向对象分析与设计(OOA......一起来看看 《面向对象分析与设计》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具