`
100Continue
  • 浏览: 157849 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

为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, 全部介绍完毕。

1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics