学习《apache源代码全景分析》之存储段和存储段组摘录

2023-05-16

1.当数据在过滤器中流动传递的时候,数据是以存储段组的形式组织的。每一个存储段组包含多个存储段,每一个存储段是一种数据类型的抽象。

2.存储段组包含多个存储段

   

 

struct apr_bucket 
{
    APR_RING_ENTRY(apr_bucket) link;
    const apr_bucket_type_t *type;
    apr_size_t length;
    apr_off_t start;
    void *data;
    void (*free)(void *e);
    apr_bucket_alloc_t *list;
};

3.存储段的内部数据结构

   

   在apr_bucket结构中,存储段的实际数据保存在data指针中,数据的长度由length进行标记。

4.所有的外部数据操作都是以存储段组为单位进行的,其数据结构定义在apr_buckets.h中:

    

   

5.在内存池中,所有的内存分配最终都由内存池分配子进行.

  存储段分配子为apr_bucket_alloc_t,其具体结构定义如下:

struct apr_bucket_alloc_t 
{
    apr_pool_t *pool;  //所有内存的来源内存池
    apr_allocator_t *alloctor;  //内存池的分配子
    node_header_t *freelist;  //用于保存回收的小于SAMLL_NODE_SIZE的结点
    apr_memnode_t *blocks;  //当前存储段所属的内存池结点
};


------------------
typedef struct node_header_t 
{
    apr_size_t size; //该内存的大小
    apr_bucket_alloc_t *alloc; //分配该内存块的存储段内存分配子
    apr_memnode_t *memnode; //记录该内存所在的内存结点
    struct node_header_t *next; //所有分配的存储段内存通过next指针形成链表
} node_header_t;

6.一旦分配成功,函数将为各个成员赋值,同时调整内存结点的first_avail指针指向实际的可用空间的起点,如下图:

    

7.存储段的内存使用函数apr_bucket_alloc进行分配。

  目前Apache支持多种类型的存储段,比如文件存储段等。分配的原则按照最大的存储段类型进行。

typedef union apr_bucket_structs apr_bucket_structs;
union apr_bucket_structs
{
    apr_bucket b; /*Bucket*/
    apr_bucket_heap heap;  /*Heap*/
    apr_bucket_pool pool;   /*pool*/
    apr_bucket_mmap mmap; /*mmap*/
    apr_bucket_file file;   /*file*/
};

8.释放存储段内存通过apr_bucket_free函数实现。

9.apr_bucket在Apache中定义如下:

struct apr_bucket
{
    APR_RING_ENTRY(apr_bucket) link;
    const apr_bucket_type_t *type;
    apr_size_t length;
    apr_off_t start;
    void *data;
    void (*free)(void *e);
    apr_bucket_alloc_t *list;
};

  通常情况下,存储段组用来保存的是一块连续的内存数据,而存储段组中的每一个存储段仅保存整个数据块的一小部分。

10.通用存储段接口和实际存储段的关系

     

apr_bucket_readapr_bucket_read函数用于从存储段中读取数据
apr_bucket_destroy将释放存储段引用的聂村,而不释放存储段本身的内存
apr_bucket_split使用split函数可以将一个存储段分割成两个存储单。
apr_bucket_copycopy函数可以接受一个存储段,并对其进行精确的复制
apr_bucket_setaside如果过滤器希望存储段组中的所有数据在下次过滤器调用的时候仍然可以使用,就要调用这个函数。

11.存储段类型包括11种数据:

堆存储段
内存池存储段
文件存储段
MMAP存储段
管道存储段
套接字存储段
持久存储段
临时存储段
刷新存储段
流中止(EOS)存储段

  (1) 堆存储段

typedef struct apr_bucket_heap apr_bucket_heap;
struct apr_bucket_heap
{
    apr_bucket_refcount refcount;
    char *base;
    apr_size_t alloc_len;    
    void (*free_func)(void *data);
};

   (2) 内存池存储段(Pool Bucket)

     内存池存储段的读取函数为pool_bucket_read.

struct apr_bucket_pool
{
    apr_bucket_heap heap;
    const char *base;
    apr_pool_t *pool;
    apr_bucket_alloc_t *list;
};

  (3) 文件存储段(file bucket)

    最重要的就是它的读取函数file_bucket_read.

