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,全部被释放
原文地址:https://www.cnblogs.com/sniperHW/p/2493876.html