nginx源码分析

阅读: 评论:0

nginx源码分析

nginx源码分析

1.数据类型

1.1基本数据

Nginx主要使用了三个标准整数类型: size_t、 u_char和off_t。

size_t用于计算数据的长度,是C/C++标准里定义的一个类型,是 sizeof 操作符的结果类型,相当于unsigned_long。在64位的系统里宽度是8字节:

u_char表示一个字节,虽然它也是一个标准整数类型,但并不是C/C++标准,而是“系统标准”,是在<sys/types.h>里的一个typedef:

typedef unsigned char u_char

1.2自定义

Nginx依据C/C++标准重新定义了三个整数类型来代替标准里的int/long 等类型,编译都能获得一致的结果。这些类型是:


typedef intptr_t        ngx_int_t;
typedef uintptr_t       ngx_uint_t;
typedef intptr_t        ngx_flag_t;

 还有很多在其他模块。

我们在开发 Nginx 块编写代码时应该尽量使用这些 Nginx 专有的整数类型,不仅是为

了与 Ngin 保持风格的一致,更重要的是保证代码的跨平台兼容

1.3无效值

变量的初始化是编程语言里一个重要但又常常会被忽略的问题。在C/C++中,整数类型属于POD类型,初始值是“未定义”的,也就是说初始值可能是任意数值,存在安全隐患。 Lua/Python等语言有Nil/None 的概念,一个变量如果未初始化,那么它的值就是Nil或者None。Nginx采用了类似思路的“UNSET”值,使用“-1”表示未初始化。 由于C/C++是强类型语言,单纯的整数-1不能直接与其他类型比较,需要做类型转换,所以Nginx为-1定义了不同类型转换的宏:
#define NGX_CONF_UNSET       -1                    //通用无效值
#define NGX_CONF_UNSET_UINT  (ngx_uint_t) -1       //无符号整数
#define NGX_CONF_UNSET_PTR   (void *) -1           //指针
#define NGX_CONF_UNSET_SIZE  (size_t) -1          //size_t 类型的无效值
#define NGX_CONF_UNSET_MSEC  (ngx_msec_t) -1      //毫秒的无效值#define ngx_conf_init_value(conf, default)                                   if (conf == NGX_CONF_UNSET) {                                            conf = default;                                                      }#define ngx_conf_init_ptr_value(conf, default)                               if (conf == NGX_CONF_UNSET_PTR) {                                        conf = default;                                                      }#define ngx_conf_init_uint_value(conf, default)                              if (conf == NGX_CONF_UNSET_UINT) {                                       conf = default;                                                      }#define ngx_conf_init_size_value(conf, default)                              if (conf == NGX_CONF_UNSET_SIZE) {                                       conf = default;                                                      }#define ngx_conf_init_msec_value(conf, default)                              if (conf == NGX_CONF_UNSET_MSEC) {                                       conf = default;                                                      }

2.c++封装数据类型

2.1封装无效值

class NgxUnsetValue final
{public:template<typename T>operator T()const{return static_cast<T>(-1);}//指针和整数之间的转换template<typename T>operator T*()const{return reinterpret_cast<T*>(-1);}////NgxUnsetvalue应该是个单件//,可以实现一个静态成员函数//,提供一个全局访问点:public:static const NgxUnsetValue&get(){static NgxUnsetValue const v={};//空类return v;}} ;

解析1

1.首先利用模板技术比宏安全(建议参考这篇文章宏与模板的区分)实现了任意封装类型的无效值。

2.NgxUnsetvalue应该是个单件,可以实现一个静态成员函数,提供一个全局访问点:

auto &&ngx_nil=NgxUnsetValue::get()

2.2操作函数封装

2.1.1判断是否无效

    public:template<typename T,typename ... Args>static void unset(T&v,Args ... arg){v=NgxUnsetValue::get(););}void unset(){};public:template<typename T>static bool invaild(const T&v){return v==static_cast<T>(NgxUnsetValue::get());}template<typename T,typename U>static void init(T&x,const U&v){if(invaild(x)){return x=v;}}public:template<typename T,typename U,typename V>static void merge(T&c,const U&p,const V&d){if(invaild(c)){c=invaild(p)?d:p;}}

思想

1.先判断是否为有效值

2.采用参数系列,使用递归来判断多个值;

3.单个值是否有效,在初始化一个值

4.一个值是否有效,再初始化两个值

2.2.2重载

 namespace cwr {auto &&ngx_nil=NgxUnsetValue::get();};template <typename T>bool operator==(const T&x,const NgxUnsetValue&){return NgxValue::invalid(x);}template<class T>bool operator!=(const T&x,const NgxUnsetValue&){return !NgxValue::invaild(x);}

本文发布于:2024-02-02 01:07:43,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170681214240423.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:源码   nginx
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23