#include "util.h"
#include "time-util.h"
#include "missing.h"
+#include "set.h"
#include "sd-event.h"
SOURCE_SIGNAL,
SOURCE_CHILD,
SOURCE_DEFER,
+ SOURCE_POST,
SOURCE_EXIT,
SOURCE_WATCHDOG
} EventSourceType;
struct {
sd_event_handler_t callback;
} defer;
+ struct {
+ sd_event_handler_t callback;
+ } post;
struct {
sd_event_handler_t callback;
unsigned prioq_index;
Hashmap *child_sources;
unsigned n_enabled_child_sources;
+ Set *post_sources;
+
Prioq *exit;
pid_t original_pid;
free(e->signal_sources);
hashmap_free(e->child_sources);
+ set_free(e->post_sources);
free(e);
}
/* nothing */
break;
+ case SOURCE_POST:
+ set_remove(s->event->post_sources, s);
+ break;
+
case SOURCE_EXIT:
prioq_remove(s->event->exit, s, &s->exit.prioq_index);
break;
return 0;
}
+_public_ int sd_event_add_post(
+ sd_event *e,
+ sd_event_source **ret,
+ sd_event_handler_t callback,
+ void *userdata) {
+
+ sd_event_source *s;
+ int r;
+
+ assert_return(e, -EINVAL);
+ assert_return(callback, -EINVAL);
+ assert_return(ret, -EINVAL);
+ assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
+ assert_return(!event_pid_changed(e), -ECHILD);
+
+ r = set_ensure_allocated(&e->post_sources, trivial_hash_func, trivial_compare_func);
+ if (r < 0)
+ return r;
+
+ s = source_new(e, SOURCE_POST);
+ if (!s)
+ return -ENOMEM;
+
+ s->post.callback = callback;
+ s->userdata = userdata;
+ s->enabled = SD_EVENT_ON;
+
+ r = set_put(e->post_sources, s);
+ if (r < 0) {
+ source_free(s);
+ return r;
+ }
+
+ *ret = s;
+ return 0;
+}
+
_public_ int sd_event_add_exit(
sd_event *e,
sd_event_source **ret,
break;
case SOURCE_DEFER:
+ case SOURCE_POST:
s->enabled = m;
break;
break;
case SOURCE_DEFER:
+ case SOURCE_POST:
s->enabled = m;
break;
return r;
}
+ if (s->type != SOURCE_POST) {
+ sd_event_source *z;
+ Iterator i;
+
+ /* If we execute a non-post source, let's mark all
+ * post sources as pending */
+
+ SET_FOREACH(z, s->event->post_sources, i) {
+ if (z->enabled == SD_EVENT_OFF)
+ continue;
+
+ r = source_set_pending(z, true);
+ if (r < 0)
+ return r;
+ }
+ }
+
if (s->enabled == SD_EVENT_ONESHOT) {
r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
if (r < 0)
r = s->defer.callback(s, s->userdata);
break;
+ case SOURCE_POST:
+ r = s->post.callback(s, s->userdata);
+ break;
+
case SOURCE_EXIT:
r = s->exit.callback(s, s->userdata);
break;
int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata);
int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata);
int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
+int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
int sd_event_run(sd_event *e, uint64_t timeout);