`

cherokee 插件加载器源码剖析

阅读更多

cherokee 服务器的绝大部分功能都是用插件实现的, 因此要理解cherokee的源码首先需要理解的就是cherokee的插件.

插件相关的主要结构体有以下几个.

 

// 插件, 对应于每个插件
typedef struct {
	cherokee_plugin_type_t    type;
	void                         *instance;
	void                         *configure;
	const char               *name;
} cherokee_plugin_info_t;
// 插件加载器实体, 对应于每个插件
typedef struct {
        cherokee_plugin_info_t *info;          // 从动态库中读取的插件info
        void                              *dlopen_ref;// dlopen打开的动态链接库
        cherokee_boolean_t      built_in;
} cherokee_plugin_loader_entry_t;
// 插件加载器, 每个Server上只有一个, 对应于每个进程
typedef struct {
        cherokee_avl_t            table;         // AVL 树包含了所有插件名-实体的键值对
        cherokee_buffer_t       module_dir;// 模块目录
        cherokee_buffer_t       deps_dir;   // 依赖插件目录
} cherokee_plugin_loader_t;

 

插件加载器各部分之间的关系

 


 

以下便是插件加载的过程, 注释上已经写得很清楚了.

 

static ret_t
get_info (cherokee_plugin_loader_t  *loader,
	  const char                *module,
	  int                        flags,
	  cherokee_plugin_info_t   **info,
	  void                     **dl_handler)
{
	ret_t             ret;
	cherokee_buffer_t info_name = CHEROKEE_BUF_INIT;

	/* Build the info struct string
	 */
	cherokee_buffer_add_va (&info_name, "cherokee_%s_info", module);

	/* Open it 加载动态链接库到dl_handler
	 */
	ret = dylib_open (loader, module, flags, dl_handler);
	if (ret != ret_ok) {
		cherokee_buffer_mrproper (&info_name);
		return ret_error;
	}
	// 从动态库中读取插件info 结构体(cherokee_plugin_info_t)
	// 
	*info = get_sym_from_dlopen_handler (*dl_handler, info_name.buf);
	if (*info == NULL) {
		cherokee_buffer_mrproper (&info_name);
		return ret_not_found;
	}

	/* Free the info struct string
	 */
	cherokee_buffer_mrproper (&info_name);
	return ret_ok;
}


static ret_t
check_deps_file (cherokee_plugin_loader_t *loader,
		 const char               *modname)
{
	FILE             *file;
	char              temp[128];
	cherokee_buffer_t filename = CHEROKEE_BUF_INIT;

	// 将路径名拷贝到buffer, 
	cherokee_buffer_add_va (&filename, "%s/%s.deps", loader->deps_dir.buf, modname);
	file = fopen (filename.buf, "r");
	if (file == NULL)
		goto exit;

	while (!feof(file)) {
		int   len;
		char *ret;
		// 读取插件名
		ret = fgets (temp, 127, file);
		if (ret == NULL)
			break;

		len = strlen (temp);

		if (len < 2)
			continue;
		if (temp[0] == '#')
			continue;

		if (temp[len-1] == '\n')
			temp[len-1] = '\0';
		// 加载插件
		cherokee_plugin_loader_load (loader, temp);
		temp[0] = '\0';
	}

	fclose (file);

exit:
	cherokee_buffer_mrproper (&filename);
	return ret_ok;
}


static ret_t
load_common (cherokee_plugin_loader_t *loader,
	     const char               *modname,
	     int                       flags)
{
	ret_t                   ret;
	entry_t                *entry     = NULL;
	cherokee_plugin_info_t *info      = NULL;
	void                   *dl_handle = NULL;

	/* If it is already loaded just return
	 * 在AVL 树中查找插件名, 如果找到说明插件已经加载, 直接返回
	 */
	ret = cherokee_avl_get_ptr (&loader->table, modname, (void **)&entry);
	if (ret == ret_ok)
		return ret_ok;

	/* Check deps
	 * 加载依赖的其他插件, 从文件中读取插件名然后递归调用cherokee_plugin_loader_load 加载
	 */
	ret = check_deps_file (loader, modname);
	if (ret != ret_ok)
		return ret;

	/* Get the module info
	 * 加载插件对应的动态库文件, 并取得插件info 结构体
	 */
	ret = get_info (loader, modname, flags, &info, &dl_handle);
	switch (ret) {
	case ret_ok:
		break;
	case ret_error:
		LOG_ERROR (CHEROKEE_ERROR_PLUGIN_NO_OPEN, modname);
		return ret;
	case ret_not_found:
		LOG_ERROR (CHEROKEE_ERROR_PLUGIN_NO_INFO, modname);
		return ret;
	default:
		SHOULDNT_HAPPEN;
		return ret_error;
	}

	/* Add new entry
	 * 创建新的插件实体, 设置info 和dl_handle, 插入到AVL树中
	 */
	entry = malloc (sizeof(entry_t));
	if (entry == NULL) {
		return ret_nomem;
	}

	entry->dlopen_ref = dl_handle;
	entry->info       = info;
	entry->built_in   = false;

	ret = cherokee_avl_add_ptr (&loader->table, modname, entry);
	if (unlikely(ret != ret_ok)) {
		dlclose (entry->dlopen_ref);
		free(entry);
		return ret;
	}

	/* Execute init function
	 * 从 dl_handle 中读出插件初始化函数cherokee_plugin_<name>_init, 并调用
	 */
	ret = execute_init_func (loader, modname, entry);
	if (ret != ret_ok) {
		return ret;
	}

	return ret_ok;
}



// 取得插件结构体
ret_t
cherokee_plugin_loader_get (cherokee_plugin_loader_t  *loader,
			    const char                *modname,
			    cherokee_plugin_info_t   **info)
{
	ret_t ret;
	// 加载插件动态链接库
	ret = cherokee_plugin_loader_load (loader, modname);
	if (ret != ret_ok)
		return ret;
	// 取得结构体
	ret = cherokee_plugin_loader_get_info (loader, modname, info);
	if (ret != ret_ok)
		return ret;

	return ret_ok;
}

  • 大小: 21.1 KB
0
0
分享到:
评论

相关推荐

    cherokee-0.99.1.tar.gz

    4. **模块化设计**:Cherokee 采用模块化的架构,可以根据需要加载或卸载功能模块,实现高度定制。 5. **实时性能监控**:内置实时性能监控工具,可以监控服务器状态,包括连接数、请求速率、内存使用等。 6. **...

    cherokee 和 Apache 服务器性能比较

    Cherokee 和 Apache 服务器性能比较 在本文中,我们将比较两种流行的 Web 服务器software:Cherokee 和 Apache。我们将从性能角度出发,对它们进行比较,以确定哪种服务器更适合我们的网站。 首先,让我们来看一下...

    Cherokee v1.2.101.zip

    Cherokee是一种非常快速、灵活、轻量级的网络服务器,这是完全用C实现的,并已超出了标准C库没有依赖,Cherokee是一个轻量级的Web服务器和所有最灵活。它是嵌入,用插件扩展。它支持通过阅读文件或字符串上进行动态...

    Cherokee v1.2.100

    Cherokee 是一个非常快速,灵活和轻便的Web服务器。它是用C语言编写。Cherokee 支持 FastCGI、SCGI、PHP、CGI、TLS 及 SSL 加密连接,虚拟主机,授权认证,实时编码,载入均衡,与 Apache 兼容的 log 文件等等。

    google-noto-sans-cherokee-fonts-20141117-5.el7.noarch.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    克莱斯勒Cherokee联合品牌车身电气.pptx

    【克莱斯勒Cherokee联合品牌车身电气】课程涵盖了克莱斯勒Cherokee车型的车身电气系统,旨在让学员深入了解车辆的电气结构和功能。课程主要内容包括: 1. **控制模块识别**:学员需能准确指出WK车辆上所有控制模块...

    Cherokee.applife.net.rar

    Cherokee 号称是目前最快的 Web 服务器软件,在性能上,甚至比 Nginx 还略胜一筹。与 Apache、Lighttpd、Nginx 等其他同类软件的对比,大家不妨看看这个测试页面。其易用性做得也很不错。

    Cherokee维修手册(1)燃油喷射式发动机·底盘·车身(2)

    切诺基维修手册,第二册,共五册,留给需要的童鞋

    克莱斯勒Cherokee漫步者 快速维修技术资料手册.doc

    9. **差速器与动力传动系统诊断故障码**:这些代码帮助识别和解决传动系统问题,包括差速器和动力传输单元的故障。 10. **ABS及APS的DTC故障码和验证测试**:针对防抱死制动系统(ABS)和加速踏板位置传感器(APS)...

    基于ASP的马克斯cms 采集插件.zip

    4. **跨平台性**:尽管ASP最初是为Windows环境设计的,但现在也有非微软平台的实现,如Cherokee Web Server等。 【马克斯CMS系统】 马克斯CMS(MaxCMS)是一款基于ASP开发的开源内容管理系统,它提供了一套完整的...

    克莱斯勒Cherokee联合品牌车身电气electrical3.pptx

    克莱斯勒Cherokee车身电气系统是一个复杂的网络,涵盖了车辆的各种照明和电气功能。该系统主要由SCM(车身控制模块)和FCM(前端控制模块)协同工作,通过CAN(控制器局域网络)进行通信,确保各个电气部件的高效...

    基于ASP的酷博MTV免维护插件版.zip

    6. **跨平台**:虽然ASP最初是为Windows平台设计的,但通过IIS(Internet Information Services)或其他兼容的Web服务器,如Cherokee、Apache(通过ASP模块)等,可以在非Windows系统上运行。 对于“酷博MTV免维护...

    Cherokee-开源

    Cherokee是一款开源自动化引擎,专为Java小程序设计。它的核心特性在于其高度的可扩展性和脚本编写能力,使得用户可以根据需求定制化自己的自动化流程。Cherokee的目标是为Java Applet提供一个简单易用但功能强大的...

    cherokee.github.com:切诺基网页

    切诺基(Cherokee)是一个快速且功能丰富的开源Web服务器,设计用于处理高并发场景。在GitHub上,有一个名为"cherokee.github.com"的项目,它似乎与维护切诺基的官方网站有关。根据描述,这个项目的网站是用静态站点...

    Cherokee维修手册(3)化油器式发动机

    切诺基维修手册第五册,共五册,留给需要的同学

    Cherokee维修手册(2)电器·暖风·空调

    切诺基维修手册第四册,共五册,留给需要的同学

    便民服务查询网 -ASP源码.zip

    4. **跨平台**:虽然ASP最初是为Windows环境设计的,但现在有第三方工具(如Cherokee或XAMPP)可以在其他操作系统上运行ASP。 【解压密码】 描述中提到的“www.cqlsoft.com”是压缩包的解压密码。这可能是为了保护...

    Cherokee维修手册(1)燃油喷射式发动机·底盘·车身(1)

    切诺基维修手册PDF版,留给需要的同学。本书共5册。

Global site tag (gtag.js) - Google Analytics