libevent 源码分析event_base
在tcp通信中,会用到event_base这个结构体。
下面来看看这个结构体。
event_base_new(),创建event_base
/** * Create and return a new event_base to use with the rest of Libevent. * 创建并返回一个新的event_base 给libevent的其它部分使用。 * @return a new event_base on success, or NULL on failure. * 成功的话,返回一个新的event_base, 失败返回NULL。 * @see event_base_free(), event_base_new_with_config() */ EVENT2_EXPORT_SYMBOL struct event_base *event_base_new(void);
truct event_base * event_base_new(void) { struct event_base *base = NULL; struct event_config *cfg = event_config_new(); if (cfg) { base = event_base_new_with_config(cfg); event_config_free(cfg); } return base; }
通过上面的代码,可以知道,在创建event_base时,需要用到event_config对象。
结构体event_config.
/** Internal structure: describes the configuration we want for an event_base * that we're about to allocate. */ 内部结构体:描叙了我们准备分配的一个event_base的配置 struct event_config { TAILQ_HEAD(event_configq, event_config_entry) entries; //定义一个tail queue int n_cpus_hint; struct timeval max_dispatch_interval; int max_dispatch_callbacks; int limit_callbacks_after_prio; enum event_method_feature require_features; enum event_base_config_flag flags; };
创建event_config对象,用到接口event_config_new
继续跟踪event_config_new
/** Allocates a new event configuration object. The event configuration object can be used to change the behavior of an event base. @return an event_config object that can be used to store configuration, or NULL if an error is encountered. @see event_base_new_with_config(), event_config_free(), event_config */ EVENT2_EXPORT_SYMBOL struct event_config *event_config_new(void);
struct event_config * event_config_new(void) { struct event_config *cfg = mm_calloc(1, sizeof(*cfg)); if (cfg == NULL) return (NULL); TAILQ_INIT(&cfg->entries); cfg->max_dispatch_interval.tv_sec = -1; cfg->max_dispatch_callbacks = INT_MAX; cfg->limit_callbacks_after_prio = 1; return (cfg); }
获取到event_config对象后,可以开始创建event_base对象。
接口event_base_new_with_config.
/** Initialize the event API. 初始化接口 Use event_base_new_with_config() to initialize a new event base, taking the specified configuration under consideration. The configuration object can currently be used to avoid certain event notification mechanisms. 根据预先制定的配置,用event_base_new_with_config() 来初始化一个新的event base。 @param cfg the event configuration object event configuration 对象 @return an initialized event_base that can be used to registering events, or NULL if no event base can be created with the requested event_config. 一个初始化的event_base,可以用于注册events,也可能是NULL(当根据指定的event_config,没有创建成功event base) @see event_base_new(), event_base_free(), event_init(), event_assign() */ EVENT2_EXPORT_SYMBOL struct event_base *event_base_new_with_config(const struct event_config *cfg);
struct event_base * event_base_new_with_config(const struct event_config *cfg) { int i; struct event_base *base; int should_check_environment; #ifndef EVENT__DISABLE_DEBUG_MODE event_debug_mode_too_late = 1; #endif if ((base = mm_calloc(1, sizeof(struct event_base))) == NULL) { event_warn("%s: calloc", __func__); return NULL; } if (cfg) base->flags = cfg->flags; should_check_environment = !(cfg && (cfg->flags & EVENT_BASE_FLAG_IGNORE_ENV)); { struct timeval tmp; int precise_time = cfg && (cfg->flags & EVENT_BASE_FLAG_PRECISE_TIMER); int flags; if (should_check_environment && !precise_time) { precise_time = evutil_getenv_("EVENT_PRECISE_TIMER") != NULL; if (precise_time) { base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER; } } flags = precise_time ? EV_MONOT_PRECISE : 0; evutil_configure_monotonic_time_(&base->monotonic_timer, flags); gettime(base, &tmp); } min_heap_ctor_(&base->timeheap); base->sig.ev_signal_pair[0] = -1; base->sig.ev_signal_pair[1] = -1; base->th_notify_fd[0] = -1; base->th_notify_fd[1] = -1; TAILQ_INIT(&base->active_later_queue); evmap_io_initmap_(&base->io); evmap_signal_initmap_(&base->sigmap); event_changelist_init_(&base->changelist); base->evbase = NULL; if (cfg) { memcpy(&base->max_dispatch_time, &cfg->max_dispatch_interval, sizeof(struct timeval)); base->limit_callbacks_after_prio = cfg->limit_callbacks_after_prio; } else { base->max_dispatch_time.tv_sec = -1; base->limit_callbacks_after_prio = 1; } if (cfg && cfg->max_dispatch_callbacks >= 0) { base->max_dispatch_callbacks = cfg->max_dispatch_callbacks; } else { base->max_dispatch_callbacks = INT_MAX; } if (base->max_dispatch_callbacks == INT_MAX && base->max_dispatch_time.tv_sec == -1) base->limit_callbacks_after_prio = INT_MAX; for (i = 0; eventops[i] && !base->evbase; i++) { if (cfg != NULL) { /* determine if this backend should be avoided */ if (event_config_is_avoided_method(cfg, eventops[i]->name)) continue; if ((eventops[i]->features & cfg->require_features) != cfg->require_features) continue; } /* also obey the environment variables */ if (should_check_environment && event_is_method_disabled(eventops[i]->name)) continue; base->evsel = eventops[i]; base->evbase = base->evsel->init(base); } if (base->evbase == NULL) { event_warnx("%s: no event mechanism available", __func__); base->evsel = NULL; event_base_free(base); return NULL; } if (evutil_getenv_("EVENT_SHOW_METHOD")) event_msgx("libevent using: %s", base->evsel->name); /* allocate a single active event queue */ if (event_base_priority_init(base, 1) < 0) { event_base_free(base); return NULL; } /* prepare for threading */ #if !defined(EVENT__DISABLE_THREAD_SUPPORT) && !defined(EVENT__DISABLE_DEBUG_MODE) event_debug_created_threadable_ctx_ = 1; #endif #ifndef EVENT__DISABLE_THREAD_SUPPORT if (EVTHREAD_LOCKING_ENABLED() && (!cfg || !(cfg->flags & EVENT_BASE_FLAG_NOLOCK))) { int r; EVTHREAD_ALLOC_LOCK(base->th_base_lock, 0); EVTHREAD_ALLOC_COND(base->current_event_cond); r = evthread_make_base_notifiable(base); if (r<0) { event_warnx("%s: Unable to make base notifiable.", __func__); event_base_free(base); return NULL; } } #endif #ifdef _WIN32 if (cfg && (cfg->flags & EVENT_BASE_FLAG_STARTUP_IOCP)) event_base_start_iocp_(base, cfg->n_cpus_hint); #endif /* initialize watcher lists */ for (i = 0; i < EVWATCH_MAX; ++i) TAILQ_INIT(&base->watchers[i]); return (base); }
至此获取到了一个初始化后的base。
这里可以看出base的创建和event_base_config有密切的关系,目前不对config进行深入的分析。

浙公网安备 33010602011771号