nginx之rtmp模块引用计数设计
對于沒有垃圾自動回收機制的語言(如C/C++)來說,引用計數提供了一種簡潔高效的內存管理方法,?
nginx-rtmp模塊為方便管理內存,在給ngx_chain_t分配內存的時候,多分配了sizeof(uint32_t)類型的字節數,用來方便管理內存
在ngx_rtmp_shared.c文件中
#define?NGX_RTMP_REFCOUNT_TYPE ? ? ? ? ? ? ?uint32_t
#define?NGX_RTMP_REFCOUNT_BYTES ??? ? ? ? ?sizeof(NGX_RTMP_REFCOUNT_TYPE)
#define ngx_rtmp_ref(b) ? ? ? ? ? ? ? ? ? ? *((NGX_RTMP_REFCOUNT_TYPE*)(b) - 1)
#define ngx_rtmp_ref_set(b, v) ? ? ? ? ? ? ?ngx_rtmp_ref(b) = v
#define ngx_rtmp_ref_get(b) ? ? ? ? ? ? ? ? ++ngx_rtmp_ref(b)
#define?ngx_rtmp_ref_put(b) ? ? ? ? ? ? ? ?--ngx_rtmp_ref(b)
//給chain分配內存
ngx_chain_t *?ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf)
{
? ? u_char ? ? ? ? ? ? ? ? ? ? *p;
? ? ngx_chain_t ? ? ? ? ? ? ? ?*out;
? ? ngx_buf_t ? ? ? ? ? ? ? ? ?*b;
? ? size_t ? ? ? ? ? ? ? ? ? ? ?size;
? ? if (cscf->free) {
? ? ? ? out = cscf->free;
? ? ? ? cscf->free = out->next;
? ? } else {
? ? ? ? size = cscf->chunk_size + NGX_RTMP_MAX_CHUNK_HEADER;
? ? ? ? //在給chain分配內存的時候,在chain前面多分配了NGX_RTMP_REFCOUNT_BYTES字節的內存,也就是4個字節,這4字節的值初始化的時候為0
? ? ? ? p = ngx_pcalloc(cscf->pool,?NGX_RTMP_REFCOUNT_BYTES?
? ? ? ? ? ? ? ? + sizeof(ngx_chain_t)
? ? ? ? ? ? ? ? + sizeof(ngx_buf_t)
? ? ? ? ? ? ? ? + size);
? ? ? ? if (p == NULL) {
? ? ? ? ? ? return NULL;
? ? ? ? }
//p指針后移NGX_RTMP_REFCOUNT_BYTES 個字節,也就是然后再覆蓋out即分配的chain
? ? ? ? p += NGX_RTMP_REFCOUNT_BYTES;
? ? ? ? out = (ngx_chain_t *)p;
? ? ? ? p += sizeof(ngx_chain_t);
? ? ? ? out->buf = (ngx_buf_t *)p;
? ? ? ? p += sizeof(ngx_buf_t);
? ? ? ? out->buf->start = p;
? ? ? ? out->buf->end = p + size;
? ? }
? ? out->next = NULL;
? ? b = out->buf;
? ? b->pos = b->last = b->start + NGX_RTMP_MAX_CHUNK_HEADER;
? ? b->memory = 1;
? ? //剛分配的時候,給引用計數置1
? ??ngx_rtmp_ref_set(out, 1);
? ? return out;
}
void ngx_rtmp_free_shared_chain(ngx_rtmp_core_srv_conf_t *cscf, ngx_chain_t *in)
{
? ? ngx_chain_t ? ? ? ?*cl;
? ? //在釋放內存的時候,先判斷引用計數是否為0,不為0直接返回
? ? if (ngx_rtmp_ref_put(in)) {
? ? ? ? return;
? ? }
? ?//為0 的時候,將當前chain放到需要釋放的鏈表當中,下次循環利用
? ? for (cl = in; ; cl = cl->next) {
? ? ? ? if (cl->next == NULL) {
? ? ? ? ? ? cl->next = cscf->free;
? ? ? ? ? ? cscf->free = in;
? ? ? ? ? ? return;
? ? ? ? }
? ? }
}
總結
以上是生活随笔為你收集整理的nginx之rtmp模块引用计数设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx基础数据结构分析-ngx_ch
- 下一篇: Nginx学习之三-ngx_http_r