为Nginx源码ngx_alloc.c添加ngx_realloc与ngx_prealloc方法

 

需求:

由于Nginx源码中并没有提供ngx_realloc和ngx_prealloc方法,因此在2011年10月,为Tengine(淘宝版Nginx)源码贡献这两个方法的实现;

 

解决方案:

在介绍解决方案之前,需要先介绍下realloc的功能定义:

 

Linux中man realloc的结果 写道
DESCRIPTION
realloc() changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, the call is equivalent to malloc(size); if size is equal to zero, the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.


RETURN VALUE
realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is not freed or moved.

 下面介绍代码实现:

 

// ngx_realloc代码实现及分析	
// 首先定义一个用于返回的new指针,并通过C的realloc方法为传入的指针p重新分配空间,
// 若返回为null则将错误信息写入nginx错误日志,否则将debug信息写入nginx debug日志并返回新地址空间的指针
void *
ngx_realloc(void *p, size_t size, ngx_log_t *log)
{
    void *new;

    new = realloc(p, size);
    if (new == NULL) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "realloc(%p:%uz) failed", p, size);
    }

    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "realloc: %p:%uz", new, size);

    return new;
}

  // ngx_prealloc代码实现及分析

void *
ngx_prealloc(ngx_pool_t *pool, void *p, size_t old_size, size_t new_size)
{
    void *new;

    // 如果p为空,则相对于在pool中分配一块新空间并返回指向该空间的指针	
    if (p == NULL) {
        return ngx_palloc(pool, new_size);
    }

    // 如果所需重新分配的空间大小为0,则判断旧空间地址是否在pool的最后,
    // 若是,则只需将pool的d.last指针移到旧空间地址的起始位置;
    // 否则,使用ngx_pfree方法是否pool中的旧空间;
    // 最后返回null。	
    if (new_size == 0) {
        if ((u_char *) p + old_size == pool->d.last) {
           pool->d.last = p;
        } else {
           ngx_pfree(pool, p);
        }
	
        return NULL;
    }

    // 如果所需重新分配的空间处于pool的最后,并且pool剩余空间
    // 的大小大于所需分配空间的大小,则只需将pool的d.last指向
    // 新空间的末尾并返回原空间的地址即可。
    if ((u_char *) p + old_size == pool->d.last
		&& (u_char *) p + new_size <= pool->d.end)
    {
        pool->d.last = (u_char *) p + new_size;
        return p;
    }
	
    // 如果以上条件均不符合,则需要通过ngx_palloc在pool内分配
    // 一个新的空间,并在将旧空间内的数据拷贝到新空间内之后,
    // 释放掉旧空间,返回新空间地址。
    new = ngx_palloc(pool, new_size);
    if (new == NULL) {
        return NULL;
    }
	
    ngx_memcpy(new, p, old_size);
	
    ngx_pfree(pool, p);
	
    return new;
}

 

 

ok, 全部介绍完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值