Libevent参考手册第一章:设置libevent
2013-12-07 23:58
148 查看
Nick Mathewson 著
晨星 翻译
老衣 整理
libevent有一些被整个进程共享的、影响整个库的全局设置。必须在调用libevent库的任何其他部分之前修改这些设置,否则,libevent会进入不一致的状态。1 Libevent中的日志消息
libevent可以记录内部错误和警告。如果编译进日志支持,还会记录调试信息。默认配置下这些信息被写到stderr。通过提供定制的日志函数可以覆盖默认行为。接口
示例
[cpp] view plaincopy#include <event2/event.h>
#include <stdio.h>
static void discard_cb(int severity, const char *msg)
{
/* This callback does nothing. */
}
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; /* never reached */
}
fprintf(logfile, "[%s] %s/n", s, msg);
}
/* Turn off all logging from Libevent. */
void suppress_logging(void)
{
event_set_log_callback(discard_cb);
}
/* Redirect all Libevent log messages to the C stdio file 'f'. */
void set_logfile(FILE *f)
{
logfile = f;
event_set_log_callback(write_to_file_cb);
}
注意
在用户提供的event_log_cb回调函数中调用libevent函数是不安全的。比如说,如果试图编写一个使用bufferevent将警告信息发送给某个套接字的日志回调函数,可能会遇到奇怪而难以诊断的bug。未来版本libevent的某些函数可能会移除这个限制。这个函数在<event2/event.h>中声明,在libevent 1.0c版本中首次出现。
2 处理致命错误
libevent在检测到不可恢复的内部错误时的默认行为是调用exit()或者abort(),退出正在运行的进程。这类错误通常意味着某处有bug:要么在你的代码中,要么在libevent中。如果希望更优雅地处理致命错误,可以为libevent提供在退出时应该调用的函数,覆盖默认行为。
接口
[cpp] view plaincopytypedef void (*event_fatal_cb)(int err);
void event_set_fatal_callback(event_fatal_cb cb);
3 内存管理
默认情况下,libevent使用C库的内存管理函数在堆上分配内存。通过提供malloc、realloc和free的替代函数,可以让libevent使用其他的内存管理器。希望libevent使用一个更高效的分配器时,或者希望libevent使用一个工具分配器以便检查内存泄漏时,可能需要这样做。接口
[c-sharp] view plaincopyvoid event_set_mem_functions(void *(*malloc_fn)(size_t sz),
void *(*realloc_fn)(void *ptr, size_t sz),
void (*free_fn)(void *ptr));
这里有个替换libevent分配器函数的示例,它可以计算已经分配的字节数。实际应用中可能需要添加锁,以避免运行在多个线程中时发生错误。
示例
[cpp] view plaincopy#include <event2/event.h>
#include <sys/types.h>
#include <stdlib.h>
/* This union's purpose is to be as big as the largest of all the
* types it contains. */
union alignment {
size_t sz;
void *ptr;
double dbl;
};
/* We need to make sure that everything we return is on the right
alignment to hold anything, including a double. */
#define ALIGNMENT sizeof(union alignment)
/* We need to do this cast-to-char* trick on our pointers to adjust
them; doing arithmetic on a void* is not standard. */
#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);
}
注意
² 替换内存管理函数影响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函数。
event_set_mem_functions函数声明在<event2/event.h>中,在libevent 2.0.1-alpha版本中首次出现。
可以在禁止event_set_mem_functions函数的配置下编译libevent。这时候使用event_set_mem_functions将不会编译或者链接。在2.0.2-alpha及以后版本中,可以通过检查是否定义了EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED宏来确定event_set_mem_functions函数是否存在。
相关文章推荐
- Libevent参考手册第一章:设置libevent (三)
- Libevent参考手册第一章:设置libevent(一)
- Libevent参考手册第一章:设置libevent(二)
- Libevent参考手册第一章:设置libevent(一)
- Libevent参考手册第一章:设置libevent(二)
- [翻译]Libevent 参考手册(一) -- 设置 Libevent 库
- Libevent参考手册:设置libevent(二)
- Libevent参考手册:设置libevent(一)
- Libevent参考手册第八章:连接侦听器: 接受 TCP 连接
- Libevent参考手册:evbuffer:缓冲IO实用功能
- ARM920T技术参考手册&amp;amp;S3C2440汇编指令设置
- libevent 第一章 设置libevent
- JBoss4 应用服务器Web开发人员参考手册(7):设置虚拟主机
- libevent 参考手册-前言
- 知识积累(四)——Acegi (version1.0.4)中文参考手册——第一章 简介
- [翻译]Libevent 参考手册:前言
- Spring框架参考手册_5.0.0_中文版_Part I_第一章
- Spring框架参考手册_5.0.0_中英文对照版_Part I_第一章
- PHP - Manual手册 - 函数参考 - Variable 变量函数 - settype设置变量的类型
- libevent参考手册第五章:辅助类型和函数