typedef struct apr_bucket_file apr_bucket_file;
struct apr_bucket_file
{
    apr_bucket_refcount refcount;
    apr_file_t *fd;
    apr_pool_t *readpool;
#if APR_HAS_MMAP
    int can_mmap;
#endif /* APR_HAS_MMAP*/
};

  (4) MMAP存储段(MMAP bucket)

     读取数据由接口mmap_bucket_read完成。

typedef struct apr_bucket_mmap apr_bucket_mmap;
struct apr_bucket_mmap
{
    apr_bucket_refcount refcount;
    apr_mmap_t *mmap;
};

  (5) 套接字存储段(Socket Bucket)

   读取函数为socket_bucket_read.

  (6) 管道存储段(pipe bucket)

    读取函数为pipe_bucket_read;

  (7) 持久存储段(immortal bucket)

  (8) 临时存储段(transient bucket)

  (9) 刷新存储段(flush bucket)

  (10) 流中止(EOS)存储段

  (11) HTTP错误存储段

struct ap_bucket_error
{
    apr_bucket_refcount refcount;
    int status;
    const char *data;
};

12.不管是堆存储段还是文件存储段,都调用apr_bucket_read函数,而不是直接调用heap_bucket_read和file_bucket_read.

   apr_bucket_read本身实际是一个宏定义,如下所示:

#define apr_bucket_read(e,str,len,block) (e)->type->read(e, str, len, block)

13.存储段类型判断

    

14.存储段结点获取

    APR_BRIGADE_EMPTY、APR_BRIGADE_SENTINEL、APR_BRIGADE_FIRST、APR_BRIGADE_LAST、APR_BUCKET_NEXT、APR_BUCKET_PREV

15.存储段结点增加和删除

   (1) 存储段组头部插入结点(APR_BRIGADE_INSERT_HEAD)

   (2) 存储段组尾部插入结点(APR_BRIGADE_INSERT_TAIL)

   (3) 存储段组在指定存储段之前插入新的存储段(APR_BUCKET_INSERT_BEFORE)

   (4) 存储段组中在指定存储段之后插入一个新的存储段(APR_BUCKET_INSERT_AFTER)

   (5) 将一个存储段组追加到另一个存储段组的尾部(APR_BRIGADE_CONCAT)

   (6) 存储段结点移除(APR_BUCKET_REMOVE)

16.存储段组操作

    (1) 创建存储段组apr_brigade_create

    (2) 存储段组的销毁  apr_brigade_cleanup

    (3) 存储段组的分裂apr_brigade_split

       

 

    (4) 偏移分裂apr_brigade_partition

      

      

    (5) 行分裂apr_brigade_split_line

    (6) 统计存储段长度

        apr_brigade_length函数用以统计当前存储段组所有的存储段的长度。

    (7) 存储段转换 apr_brigade_flatten   用于将存储段组转换为字符串。

    (8) 将数据写入存储段组apr_bucket_write.

       

    (9) 一次向存储段组批量写入多个字符串数据apr_bucket_writev

    (10) 其余写入函数 apr_brigade_puts、apr_brigade_putc、apr_brigade_putstrs

    (11) ap_r*函数写入ap_rputc、ap_rputs、ap_rwrite、ap_rvputs、ap_vrprintf

17.存储段组和过滤器的关系

    

   ap_get_brigade函数正是用于获取下一个过滤器的存储段组内容。

       

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

