惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
爱范儿
爱范儿
宝玉的分享
宝玉的分享
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - Franky
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
博客园 - 聂微东
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 叶小钗
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
博客园 - 司徒正美
博客园 - 【当耐特】
IT之家
IT之家

博客园 - osbreak

ros2::tf2 QML::qml与c++数据交互 k8s:: Service 管理 deployment postgresql 索引 postgresql 基本类型 postgresql 基础运维 PLSQL 触发器 PLSQL 程序包 PLSQL 执行块 PLSQL 基础数据类型 PLSQL oracle安装部署 mysql事务与隔离 mysql慢查询分析 mysql建增删改查 mysql常用总结 (8)libevent 构建libevent http服务,支持文件下载 (7)libevent filter(过滤器) (6)libevent定时器 (5)libevent evbuffer
(9)libevent 常用设置
osbreak · 2023-11-17 · via 博客园 - osbreak

1.日志消息回调设置

  • 要覆盖libevent 的日志行为,编写匹配event_log_cb 签名的定制函数,将其作为参数传递给event_set_log_callback()。
  • event_log_cb 回调函数中调用libevent 函数是不安全的。
#define EVENT_LOG_DEBUG 0
#define EVENT_LOG_MSG   1
#define EVENT_LOG_WARN  2
#define EVENT_LOG_ERR   3

/* Deprecated; see note at the end of this section */
#define _EVENT_LOG_DEBUG EVENT_LOG_DEBUG
#define _EVENT_LOG_MSG   EVENT_LOG_MSG
#define _EVENT_LOG_WARN  EVENT_LOG_WARN
#define _EVENT_LOG_ERR   EVENT_LOG_ERR


typedef void (*event_log_cb)(int severity, const char *msg);
void event_set_log_callback(event_log_cb cb);
#include <event2/event.h>
#include <stdio.h>

static void discard_cb(int severity, const char *msg)
{
}

static FILE *logfile = NULL;
static void write_to_file_cb(int severity, const char *msg)
{
    const char *s;
    if (!logfile)
        return;
    switch (severity) {
        case _EVENT_LOG_DEBUG: s = "debug"; break;
        case _EVENT_LOG_MSG:   s = "msg";   break;
        case _EVENT_LOG_WARN:  s = "warn";  break;
        case _EVENT_LOG_ERR:   s = "error"; break;
        default:               s = "?";     break; 
    }
    fprintf(logfile, "[%s] %s\n", s, msg);
}

void suppress_logging(void)
{
    event_set_log_callback(discard_cb);
}

void set_logfile(FILE *f)
{
    logfile = f;
    event_set_log_callback(write_to_file_cb);
}

2. 致命错误回调设置

在检测到不可恢复的内部错误时的默认行为是调用exit()或者abort(),如果希望更优雅地处理致命错误,可以为libevent 提供在退出时应该调用的函数,覆盖默认行为。

typedef void (*event_fatal_cb)(int err);
void event_set_fatal_callback(event_fatal_cb cb);

3. 内存管理回调设置

通过提供malloc、realloc和free 的替代函数,可以让libevent 使用其他的内存管理器。
需要添加锁,以避免运行在多个线程中时发生错误。
需要注意:

  • 替换内存管理函数影响libevent 随后的所有分配、调整大小和释放内存操作。所以,必须保证在调用任何其他libevent 函数之前进行替换。否则,libevent 可能用你的free 函数释放用C 库的malloc 分配的内存。
  • 你的malloc 和realloc 函数返回的内存块应该具有和C 库返回的内存块一样的地址对齐。
  • 你的realloc 函数应该正确处理realloc(NULL,sz)(也就是当作malloc(sz)处理)
  • 你的realloc 函数应该正确处理realloc(ptr,0)(也就是当作free(ptr)处理)
  • 你的free 函数不必处理free(NULL)
  • 你的malloc 函数不必处理malloc(0)
  • 如果在多个线程中使用libevent,替代的内存管理函数需要是线程安全的。
  • libevent 将使用这些函数分配返回给你的内存。所以,如果要释放由libevent 函数分配和返回的内存,而你已经替换malloc 和realloc 函数,那么应该使用替代的free 函数。
void event_set_mem_functions(void *(*malloc_fn)(size_t sz),
                             void *(*realloc_fn)(void *ptr, size_t sz),
                             void (*free_fn)(void *ptr));
#include <event2/event.h>
#include <sys/types.h>
#include <stdlib.h>

union alignment {
    size_t sz;
    void *ptr;
    double dbl;
};

#define ALIGNMENT sizeof(union alignment)
#define OUTPTR(ptr) (((char*)ptr)+ALIGNMENT)
#define INPTR(ptr) (((char*)ptr)-ALIGNMENT)

static size_t total_allocated = 0;
static void *replacement_malloc(size_t sz)
{
    void *chunk = malloc(sz + ALIGNMENT);
    if (!chunk) return chunk;
    total_allocated += sz;
    *(size_t*)chunk = sz;
    return OUTPTR(chunk);
}

static void *replacement_realloc(void *ptr, size_t sz)
{
    size_t old_size = 0;
    if (ptr) {
        ptr = INPTR(ptr);
        old_size = *(size_t*)ptr;
    }
    ptr = realloc(ptr, sz + ALIGNMENT);
    if (!ptr)
        return NULL;
    *(size_t*)ptr = sz;
    total_allocated = total_allocated - old_size + sz;
    return OUTPTR(ptr);
}

static void replacement_free(void *ptr)
{
    ptr = INPTR(ptr);
    total_allocated -= *(size_t*)ptr;
    free(ptr);
}

void start_counting_bytes(void)
{
    event_set_mem_functions(replacement_malloc,
                            replacement_realloc,
                            replacement_free);
}