acl 3.3.0 版本发布了,acl 是 one advanced C/C++ library 的简称,主要包括网络通信库以及服务器框架库等功能,支持 Linux/Windows/Solaris/FreeBsd/MacOS 平台;整个 acl 项目主要包含四个函数库:lib_acl(纯C开发的基础库,主要包含网络通信及服务器编程框架以及其它丰富的功能)、lib_protocol(包含 HTTP/PING/SMTP 通信协议的C语言实现)、lib_fiber(网络协程库)、lib_acl_cpp(基于 lib_acl 及 lib_protocol 两个C库,提供了更为强大的编程接口及丰富的功能类)。

本次 acl 升级为大版本升级,主要内容为:全面支持移动端(Android, IOS)平台,支持 IPV6,协程库功能更加完善,修复了 redis 客户端库几处关键问题;此外,还增加了 cmake 支持,修复了其它多处问题。

acl 包括以下丰富的常用函数库:
1、服务器框架:包括进程池模式、线程池模式、非阻塞模式、UDP通信模式、触发器模式以及协程模式
2、网络通信库:阻塞/非阻塞网络 IO 库(其中 lib_acl_cpp 库通过嵌入 polarssl 而具备了 SSL 通信能力)
3、HTTP 网络库:HTTP 客户端/服务端库,HTTP 服务端支持 HttpServlet 接口访问方式;支持 HTTP cookies/session;HTTP 客户端支持连接池及连接池集群;支持 Websocket
4、redis 客户端库:实现了 redis 客户端命令中 12 个大类中的总共 150 多个命令,支持连接池及集群连接池方式
5、常见网络应用库: SMTP 客户端库/PING 库/DNS 解析库/memcache 客户端库/handler socket 客户端库/beanstalk 客户端库/disque 客户端库
6、邮件解析库:mime解析库/RFC2047/RFC2048/mime base64/mime qp/mime uucode 等
7、事件引擎:支持 select、poll(for unix)、epoll(for linux)、kqueue(for bsd)、devpoll(for solaris)、iocp(for win32)、win32 窗口消息(for win32)事件引擎
8、通用连接池库:高效的连接池基础类库,支持丰富的功能
9、数据库客户端库:对原生的数据库客户端库进行了二次封装,使编程更为简易,功能更为丰富,支持连接池及连接池集群管理功能
10、xml/json 流式解析库:区别于网上其它已有的 xml/json 解析库,acl 中的 xml/json 解析库采用有限状态机方式解析数据,处理方式更为灵活
11、网络协程库:该库将阻塞 IO 模式在底层通过上下文切换和事件触发方式转变为非阻塞模式,从而方便程序员快速编写高并发、高性能的网络服务
12、支持将 C++ struct 对象序列化与反序列化(序列化为 Json 对象及由 Json 对象反序列化)

示例:
1、lib_acl/samples: 该目录下有大量的基于 lib_acl C 库的示例
2、lib_protocol/samples: 该目录下有大量的基于 lib_protocol C 库的示例
3、lib_acl_cpp/samples: 该目录下有大量的基于 lib_acl_cpp C++ 库的示例
4、lib_fiber/samples:该目录下有大量的基于协程的网络客户端/服务端示例

应用:
1、app/redis_tools: 该目录下为 redis 集群管理、监控及智能创建工具
2、app/wizard:用来自动生成 acl 服务器框架的向导程序
3、app/master_dispatch:用于管理和分发客户端连接的服务程序
4、app/gid:用来产生全局唯一整型 ID 的服务程序及客户端库
5、app/wizard_demo:为一些服务器测试程序
6、app/gson:json 序列化及反序列化代码生成工具

一、基础 C 库:lib_acl
.新特性:增加了内存调试函数 acl_default_meminfo 用来显示内存分配及释放情况
.新特性:acl_master 服务器框架支持监听地址的模糊匹配机制,以便于多机部署时的配置文件一致性
.新特性:acl_aio_server.c/acl_threads_server.c/acl_single_server.c 增加回调函数 __service_on_listen,以便于将监听的流对象传递给应用
.新特性:acl_mem_slice.c 中的函数 tls_mem_realloc 允许源指针为 NULL
.新特性:json 类对象在创建 json 字符串时默认不自动添加空格,但允许调用者设置参数以便于自动添加空格从而使 json 字符串更可读
.新特性:所有网络模块均支持 IPV6

