#include <sys/timerfd.h>
#include <sys/wait.h>
+#include "sd-id128.h"
#include "macro.h"
#include "prioq.h"
#include "hashmap.h"
#include "util.h"
#include "time-util.h"
-#include "sd-id128.h"
+#include "missing.h"
#include "sd-event.h"
bool quit_requested:1;
bool need_process_child:1;
+
+ pid_t tid;
+ sd_event **default_event_ptr;
};
static int pending_prioq_compare(const void *a, const void *b) {
static void event_free(sd_event *e) {
assert(e);
+ if (e->default_event_ptr)
+ *(e->default_event_ptr) = NULL;
+
if (e->epoll_fd >= 0)
close_nointr_nofail(e->epoll_fd);
free(e);
}
-int sd_event_new(sd_event** ret) {
+_public_ int sd_event_new(sd_event** ret) {
sd_event *e;
int r;
return r;
}
-sd_event* sd_event_ref(sd_event *e) {
+_public_ sd_event* sd_event_ref(sd_event *e) {
assert_return(e, NULL);
assert(e->n_ref >= 1);
return e;
}
-sd_event* sd_event_unref(sd_event *e) {
+_public_ sd_event* sd_event_unref(sd_event *e) {
assert_return(e, NULL);
assert(e->n_ref >= 1);
return s;
}
-int sd_event_add_io(
+_public_ int sd_event_add_io(
sd_event *e,
int fd,
uint32_t events,
return r;
}
-int sd_event_add_monotonic(sd_event *e, uint64_t usec, uint64_t accuracy, sd_time_handler_t callback, void *userdata, sd_event_source **ret) {
+_public_ int sd_event_add_monotonic(sd_event *e,
+ uint64_t usec,
+ uint64_t accuracy,
+ sd_time_handler_t callback,
+ void *userdata,
+ sd_event_source **ret) {
+
return event_add_time_internal(e, SOURCE_MONOTONIC, &e->monotonic_fd, CLOCK_MONOTONIC, &e->monotonic_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret);
}
-int sd_event_add_realtime(sd_event *e, uint64_t usec, uint64_t accuracy, sd_time_handler_t callback, void *userdata, sd_event_source **ret) {
+_public_ int sd_event_add_realtime(sd_event *e,
+ uint64_t usec,
+ uint64_t accuracy,
+ sd_time_handler_t callback,
+ void *userdata,
+ sd_event_source **ret) {
+
return event_add_time_internal(e, SOURCE_REALTIME, &e->realtime_fd, CLOCK_REALTIME, &e->realtime_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret);
}
return 0;
}
-int sd_event_add_signal(
+_public_ int sd_event_add_signal(
sd_event *e,
int sig,
sd_signal_handler_t callback,
return 0;
}
-int sd_event_add_child(
+_public_ int sd_event_add_child(
sd_event *e,
pid_t pid,
int options,
return 0;
}
-int sd_event_add_defer(
+_public_ int sd_event_add_defer(
sd_event *e,
sd_defer_handler_t callback,
void *userdata,
return 0;
}
-int sd_event_add_quit(
+_public_ int sd_event_add_quit(
sd_event *e,
sd_quit_handler_t callback,
void *userdata,
return 0;
}
-sd_event_source* sd_event_source_ref(sd_event_source *s) {
+_public_ sd_event_source* sd_event_source_ref(sd_event_source *s) {
assert_return(s, NULL);
assert(s->n_ref >= 1);
return s;
}
-sd_event_source* sd_event_source_unref(sd_event_source *s) {
+_public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
assert_return(s, NULL);
assert(s->n_ref >= 1);
return NULL;
}
-sd_event *sd_event_get(sd_event_source *s) {
+_public_ sd_event *sd_event_get(sd_event_source *s) {
assert_return(s, NULL);
return s->event;
}
-int sd_event_source_get_pending(sd_event_source *s) {
+_public_ int sd_event_source_get_pending(sd_event_source *s) {
assert_return(s, -EINVAL);
assert_return(s->type != SOURCE_QUIT, -EDOM);
assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
return s->pending;
}
-int sd_event_source_get_io_fd(sd_event_source *s) {
+_public_ int sd_event_source_get_io_fd(sd_event_source *s) {
assert_return(s, -EINVAL);
assert_return(s->type == SOURCE_IO, -EDOM);
assert_return(!event_pid_changed(s->event), -ECHILD);
return s->io.fd;
}
-int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
+_public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
assert_return(s, -EINVAL);
assert_return(events, -EINVAL);
assert_return(s->type == SOURCE_IO, -EDOM);
return 0;
}
-int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
+_public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
int r;
assert_return(s, -EINVAL);
return 0;
}
-int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
+_public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
assert_return(s, -EINVAL);
assert_return(revents, -EINVAL);
assert_return(s->type == SOURCE_IO, -EDOM);
return 0;
}
-int sd_event_source_get_signal(sd_event_source *s) {
+_public_ int sd_event_source_get_signal(sd_event_source *s) {
assert_return(s, -EINVAL);
assert_return(s->type == SOURCE_SIGNAL, -EDOM);
assert_return(!event_pid_changed(s->event), -ECHILD);
return s->signal.sig;
}
-int sd_event_source_get_priority(sd_event_source *s, int *priority) {
+_public_ int sd_event_source_get_priority(sd_event_source *s, int *priority) {
assert_return(s, -EINVAL);
assert_return(!event_pid_changed(s->event), -ECHILD);
return s->priority;
}
-int sd_event_source_set_priority(sd_event_source *s, int priority) {
+_public_ int sd_event_source_set_priority(sd_event_source *s, int priority) {
assert_return(s, -EINVAL);
assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(s->event), -ECHILD);
return 0;
}
-int sd_event_source_get_enabled(sd_event_source *s, int *m) {
+_public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
assert_return(s, -EINVAL);
assert_return(m, -EINVAL);
assert_return(!event_pid_changed(s->event), -ECHILD);
return 0;
}
-int sd_event_source_set_enabled(sd_event_source *s, int m) {
+_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
int r;
assert_return(s, -EINVAL);
return 0;
}
-int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
+_public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
assert_return(s, -EINVAL);
assert_return(usec, -EINVAL);
assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
return 0;
}
-int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
+_public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
assert_return(s, -EINVAL);
assert_return(usec != (uint64_t) -1, -EINVAL);
assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
return 0;
}
-int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
+_public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
assert_return(s, -EINVAL);
assert_return(usec, -EINVAL);
assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
return 0;
}
-int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
+_public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
assert_return(s, -EINVAL);
assert_return(usec != (uint64_t) -1, -EINVAL);
assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
return 0;
}
-int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
+_public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
assert_return(s, -EINVAL);
assert_return(pid, -EINVAL);
assert_return(s->type == SOURCE_CHILD, -EDOM);
return 0;
}
-int sd_event_source_set_prepare(sd_event_source *s, sd_prepare_handler_t callback) {
+_public_ int sd_event_source_set_prepare(sd_event_source *s, sd_prepare_handler_t callback) {
int r;
assert_return(s, -EINVAL);
return 0;
}
-void* sd_event_source_get_userdata(sd_event_source *s) {
+_public_ void* sd_event_source_get_userdata(sd_event_source *s) {
assert_return(s, NULL);
return s->userdata;
return r;
}
+ sd_event_source_ref(s);
+
switch (s->type) {
case SOURCE_IO:
break;
}
+ sd_event_source_unref(s);
+
return r;
}
return p;
}
-int sd_event_run(sd_event *e, uint64_t timeout) {
+_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
struct epoll_event ev_queue[EPOLL_QUEUE_MAX];
sd_event_source *p;
int r, i, m;
return r;
}
-int sd_event_loop(sd_event *e) {
+_public_ int sd_event_loop(sd_event *e) {
int r;
assert_return(e, -EINVAL);
return r;
}
-int sd_event_get_state(sd_event *e) {
+_public_ int sd_event_get_state(sd_event *e) {
assert_return(e, -EINVAL);
assert_return(!event_pid_changed(e), -ECHILD);
return e->state;
}
-int sd_event_get_quit(sd_event *e) {
+_public_ int sd_event_get_quit(sd_event *e) {
assert_return(e, -EINVAL);
assert_return(!event_pid_changed(e), -ECHILD);
return e->quit_requested;
}
-int sd_event_request_quit(sd_event *e) {
+_public_ int sd_event_request_quit(sd_event *e) {
assert_return(e, -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
return 0;
}
-int sd_event_get_now_realtime(sd_event *e, uint64_t *usec) {
+_public_ int sd_event_get_now_realtime(sd_event *e, uint64_t *usec) {
assert_return(e, -EINVAL);
assert_return(usec, -EINVAL);
assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA);
return 0;
}
-int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) {
+_public_ int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) {
assert_return(e, -EINVAL);
assert_return(usec, -EINVAL);
assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA);
*usec = e->timestamp.monotonic;
return 0;
}
+
+_public_ int sd_event_default(sd_event **ret) {
+
+ static __thread sd_event *default_event = NULL;
+ sd_event *e;
+ int r;
+
+ if (!ret)
+ return !!default_event;
+
+ if (default_event) {
+ *ret = sd_event_ref(default_event);
+ return 0;
+ }
+
+ r = sd_event_new(&e);
+ if (r < 0)
+ return r;
+
+ e->default_event_ptr = &default_event;
+ e->tid = gettid();
+ default_event = e;
+
+ *ret = e;
+ return 1;
+}
+
+_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
+ assert_return(e, -EINVAL);
+ assert_return(tid, -EINVAL);
+ assert_return(!event_pid_changed(e), -ECHILD);
+
+ if (e->tid != 0) {
+ *tid = e->tid;
+ return 0;
+ }
+
+ return -ENXIO;
+}