libhv icon indicating copy to clipboard operation
libhv copied to clipboard

libhv什么接口可以替换libevent中的event_new添加信号的功能?

Open gtoo8888 opened this issue 1 year ago • 5 comments

现在我正在实现一个功能,有一个异步事件循环的库libverto,内部实现了libevent,libhv,glib来实现事件循环,我现在正在尝试使用libhv作为底层的事件循环库 这是libverto库中,使用libevent的接口来添加信号处理的功能的位置

static verto_mod_ev *
libevent_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
{
    struct event *priv = NULL;
    XXXXXX
    case VERTO_EV_TYPE_SIGNAL:
        priv = event_new(ctx, verto_get_signal(ev),
                            EV_SIGNAL | libeventflags,
                            libevent_callback, (void *) ev);
        break;
    XXXXX
}

现在我想使用libhv替代libevent实现这个功能 我之前尝试了下面这两个函数,我发现是命令行处理的函数,没法达到添加信号的目的

signal_init(on_reload);
signal_handle(signal);

我在这个issue354中找到了有人尝试使用libhv替代libevent,但是我看写的还不完善 不知道需要替代掉event_new这个接口,libhv应该用什么接口实现

gtoo8888 avatar Aug 31 '23 08:08 gtoo8888

libhv里没有直接提供将signal封装成事件,投递到loop里,你可以这么实现

void signal_event_cb(hevent_t* ev) {
    // ...
}

void signal_func(int signo) {
    hevent_t ev;
    ev.cb = signal_event_cb;
    // ...
    hloop_post_event(loop, &ev);
}

signal(SIGXXX, signal_func);

ithewei avatar Sep 01 '23 07:09 ithewei

signal_func是signal的回调函数,只能传递int signo这个参数进去,我这边不方便使用全局变量,那我应该怎么把loop这个参数传进去

gtoo8888 avatar Sep 07 '23 09:09 gtoo8888

signal本身是中断执行的,上面把这个信号转化为一个有序的事件,扔给指定的loop去处理,你可以看看libevent里面的实现,也是使用一个static event_base* evsig_base来保存这个loop对象的

ithewei avatar Sep 07 '23 13:09 ithewei

不好意思,之前一直有事耽搁,最近做了一下尝试,想问下对于你写的参考函数

void signal_func(int signo) {
    hevent_t ev;
    ev.cb = signal_event_cb;
    // ...
    hloop_post_event(loop, &ev); // 如何传入loop变量
}

我去参考了下signal函数的使用,它仅仅接收一个int参数,用来表示传入的信号,那如何将loop变量传入到signal_func中呢 不知道还有什么实现方式

/* Type of a signal handler.  */
typedef void (*__sighandler_t) (int);

gtoo8888 avatar Oct 07 '23 14:10 gtoo8888

我自己尝试增加一下添加信号的功能,我现在自己做的尝试

// hloop.h
typedef struct hsignal_s    hsignal_t;

typedef void (*hsignal_cb)  (hsignal_t* hsignal);

HV_EXPORT hsignal_t* hsignal_add(hloop_t* loop, hsignal_cb cb, int signal_type, uint32_t repeat DEFAULT(INFINITE));
// hloop.c
hsignal_t* hsignal_add(hloop_t* loop, hsignal_cb cb, int signal_type, uint32_t repeat){
    hsignal_t *hsignal;
    HV_ALLOC_SIZEOF(hsignal);
    hsignal->signal_type = signal_type;
    hsignal->priority = HEVENT_HIGHEST_PRIORITY;
    hsignal->repeat = repeat;
    EVENT_ADD(loop, hsignal, cb);
    return (hsignal_t*)hsignal;
}
// hevent.c
struct hsignal_s{
    HEVENT_FIELDS  
    uint32_t    repeat;
    int         signal_type;
};

现在发现,应当在hloop_process_events中做一些处理,比如添加hloop_process_signal函数,不知道应该怎么做

// hevent.c
int hloop_process_events(hloop_t* loop, int timeout_ms) {
    int nios, ntimers, nidles;
    nios = ntimers = nidles = 0;
    // ...
    nios = hloop_process_ios(loop, blocktime_ms);
    // ...
    ntimers = hloop_process_timers(loop);
    // ...
    nidles= hloop_process_idles(loop);
    // ...
    int ncbs = hloop_process_pendings(loop);
    return ncbs;
}

gtoo8888 avatar Oct 07 '23 14:10 gtoo8888