eloop: add EV_ONESHOT and EV_SINGLE flags for idle sources
EV_ONESHOT will remove idle sources once they have been processed and EV_SINGLE will only register the source if it hasn't been registered, yet. For source removal EV_ONESHOT has no effect but EV_SINGLE causes all events with this cb+data combination to be removed. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
5ee2338b60
commit
1ef166c12c
22
src/eloop.c
22
src/eloop.c
@ -2297,6 +2297,7 @@ void ev_eloop_unregister_child_cb(struct ev_eloop *loop, ev_child_cb cb,
|
||||
* @eloop: event loop
|
||||
* @cb: user-supplied callback
|
||||
* @data: user-supplied data
|
||||
* @flags: flags
|
||||
*
|
||||
* This register a new idle-source with the given callback and data. @cb must
|
||||
* not be NULL!.
|
||||
@ -2304,14 +2305,19 @@ void ev_eloop_unregister_child_cb(struct ev_eloop *loop, ev_child_cb cb,
|
||||
* Returns: 0 on success, negative error code on failure.
|
||||
*/
|
||||
int ev_eloop_register_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
|
||||
void *data)
|
||||
void *data, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
bool os = flags & EV_ONESHOT;
|
||||
|
||||
if (!eloop)
|
||||
if (!eloop || (flags & ~EV_IDLE_ALL))
|
||||
return -EINVAL;
|
||||
|
||||
ret = shl_hook_add_cast(eloop->idlers, cb, data, false);
|
||||
if ((flags & EV_SINGLE))
|
||||
ret = shl_hook_add_single_cast(eloop->idlers, cb, data, os);
|
||||
else
|
||||
ret = shl_hook_add_cast(eloop->idlers, cb, data, os);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -2330,6 +2336,7 @@ int ev_eloop_register_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
|
||||
* @eloop: event loop
|
||||
* @cb: user-supplied callback
|
||||
* @data: user-supplied data
|
||||
* @flags: flags
|
||||
*
|
||||
* This removes an idle-source. The arguments must be the same as for the
|
||||
* ev_eloop_register_idle_cb() call. If two identical callbacks are registered,
|
||||
@ -2337,12 +2344,15 @@ int ev_eloop_register_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
|
||||
* they are identical.
|
||||
*/
|
||||
void ev_eloop_unregister_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
|
||||
void *data)
|
||||
void *data, unsigned int flags)
|
||||
{
|
||||
if (!eloop)
|
||||
if (!eloop || (flags & ~EV_IDLE_ALL))
|
||||
return;
|
||||
|
||||
shl_hook_rm_cast(eloop->idlers, cb, data);
|
||||
if (flags & EV_SINGLE)
|
||||
shl_hook_rm_all_cast(eloop->idlers, cb, data);
|
||||
else
|
||||
shl_hook_rm_cast(eloop->idlers, cb, data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
11
src/eloop.h
11
src/eloop.h
@ -262,10 +262,17 @@ void ev_eloop_unregister_child_cb(struct ev_eloop *loop, ev_child_cb cb,
|
||||
|
||||
/* idle sources */
|
||||
|
||||
enum ev_idle_flags {
|
||||
EV_NORMAL = 0x00,
|
||||
EV_ONESHOT = 0x01,
|
||||
EV_SINGLE = 0x02,
|
||||
EV_IDLE_ALL = EV_ONESHOT | EV_SINGLE,
|
||||
};
|
||||
|
||||
int ev_eloop_register_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
|
||||
void *data);
|
||||
void *data, unsigned int flags);
|
||||
void ev_eloop_unregister_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
|
||||
void *data);
|
||||
void *data, unsigned int flags);
|
||||
|
||||
/* pre dispatch callbacks */
|
||||
|
||||
|
@ -45,8 +45,12 @@ typedef void (*shl_hook_cb) (void *parent, void *arg, void *data);
|
||||
|
||||
#define shl_hook_add_cast(hook, cb, data, oneshot) \
|
||||
shl_hook_add((hook), (shl_hook_cb)(cb), (data), (oneshot))
|
||||
#define shl_hook_add_single_cast(hook, cb, data, oneshot) \
|
||||
shl_hook_add_single((hook), (shl_hook_cb)(cb), (data), (oneshot))
|
||||
#define shl_hook_rm_cast(hook, cb, data) \
|
||||
shl_hook_rm((hook), (shl_hook_cb)(cb), (data))
|
||||
#define shl_hook_rm_all_cast(hook, cb, data) \
|
||||
shl_hook_rm_all((hook), (shl_hook_cb)(cb), (data))
|
||||
|
||||
struct shl_hook_entry {
|
||||
struct shl_dlist list;
|
||||
|
@ -475,7 +475,7 @@ static void intro_idle_event(struct ev_eloop *eloop, void *unused, void *data)
|
||||
int ret;
|
||||
|
||||
vfb->pending_intro = false;
|
||||
ev_eloop_unregister_idle_cb(eloop, intro_idle_event, data);
|
||||
ev_eloop_unregister_idle_cb(eloop, intro_idle_event, data, EV_NORMAL);
|
||||
|
||||
ret = display_new(&disp, &fbdev_display_ops);
|
||||
if (ret) {
|
||||
@ -514,7 +514,8 @@ static int video_init(struct uterm_video *video, const char *node)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = ev_eloop_register_idle_cb(video->eloop, intro_idle_event, video);
|
||||
ret = ev_eloop_register_idle_cb(video->eloop, intro_idle_event, video,
|
||||
EV_NORMAL);
|
||||
if (ret) {
|
||||
log_error("cannot register idle event: %d", ret);
|
||||
goto err_node;
|
||||
@ -538,7 +539,7 @@ static void video_destroy(struct uterm_video *video)
|
||||
|
||||
if (vfb->pending_intro)
|
||||
ev_eloop_unregister_idle_cb(video->eloop, intro_idle_event,
|
||||
video);
|
||||
video, EV_NORMAL);
|
||||
|
||||
free(vfb->node);
|
||||
free(vfb);
|
||||
|
@ -177,7 +177,7 @@ static void real_delayed(struct ev_eloop *eloop, void *unused, void *data)
|
||||
|
||||
log_debug("enter VT %d %p during startup", vt->real_num, vt);
|
||||
vt->real_delayed = false;
|
||||
ev_eloop_unregister_idle_cb(eloop, real_delayed, vt);
|
||||
ev_eloop_unregister_idle_cb(eloop, real_delayed, vt, EV_NORMAL);
|
||||
vt_call_activate(vt);
|
||||
}
|
||||
|
||||
@ -197,7 +197,8 @@ static void real_sig_enter(struct uterm_vt *vt, struct signalfd_siginfo *info)
|
||||
|
||||
if (vt->real_delayed) {
|
||||
vt->real_delayed = false;
|
||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, real_delayed, vt);
|
||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, real_delayed, vt,
|
||||
EV_NORMAL);
|
||||
} else if (vt->active) {
|
||||
log_warning("activating VT %d even though it's already active",
|
||||
vt->real_num);
|
||||
@ -237,7 +238,8 @@ static void real_sig_leave(struct uterm_vt *vt, struct signalfd_siginfo *info)
|
||||
|
||||
if (vt->real_delayed) {
|
||||
vt->real_delayed = false;
|
||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, real_delayed, vt);
|
||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, real_delayed, vt,
|
||||
EV_NORMAL);
|
||||
uterm_input_sleep(vt->input);
|
||||
} else if (!active) {
|
||||
log_warning("deactivating VT %d even though it's not active",
|
||||
@ -372,7 +374,7 @@ static int real_open(struct uterm_vt *vt, const char *vt_name)
|
||||
|
||||
if (vts.v_active == vt->real_num) {
|
||||
ret = ev_eloop_register_idle_cb(vt->vtm->eloop, real_delayed,
|
||||
vt);
|
||||
vt, EV_NORMAL);
|
||||
if (ret) {
|
||||
log_error("cannot register idle cb for VT switch");
|
||||
goto err_kbdmode;
|
||||
@ -417,7 +419,8 @@ static void real_close(struct uterm_vt *vt)
|
||||
|
||||
if (vt->real_delayed) {
|
||||
vt->real_delayed = false;
|
||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, real_delayed, vt);
|
||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, real_delayed, vt,
|
||||
EV_NORMAL);
|
||||
uterm_input_sleep(vt->input);
|
||||
} else if (vt->active) {
|
||||
uterm_input_sleep(vt->input);
|
||||
|
@ -1423,7 +1423,8 @@ static void do_frame(struct wlt_window *wnd)
|
||||
bool force;
|
||||
|
||||
wnd->idle_pending = false;
|
||||
ev_eloop_unregister_idle_cb(wnd->disp->eloop, idle_frame, wnd);
|
||||
ev_eloop_unregister_idle_cb(wnd->disp->eloop, idle_frame, wnd,
|
||||
EV_NORMAL);
|
||||
|
||||
if (wnd->need_resize) {
|
||||
force = wnd->need_redraw;
|
||||
@ -1501,7 +1502,8 @@ static void schedule_frame(struct wlt_window *wnd)
|
||||
if (wnd->need_frame || wnd->idle_pending)
|
||||
return;
|
||||
|
||||
ret = ev_eloop_register_idle_cb(wnd->disp->eloop, idle_frame, wnd);
|
||||
ret = ev_eloop_register_idle_cb(wnd->disp->eloop, idle_frame, wnd,
|
||||
EV_NORMAL);
|
||||
if (ret)
|
||||
log_error("cannot schedule idle callback: %d", ret);
|
||||
else
|
||||
@ -1537,7 +1539,7 @@ static void close_window(struct ev_eloop *eloop, void *unused, void *data)
|
||||
{
|
||||
struct wlt_window *wnd = data;
|
||||
|
||||
ev_eloop_unregister_idle_cb(eloop, close_window, wnd);
|
||||
ev_eloop_unregister_idle_cb(eloop, close_window, wnd, EV_NORMAL);
|
||||
wnd->close_pending = false;
|
||||
|
||||
if (wnd->close_cb)
|
||||
@ -1631,9 +1633,10 @@ void wlt_window_unref(struct wlt_window *wnd)
|
||||
|
||||
if (wnd->close_pending)
|
||||
ev_eloop_unregister_idle_cb(wnd->disp->eloop, close_window,
|
||||
wnd);
|
||||
wnd, EV_NORMAL);
|
||||
if (wnd->idle_pending)
|
||||
ev_eloop_unregister_idle_cb(wnd->disp->eloop, idle_frame, wnd);
|
||||
ev_eloop_unregister_idle_cb(wnd->disp->eloop, idle_frame, wnd,
|
||||
EV_NORMAL);
|
||||
shl_dlist_unlink(&wnd->list);
|
||||
if (wnd->w_frame)
|
||||
wl_callback_destroy(wnd->w_frame);
|
||||
@ -1790,7 +1793,8 @@ void wlt_window_close(struct wlt_window *wnd)
|
||||
return;
|
||||
|
||||
wnd->close_pending = true;
|
||||
ev_eloop_register_idle_cb(wnd->disp->eloop, close_window, wnd);
|
||||
ev_eloop_register_idle_cb(wnd->disp->eloop, close_window, wnd,
|
||||
EV_NORMAL);
|
||||
}
|
||||
|
||||
void wlt_window_toggle_maximize(struct wlt_window *wnd)
|
||||
|
Loading…
x
Reference in New Issue
Block a user