.问题修复:acl_vstream.c 中的函数 acl_vstream_fdopen 设置 IO 句柄为非阻塞模式是存在问题的,上层应用应该自己决定是否设为非阻塞模式
.问题修复:acl_slice.c 中修复了 SLICE1 方式分配内存的一处 BUG
.问题修复:acl_dbuf_pool.c 支持 ARM LINUX,内部在分配内存片时,应该是 4 字节对齐
.问题修复:acl_scan_dir.c 中函数 acl_scan_dir_push 在 windows 下存在问题,会造成死循环
.问题修复:acl_atomic.c/acl_mbox.c/acl_pthread_mutext.c 存在内存泄露问题
.问题修复:rfc1035.c 中的函数 rfc1035MessageUnpack 存在内存泄露
.问题修复:acl_pthread_cond.c 中在 windows 平台下当释放线程锁时会造成内存重复释放的问题,主要还是 acl_pthread_mutex_create 的函数设计不合理所致,故去掉了 acl_pthread_mutex_create 以免引起误用

.编译:在 Linux/Android/Macos/IOS/FreeBSD/Windows 平台下编译时,由头文件自动识别操作系统类型,无需在 Makefile 文件中专门指定

二、lib_protocol 库
.无变化

三、lib_acl_cpp 库
.新特性:master_proc.cpp/master_threads.cpp/master_aio.cpp 的类中增加虚方法 (proc_)on_listen,以便将监听对象传递给应用
.新特性:redis_command/redis_client 增加连接 IP 地址校验检测功能,主要用于调试情况
.新特性:json.cpp 中 json 类及 json_node 类中的 to_string 方法允许复用用户传入的缓冲区
.新特性:gson 对象序列化模块支持 struct 对象的成员函数及非序列化成员变量
.新特性:gson 对象序列化模块增加成员函数限定符的支持
.新特性:db 模块中 db_handle/db_mysql/db_sqlite 在查询时,允许将结果集存储于用户输入的对象中,从而实现结果集与 db 句柄分离的目的
.新特性:db_handle 模块支持事务回滚
.新特性:json 类对象在创建 json 字符串时默认不自动添加空格,但允许调用者设置参数以便于自动添加空格从而使 json 字符串更可读
.新特性:增加 mbox 类用于消息队列的发送与读取,该类封装了 C 对象 ACL_MBOX

.问题修复:redis_result::argv_to_string 返回值应该 >= 0
.问题修复:redis_command::run() 中当循环次数超过阀值后应该将连接归还给连接池
.问题修复:redis_list::bpop 及 redis_pubsub::get_message 的超时时间应不受 socket_stream 里的超时时间影响
.问题修复:redis_script 类中的参数顺序有误
.问题修复:redis_client.cpp 中的 run 方法在进行连接重试时,如果请求数据为空,则不应进行重试,而是应直接给上层应用返回失败,由应用层处理,比如对于 redis_pubsub 类中的方法 get_message 是没有请求命令的,针对此情况的连接重试,并不会重新获得订阅信息
.问题修复:redis_pubsub 类中如果通过 psubcribe 订阅消息时,get_message 则会出错,需要 get_message 使其同时支持 subcribe 及 psubscribe
.问题修复:redis_command::run 中当遇到 ASK 命令执行重定向成功,但紧接着执行命令时如果失败,则应该将该连接归还给连接池
.问题修复:redis_command::run 当连接异常断开时应该对 request_obj_ 判空
.问题修复:redis_command::run 当连接异常断开时,在将连接归还给连接池时应提前保留连接池对象以备下面使用
.问题修复:istream.cpp 中的 gets 函数不应当读超时时设置 eof_ 标志位
.问题修复:master_threads.cpp 中 thread_on_handshake 被调用了两次
.问题修复:gson 对象序列化模块修改了 std::map 第二个参数不能为类对象的问题
.问题修复:当启用 -DNDEBUG 编译选项时,内部一些调用 assert 的语句会被过滤掉,可能导致一些代码逻辑无法执行
.问题修复:db_mysql.cpp 当进程退出前会自动卸载 mysql 动态库,但 mysql 的句柄有可能会在该操作后发生,从而造成程序崩溃,增加判断条件以防止此问题发生
.问题修复:db_mysql/db_sqlite 模块当采用静态方式使用时,编译出错