学习《apache源代码全景分析》之存储段和存储段组摘录 的相关文章

  • 使用 WSGI 在 Windows XAMPP 中设置 Python 路径

    我正在 Webfaction 上设置实时服务器的开发版本 在本地计算机上的虚拟 Apache 服务器环境 运行没有任何错误 中运行 Django 应用程序 XP 使用 Python 2 6 运行 XAMPP Lite 我可以提交更改通过 G
  • Magento 中的子域 htaccess 问题

    public html www domain com public html subdomain subdomain domain com public html htaccess public html subdomain htacces
  • Apache 网络服务器启动时出现错误[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我刚刚切换
  • 文件不存在时.htaccess 重定向

    我正在使用 htaccess 将用户重定向到我的主控制器 并且工作正常 但是当我调用一个不存在的js文件时 如下所示 这个js文件不只是说404 文件不存在 而是获取index php的内容 我应该如何进行 这是我的 htaccess
  • ProxyPassMatch 与 ProxyPassReverse

    各位 我们正在尝试为以下场景设置 Apache 反向代理 传入请求采用以下形式http foo com APP v1 main html 对于某些服务器 URL 将引用不同的版本 例如 http foo com APP v2 main ht
  • 让 Rails 生产在端口 80 上运行

    我正在尝试让我的 Rails 应用程序在生产模式下运行 但遇到了一些困难 我正在使用 Passenger 和 apache 并运行 Ubuntu 12 04 我已经配置和创建了生产数据库 并设置了乘客 状态如下 rvmsudo passen
  • 使用代理时,React 应用程序正在不同位置查找静态文件

    我用过npx create react app my app创建一个反应应用程序 我用过的npm run build构建应用程序并使用它进行部署serve s build 我正在使用代理服务器来公开我的应用程序 我的 httpd 配置如下所
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • 如何更改 Apache 服务器的根目录? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何更改 Apache 服务器的文档根目录 我基本上想要localhost从 来 users spencer projects目录而不是
  • 具有动态 apache vhost 的非通配符证书

    我正在尝试根据用于连接到我的服务器的 url 动态读取 SSL 证书的位置 我尝试了几种不同的方法 但似乎都不起作用 目前我的配置如下所示 UseCanonicalName Off listen 443
  • 如何阻止用户通过url访问css文件和图像

    我在用 htaccess防止用户通过 url 访问文件 线路 RewriteRule frontend assets css index L R 工作正常 它阻止用户访问 css 文件 然而 RewriteRule frontend ass
  • Apache 子进程已退出,状态为 255

    经过大量的搜索 尝试 修复 等待和哭泣 在我放弃之前 我想为这个错误抓住最后的机会 我们正在奔跑Microsoft Windows Server 2012 Apache 2 4 6 Win64 OpenSSL 1 0 1e PHP 5 5
  • 新部署后,React 应用程序必须清除浏览器缓存

    我们正在使用 Jenkins 管道在 apache 服务器上部署 React 应用程序 当我们部署新代码时 大多数新功能都可以正常工作 但并非所有更改都反映浏览器中的最新内容 用户必须打开隐身窗口或清除缓存才能看到新功能 我见过一些相关的解
  • mod_rewrite 可以转换任意数量、任意名称的参数吗?

    我对 mod rewrite 完全是个新手 我想做的事情听起来很简单 我不想拥有domain com script php a 1 b 2 c 3 我想要 domain com script a 1 b 2 c 3 问题是我的脚本采用各种组
  • 在浏览器中读取wsdl文件

    当我尝试在浏览器中打开 WSDL 文件 http localhost something file wsdl 时 我被提议下载该文件 但我希望能够在浏览器中以 XML 字符串 形式查看 而不是下载 谢谢 如果您的服务器未发送 WSDL 文件
  • Apache mod_rewrite:仅当不在本地主机中时才强制 www

    我的 htaccess 中有以下内容来强制 URL 中包含 www RewriteCond HTTP HOST www RewriteRule http www HTTP HOST 1 R 301 L 如果不在本地主机上 我该如何应用它 我
  • 仅使用 mod_rewrite 重定向主页

    我有一个需要重定向的网站 但我不能只重定向 目录 因为服务器上的文件夹中还有其他网站 这样做也会重定向它们 不好 因此 我的 htaccess 文件包含一堆针对各个 HTML 页面的 301 重定向 并且这些文件工作得很好 但我需要重定向主
  • 连接到 mysql 服务器(localhost)非常慢

    实际上有点复杂 摘要 与数据库的连接非常慢 页面渲染大约需要 10 秒 但页面上的最后一条语句是一个回显 当页面在 Firefox 中加载时我可以看到它的输出 IE 是相同的 在谷歌浏览器中 只有在加载完成后输出才可见 不同浏览器的加载时间
  • php7ts.dll 无法加载到服务器

    今天我已经安装了php7 但是当我重新启动apache时 它无法启动 尽管我再次编辑了httpd xampp conf文件到配置php7 无论如何我去了C xampp并运行apache start bat 然后我看到以下错误 Apache
  • Spring MVC http 500错误apache

    上面是我的程序的目录层次结构 我是 Spring 新手 正在学习 MVC 概念 我编写了一个程序 它将输入 名称 输入文本框并打印 Hello name 以下是我的目录结构和我创建的各种文件 web xml

随机推荐