zoukankan      html  css  js  c++  java
  • C工具库10:带引用计数的buffer

    前面写了一系列文章都是关于网络底层机制封装的,后面要慢慢的将这些机制组装起来,实现一套可用的网络库。

    既然是网络库,自然少不了对缓存的管理,本文实现一个带引用计数的buffer,作为packet的底层缓存组件.packet

    的具体设计思路可见:

    http://www.cnblogs.com/sniperHW/archive/2012/04/02/2429625.html

    http://www.cnblogs.com/sniperHW/archive/2012/04/02/2429629.html

    #ifndef _BUFFER_H
    #define _BUFFER_H
    /*    
        Copyright (C) <2012>  <huangweilook@21cn.com>
    
        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
    
        You should have received a copy of the GNU General Public License
        along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
    /*
    * 带引用计数的buffer
    */
    typedef struct buffer
    {
        long ref_count;
        unsigned long capacity;
        unsigned long size;
        struct buffer *next;
        char   buf[0];
    }*buffer_t;
    
    
    buffer_t buffer_create_and_acquire(buffer_t,unsigned long);
    buffer_t buffer_acquire(buffer_t,buffer_t);
    void     buffer_release(buffer_t*);
    
    #endif
    #include <stdlib.h>
    #include <stdio.h>
    #include "buffer.h"
    
    static buffer_t buffer_create(unsigned long capacity)
    {
        unsigned long size = sizeof(struct buffer) + capacity;
        buffer_t b = calloc(1,size);
        if(b)
        {
            b->ref_count = 0;
            b->size = 0;
            b->capacity = capacity;
        }
        return b;
    }
    
    static void     buffer_destroy(buffer_t *b)
    {
        printf("buffer destroy\n");
        if((*b)->next)
            buffer_release(&(*b)->next);
        free(*b);
        *b = 0;
    }
    
    buffer_t buffer_create_and_acquire(buffer_t b,unsigned long capacity)
    {
        buffer_t nb = buffer_create(capacity);
        return buffer_acquire(b,nb);
    }
    
    buffer_t buffer_acquire(buffer_t b1,buffer_t b2)
    {
        if(b1 == b2)
            return b1;    
        if(b2)
            ++b2->ref_count;
        if(b1)
            buffer_release(&b1);
    
        return b2;
    }
    
    void buffer_release(buffer_t *b)
    {
        if(--(*b)->ref_count <= 0)
            buffer_destroy(b);
        *b = 0;
    }

    测试用例如下:

        buffer_t cur = 0;
        buffer_t b1 = buffer_create_and_acquire(0,16);
        buffer_t b2 = buffer_acquire(0,b1);
        buffer_release(&b1);
        buffer_release(&b2);
    
        b1 = buffer_create_and_acquire(0,16); //b1指向bufferA
        b1 = buffer_create_and_acquire(b1,16);//b1指向bufferB,bufferA计数减为0,被释放
        buffer_release(&b1);
    
        //创建3个buffer形成链表
        b1 = buffer_create_and_acquire(0,16);
        b1->next = buffer_create_and_acquire(0,16);
        b1->next->next = buffer_create_and_acquire(0,16);
    
        cur = b1;
        while(cur)
        {
            cur = buffer_acquire(cur,cur->next);
        }
        //遍历结束,所有buffer的计数减为0,全部被释放
  • 相关阅读:
    2016年 CodePen 最热门的前端代码 Top 100
    HttpClientHelper
    .net core mvc 简易登录
    senparc 第三方授权回调,保存授权信息到文件
    盛派微信Sdk .Net Core 初始化注册服务信息
    分享一个gif截图工具
    C# 单例模式
    获取微信AccessToken,保存在内存中,过期后重新获取
    .NET Core WebAPI Swagger使用
    .net Core 读取配置文件参数
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2493876.html
Copyright © 2011-2022 走看看