diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 046457b..d053127 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -146,7 +146,7 @@ bool ctl_sink_is_closed(struct ctl_sink *s); #define wfd_session_has_id(s) (0 < wfd_session_get_id(s)) #define wfd_is_out_session(s) (WFD_SESSION_DIR_OUT == wfd_session_get_dir(s)) #define wfd_is_in_session(s) (WFD_SESSION_DIR_IN == wfd_session_get_dir(s)) -#define _wfd_session_free_ _shl_cleanup_(wfd_session_freep) +#define _wfd_session_free_ _shl_cleanup_(wfd_session_free_p) struct wfd_sink; struct wfd_session; @@ -181,7 +181,7 @@ void wfd_session_end(struct wfd_session *s); void wfd_session_free(struct wfd_session *s); uint64_t wfd_session_get_id(struct wfd_session *s); struct wfd_sink * wfd_out_session_get_sink(struct wfd_session *s); -void wfd_session_freep(struct wfd_session **s); +void wfd_session_free_p(struct wfd_session **s); uint64_t * wfd_session_to_htable(struct wfd_session *s); struct wfd_session * wfd_session_from_htable(uint64_t *e); diff --git a/src/ctl/wfd-dbus.c b/src/ctl/wfd-dbus.c index 25975f2..cfab4f0 100644 --- a/src/ctl/wfd-dbus.c +++ b/src/ctl/wfd-dbus.c @@ -473,7 +473,7 @@ static int wfd_dbus_session_get_sink(sd_bus *bus, sd_bus_error *ret_error) { struct wfd_session *s = userdata; - _shl_free_ char *sink_path; + _shl_free_ char *sink_path = NULL; int r; if(wfd_session_get_id(s) != WFD_SESSION_DIR_OUT) { diff --git a/src/ctl/wfd-session.c b/src/ctl/wfd-session.c index 065bec1..1af053d 100644 --- a/src/ctl/wfd-session.c +++ b/src/ctl/wfd-session.c @@ -119,7 +119,7 @@ void wfd_session_end(struct wfd_session *s) log_info("session %lu ended", s->id); - wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN); + wfd_session_set_state(s, WFD_SESSION_STATE_NULL); (*session_vtables[s->dir].end)(s); @@ -128,6 +128,17 @@ void wfd_session_end(struct wfd_session *s) s->rtsp = NULL; } + if(wfd_is_out_session(s)) { + wfd_fn_out_session_ended(s); + } +} + +void wfd_session_free(struct wfd_session *s) +{ + if(!s) { + return; + } + if(s->vformats) { wfd_video_formats_free(s->vformats); s->vformats = NULL; @@ -147,19 +158,6 @@ void wfd_session_end(struct wfd_session *s) s->rtp_ports[1] = 0; s->last_request = RTSP_M_UNKNOWN; - if(wfd_is_out_session(s)) { - wfd_fn_out_session_ended(s); - } -} - -void wfd_session_free(struct wfd_session *s) -{ - if(wfd_session_is_destructed(s)) { - return; - } - - s->destructed = true; - wfd_session_end(s); if(session_vtables[s->dir].distruct) { @@ -559,7 +557,7 @@ int wfd_session_start(struct wfd_session *s, uint64_t id) return 0; } -void wfd_session_freep(struct wfd_session **s) +void wfd_session_free_p(struct wfd_session **s) { wfd_session_free(*s); } diff --git a/src/ctl/wfd-session.h b/src/ctl/wfd-session.h index acd4f5a..c3e6ed4 100644 --- a/src/ctl/wfd-session.h +++ b/src/ctl/wfd-session.h @@ -109,8 +109,6 @@ struct wfd_session uint16_t rtp_port; pid_t gst; } stream; - - bool destructed: 1; }; int wfd_session_init(struct wfd_session *s); diff --git a/src/ctl/wfd-sink.c b/src/ctl/wfd-sink.c index cd1ccdf..088ebb9 100644 --- a/src/ctl/wfd-sink.c +++ b/src/ctl/wfd-sink.c @@ -19,6 +19,8 @@ #define LOG_SUBSYSTEM "wfd-session" #include +#include +#include #include "ctl.h" #include "wfd-dbus.h" @@ -119,21 +121,43 @@ int wfd_sink_start_session(struct wfd_sink *sink, struct wfd_session **out) return 0; } +static int wfd_sink_defered_session_cleanup(sd_event_source *source, + uint64_t used, + void *userdata) +{ + struct wfd_session *s = userdata; + + sd_event_source_set_enabled(source, false); + + ctl_wfd_remove_session_by_id(ctl_wfd_get(), + wfd_session_get_id(s), + NULL); + wfd_session_free(s); + + return 0; +} + int wfd_fn_out_session_ended(struct wfd_session *s) { struct wfd_sink *sink; + uint64_t now = 0; assert(wfd_is_out_session(s)); sink = wfd_out_session_get_sink(s); - wfd_fn_sink_properties_changed(sink, "Session"); - ctl_wfd_remove_session_by_id(ctl_wfd_get(), - wfd_session_get_id(s), - NULL); sink->session = NULL; - wfd_session_free(s); - return 0; + wfd_fn_sink_properties_changed(sink, "Session"); + + sd_event_now(ctl_wfd_get_loop(), CLOCK_MONOTONIC, &now); + + return sd_event_add_time(ctl_wfd_get_loop(), + NULL, + CLOCK_MONOTONIC, + 200 * 1000 + now, + 0, + wfd_sink_defered_session_cleanup, + s); } bool wfd_sink_is_session_started(struct wfd_sink *sink)