.编译:gsoner.cpp, http_header.cpp 用 VC x64 编译时有警告

四、lib_fiber 库
.新特性:增加 acl_fiber_kill 接口用来通知指定协程退出
.新特性:fiber.cpp 中,fiber 类增加了 kill 和 killed 方法用来”杀死“协程和判断指定协程是否已经退出
.新特性:acl_fiber_kill 可以支持因调用 acl_fiber_sleep, acl_fiber_sem, acl_fiber_mutex_lock 而阻塞的协程
.新特性:fiber.c 中有关协程局部变量的接口调整,更符合实际应用场景
.新特性:fiber.cpp 允许将当前运行的协程与 fiber 类对象绑定(只需在构造函数中将构造参数设为 true),从而可以方便使用类 fiber 中的方法
.新特性:增加 acl_fiber_signal 函数,允许协程给其它协程发送唤醒信号
.新特性:fiber.c 中 acl_fiber_signal/acl_fiber_kill 中,需要设置 errno 为 ECANCELED
.新特性:fiber.c 中 fiber_alloc 函数当复用缓存的协程内存对象时,应调用 free->malloc,而不是调用 realloc,这样一方面可以避免使用 tcmalloc 时的 valgrind 的内存警告,另一方面,可以有效地使用虚存
.新特性:协程信号量当被跨线程使用时,禁止出现同一信号量被不同线程使用
.新特性:hook_net.c 中新增对 getaddrinfo 的支持

.问题修复:fiber.c 中函数 acl_fiber_create 中存在运行时内存增长问题,即 __thread_fiber->fibers 对象在 realloc 过程中内存不断增长,因为 __thread_fier->size 计算方法有问题
.问题修复:hook_net.c 中,当非协程模式下,hook epoll 相关 API 应该加以区别
.问题修复:hook_net.c, hook_io.c, event_epoll.c 其中因为 hook 了很多系统的 API,当个别应用在 main 函数执行前需要调用这些 API 时可能会因为 hook 操作还未进行而造成函数指针为 NULL,从而导致程序崩溃
.问题修复:fiber.c 中当协程退出时,协程局部变量的对象未释放造成内存泄露
.问题修复:fiber.cpp 中 kill 方法需将 f_ 成员置 NULL,防止嵌套访问非法地址
.问题修复:协程在双通模式下,如果写时堵塞会导致读也堵塞,是因为延迟关闭及事件设置不合理
.问题修复:fiber.c 中,fiber_init 函数应该必须保证 __sys_errno 为 NULL 时被调用,否则会引起一些静态初始化需要 __sys_errno 的使用
.问题修复:当一个协程处于 poll wait 状态时被另一个协程 kill 掉时,会造成内存非法访问,修复方式是在 event.c 中对 poll list 的遍历访问采用 pop 方式,同时在 hook_net.c 中的 poll 函数中当被 kill 时自动清理自身,与本 BUG 相关的文件有 fiber.c, hook_net.c, event.c,其中 hook_net.c 及 event.c 中的修复是最关键的

.示例:samples/fiber_local,该示例用于测试协程局部变量

五、参考链接:
oschina git:https://git.oschina.net/zsxxsz/acl
github: https://github.com/zhengshuxin/acl/
sourceforge:http://sourceforge.net/projects/acl/



新闻来源:acl_3.3.0 发布,跨平台网络通信与服务器框架