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,全部被释放