libhv
libhv copied to clipboard
能否提供一个兼容层,以方便在现有软件中使用libhv替代libevent?
大部分Linux操作系统中,都已经集成了libevent,并且很多关键软件中都大量使用了libevent接口。 如果想要在已有软件中使用libhv替代libevent,必须适配软件中所有使用libevent接口的位置,调整成使用libhv接口,这个修改量是相当大的,非常困难。 但如果libhv能实现libevent库的一些核心接口,那么就可以无需适配下游软件,直接将下游软件使用的头文件换为libhv头文件即可。
想问一下,当前是否有计划在libhv中提供一个兼容层?兼容层实现可以参考libev:http://cvs.schmorp.de/libev/event.c
如果这个兼容层能够实现,像一些国产操作系统社区,比如openEuler,都可以推动将libhv作为核心系统组件集成到系统中,带来更广泛的使用。
兼容层只需实现少量libevent接口。比如说, nfs-utils中使用的:
event_init
event_add
event_del
event_dispatch
event_set
event_initialized
avahi中使用的:
event_new
event_free
event_add
event_del
event_base_free
event_base_new
event_base_dispatch
event_assign
event_base_loopbreak
event_pending
event_get_fd
event_loop
openEuler社区今年在开源之夏有一个项目 ,正好可以用您说的这个思路实现。这个项目目前由我跟进,我会尝试基于libhv实现一个libevent兼容层。
我写了部分实现,可以参考下:
#ifndef HV_LIBEVENT_COMPAT_H_
#define HV_LIBEVENT_COMPAT_H
#include "hexport.h"
#include "hloop.h"
#define event_base hloop_s;
#define event hio_s;
#define EV_READ HV_READ
#define EV_WRITE HV_WRITE
typedef int evutil_socket_t;
typedef void (*event_callback_fn)(evutil_socket_t fd, short events, void *callback_arg);
HV_INLINE struct event_base *event_base_new(void) {
return hloop_new(0);
}
HV_INLINE void event_base_free(struct event_base *eb) {
hloop_free(&eb);
}
HV_INLINE int event_base_dispatch(struct event_base *eb) {
return hloop_run(eb);
}
HV_INLINE int event_base_loopbreak(struct event_base *eb) {
return hloop_stop(eb);
}
HV_INLINE void on_readable(hio_t* io) {
struct hloop_s *base = hevent_loop(io);
int fd = hio_fd(io);
short events = EV_READ;
event_callback_fn callback = (event_callback_fn)hio_context(io);
void* callback_arg = (void*)hevent_userdata(io);
if (callback) {
callback(base, fd, events, callback_arg);
}
}
HV_INLINE void on_writable(hio_t* io) {
struct hloop_s *base = hevent_loop(io);
int fd = hio_fd(io);
short events = EV_WRITE;
event_callback_fn callback = (event_callback_fn)hio_context(io);
void* callback_arg = (void*)hevent_userdata(io);
if (callback) {
callback(base, fd, events, callback_arg);
}
}
int event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg) {
struct hio_s *io = (struct hio_s*)ev;
// NOTE: use io->context to save callback, event->userdata to save callback_arg
hio_set_context(io, callback);
hevent_set_userdata(io, callback_arg);
if (events & EV_READ) {
hio_add(io, on_readable, HV_READ);
}
if (events & EV_WRITE) {
hio_add(io, on_writable, HV_WRITE);
}
return io;
}
HV_INLINE struct event *event_new(struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg) {
struct hio_s *io = hloop_get(fd);
event_assign(io, base, fd, events, callback, callback_arg);
return io;
}
int event_add(struct event *ev, const struct timeval *timeout) {
void(ev);
void(timeout);
return 0;
}
int event_del(struct event *ev) {
return hio_del(ev);
}
HV_INLINE void event_free(struct event *ev) {
void(ev);
}
HV_INLINE evutil_socket_t event_get_fd(const struct event *ev) {
return hio_fd(ev);
}
HV_INLINE int event_pending(const struct event *ev, short events, struct timeval *tv) {
int added_events = hio_events(ev);
if (added_events & events) return 1;
return 0;
}
HV_INLINE int event_initialized(const struct event *ev) {
void(ev);
return 1;
}
#endif
我写了部分实现,可以参考下:
#ifndef HV_LIBEVENT_COMPAT_H_ #define HV_LIBEVENT_COMPAT_H #include "hexport.h" #include "hloop.h" #define event_base hloop_s; #define event hio_s; #define EV_READ HV_READ #define EV_WRITE HV_WRITE typedef int evutil_socket_t; typedef void (*event_callback_fn)(evutil_socket_t fd, short events, void *callback_arg); HV_INLINE struct event_base *event_base_new(void) { return hloop_new(0); } HV_INLINE void event_base_free(struct event_base *eb) { hloop_free(&eb); } HV_INLINE int event_base_dispatch(struct event_base *eb) { return hloop_run(eb); } HV_INLINE int event_base_loopbreak(struct event_base *eb) { return hloop_stop(eb); } HV_INLINE void on_readable(hio_t* io) { struct hloop_s *base = hevent_loop(io); int fd = hio_fd(io); short events = EV_READ; event_callback_fn callback = (event_callback_fn)hio_context(io); void* callback_arg = (void*)hevent_userdata(io); if (callback) { callback(base, fd, events, callback_arg); } } HV_INLINE void on_writable(hio_t* io) { struct hloop_s *base = hevent_loop(io); int fd = hio_fd(io); short events = EV_WRITE; event_callback_fn callback = (event_callback_fn)hio_context(io); void* callback_arg = (void*)hevent_userdata(io); if (callback) { callback(base, fd, events, callback_arg); } } int event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg) { struct hio_s *io = (struct hio_s*)ev; // NOTE: use io->context to save callback, event->userdata to save callback_arg hio_set_context(io, callback); hevent_set_userdata(io, callback_arg); if (events & EV_READ) { hio_add(io, on_readable, HV_READ); } if (events & EV_WRITE) { hio_add(io, on_writable, HV_WRITE); } return io; } HV_INLINE struct event *event_new(struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg) { struct hio_s *io = hloop_get(fd); event_assign(io, base, fd, events, callback, callback_arg); return io; } int event_add(struct event *ev, const struct timeval *timeout) { void(ev); void(timeout); return 0; } int event_del(struct event *ev) { return hio_del(ev); } HV_INLINE void event_free(struct event *ev) { void(ev); } HV_INLINE evutil_socket_t event_get_fd(const struct event *ev) { return hio_fd(ev); } HV_INLINE int event_pending(const struct event *ev, short events, struct timeval *tv) { int added_events = hio_events(ev); if (added_events & events) return 1; return 0; } HV_INLINE int event_initialized(const struct event *ev) { void(ev); return 1; } #endif
感谢!