Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

能否提供一个兼容层,以方便在现有软件中使用libhv替代libevent? #354

Open
he7850 opened this issue Mar 25, 2023 · 4 comments

Comments

@he7850
Copy link

he7850 commented Mar 25, 2023

大部分Linux操作系统中,都已经集成了libevent,并且很多关键软件中都大量使用了libevent接口。
如果想要在已有软件中使用libhv替代libevent,必须适配软件中所有使用libevent接口的位置,调整成使用libhv接口,这个修改量是相当大的,非常困难。
但如果libhv能实现libevent库的一些核心接口,那么就可以无需适配下游软件,直接将下游软件使用的头文件换为libhv头文件即可。

想问一下,当前是否有计划在libhv中提供一个兼容层?兼容层实现可以参考libev:http://cvs.schmorp.de/libev/event.c

如果这个兼容层能够实现,像一些国产操作系统社区,比如openEuler,都可以推动将libhv作为核心系统组件集成到系统中,带来更广泛的使用。

@he7850 he7850 changed the title 能否在无需适配下游软件接口使用的前提下,使用libhv替代libevent? 能否提供一个兼容层,以方便在现有软件中使用libhv替代libevent? Mar 27, 2023
@he7850
Copy link
Author

he7850 commented Mar 27, 2023

兼容层只需实现少量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

@ptbxzrt
Copy link

ptbxzrt commented Jul 13, 2023

openEuler社区今年在开源之夏有一个项目 ,正好可以用您说的这个思路实现。这个项目目前由我跟进,我会尝试基于libhv实现一个libevent兼容层。

@ithewei
Copy link
Owner

ithewei commented Jul 14, 2023

我写了部分实现,可以参考下:

#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

@ptbxzrt
Copy link

ptbxzrt commented Jul 14, 2023

我写了部分实现,可以参考下:

#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

感谢!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants