mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-25 15:35:58 +01:00
Check cast instance refcount before attaching
This commit is contained in:
parent
55f873dac4
commit
f6d14d9206
5 changed files with 31 additions and 18 deletions
|
@ -78,14 +78,14 @@ int main(int argc, char *argv[]) {
|
||||||
logprint(ERROR, "dbus: failed to connect to user bus: %s", strerror(-ret));
|
logprint(ERROR, "dbus: failed to connect to user bus: %s", strerror(-ret));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
logprint(TRACE, "dbus: connected");
|
logprint(DEBUG, "dbus: connected");
|
||||||
|
|
||||||
struct wl_display *wl_display = wl_display_connect(NULL);
|
struct wl_display *wl_display = wl_display_connect(NULL);
|
||||||
if (!wl_display) {
|
if (!wl_display) {
|
||||||
logprint(ERROR, "wayland: failed to connect to display");
|
logprint(ERROR, "wayland: failed to connect to display");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
logprint(TRACE, "wlroots: wl_display connected");
|
logprint(DEBUG, "wlroots: wl_display connected");
|
||||||
|
|
||||||
pw_init(NULL, NULL);
|
pw_init(NULL, NULL);
|
||||||
struct pw_loop *pw_loop = pw_loop_new(NULL);
|
struct pw_loop *pw_loop = pw_loop_new(NULL);
|
||||||
|
@ -93,7 +93,7 @@ int main(int argc, char *argv[]) {
|
||||||
logprint(ERROR, "pipewire: failed to create loop");
|
logprint(ERROR, "pipewire: failed to create loop");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
logprint(TRACE, "pipewire: pw_loop created");
|
logprint(DEBUG, "pipewire: pw_loop created");
|
||||||
|
|
||||||
struct xdpw_state state = {
|
struct xdpw_state state = {
|
||||||
.bus = bus,
|
.bus = bus,
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct xdpw_session *xdpw_session_create(struct xdpw_state *state, sd_bus *bus,
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdpw_session_destroy(struct xdpw_session *sess) {
|
void xdpw_session_destroy(struct xdpw_session *sess) {
|
||||||
logprint(TRACE, "dbus: destroying session");
|
logprint(DEBUG, "dbus: destroying session %p", sess);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,8 @@ void xdpw_session_destroy(struct xdpw_session *sess) {
|
||||||
if (cast) {
|
if (cast) {
|
||||||
assert(cast->refcount > 0);
|
assert(cast->refcount > 0);
|
||||||
--cast->refcount;
|
--cast->refcount;
|
||||||
logprint(INFO, "xdpw: screencast instance %p has %d references", cast, cast->refcount);
|
logprint(DEBUG, "xdpw: screencast instance %p now has %d references",
|
||||||
|
cast, cast->refcount);
|
||||||
if (cast->refcount < 1) {
|
if (cast->refcount < 1) {
|
||||||
cast->quit = true;
|
cast->quit = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ void xdpw_pwr_stream_init(struct xdpw_screencast_instance *cast) {
|
||||||
/* make an event to signal frame ready */
|
/* make an event to signal frame ready */
|
||||||
cast->event =
|
cast->event =
|
||||||
pw_loop_add_event(state->pw_loop, pwr_on_event, cast);
|
pw_loop_add_event(state->pw_loop, pwr_on_event, cast);
|
||||||
logprint(TRACE, "pipewire: registered event %p", cast->event);
|
logprint(DEBUG, "pipewire: registered event %p", cast->event);
|
||||||
|
|
||||||
params[0] = spa_pod_builder_add_object(&b,
|
params[0] = spa_pod_builder_add_object(&b,
|
||||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||||
|
@ -194,7 +194,7 @@ void xdpw_pwr_stream_init(struct xdpw_screencast_instance *cast) {
|
||||||
int xdpw_pwr_core_connect(struct xdpw_state *state) {
|
int xdpw_pwr_core_connect(struct xdpw_state *state) {
|
||||||
struct xdpw_screencast_context *ctx = &state->screencast;
|
struct xdpw_screencast_context *ctx = &state->screencast;
|
||||||
|
|
||||||
logprint(TRACE, "pipewire: establishing connection to core");
|
logprint(DEBUG, "pipewire: establishing connection to core");
|
||||||
|
|
||||||
if (!ctx->pwr_context) {
|
if (!ctx->pwr_context) {
|
||||||
ctx->pwr_context = pw_context_new(state->pw_loop, NULL, 0);
|
ctx->pwr_context = pw_context_new(state->pw_loop, NULL, 0);
|
||||||
|
@ -215,7 +215,7 @@ int xdpw_pwr_core_connect(struct xdpw_state *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdpw_pwr_stream_destroy(struct xdpw_screencast_instance *cast) {
|
void xdpw_pwr_stream_destroy(struct xdpw_screencast_instance *cast) {
|
||||||
logprint(TRACE, "pipewire: destroying stream");
|
logprint(DEBUG, "pipewire: destroying stream");
|
||||||
pw_stream_flush(cast->stream, false);
|
pw_stream_flush(cast->stream, false);
|
||||||
pw_stream_disconnect(cast->stream);
|
pw_stream_disconnect(cast->stream);
|
||||||
pw_stream_destroy(cast->stream);
|
pw_stream_destroy(cast->stream);
|
||||||
|
|
|
@ -34,8 +34,8 @@ void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdpw_screencast_instance_destroy(struct xdpw_screencast_instance *cast) {
|
void xdpw_screencast_instance_destroy(struct xdpw_screencast_instance *cast) {
|
||||||
assert(cast->refcount == 0);
|
assert(cast->refcount == 0); // Fails assert if called by screencast_finish
|
||||||
logprint(TRACE, "xdpw: destroying cast instance");
|
logprint(DEBUG, "xdpw: destroying cast instance");
|
||||||
wl_list_remove(&cast->link);
|
wl_list_remove(&cast->link);
|
||||||
xdpw_pwr_stream_destroy(cast);
|
xdpw_pwr_stream_destroy(cast);
|
||||||
free(cast);
|
free(cast);
|
||||||
|
@ -71,9 +71,17 @@ int setup_outputs(struct xdpw_screencast_context *ctx, struct xdpw_session *sess
|
||||||
cast->with_cursor ? "with" : "without");
|
cast->with_cursor ? "with" : "without");
|
||||||
|
|
||||||
if (cast->target_output->id == out->id && cast->with_cursor == with_cursor) {
|
if (cast->target_output->id == out->id && cast->with_cursor == with_cursor) {
|
||||||
sess->screencast_instance = cast;
|
if (cast->refcount == 0) {
|
||||||
++cast->refcount;
|
logprint(DEBUG,
|
||||||
logprint(INFO, "xdpw: screencast instance %p has %d references", cast, cast->refcount);
|
"xdpw: matching cast instance found, "
|
||||||
|
"but is already scheduled for destruction, skipping");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sess->screencast_instance = cast;
|
||||||
|
++cast->refcount;
|
||||||
|
}
|
||||||
|
logprint(INFO, "xdpw: screencast instance %p now has %d references",
|
||||||
|
cast, cast->refcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +278,7 @@ static int method_screencast_select_sources(sd_bus_message *msg, void *data,
|
||||||
ret = -1;
|
ret = -1;
|
||||||
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
||||||
if (strcmp(sess->session_handle, session_handle) == 0) {
|
if (strcmp(sess->session_handle, session_handle) == 0) {
|
||||||
logprint(TRACE, "dbus: select sources: found matching session %s", sess->session_handle);
|
logprint(DEBUG, "dbus: select sources: found matching session %s", sess->session_handle);
|
||||||
ret = setup_outputs(ctx, sess, cursor_embedded);
|
ret = setup_outputs(ctx, sess, cursor_embedded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +304,7 @@ static int method_screencast_select_sources(sd_bus_message *msg, void *data,
|
||||||
error:
|
error:
|
||||||
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
||||||
if (strcmp(sess->session_handle, session_handle) == 0) {
|
if (strcmp(sess->session_handle, session_handle) == 0) {
|
||||||
logprint(TRACE, "dbus: select sources error: destroying matching session %s", sess->session_handle);
|
logprint(DEBUG, "dbus: select sources error: destroying matching session %s", sess->session_handle);
|
||||||
xdpw_session_destroy(sess);
|
xdpw_session_destroy(sess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,7 +374,7 @@ static int method_screencast_start(sd_bus_message *msg, void *data,
|
||||||
struct xdpw_session *sess, *tmp_s;
|
struct xdpw_session *sess, *tmp_s;
|
||||||
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
||||||
if (strcmp(sess->session_handle, session_handle) == 0) {
|
if (strcmp(sess->session_handle, session_handle) == 0) {
|
||||||
logprint(TRACE, "dbus: start: found matching session %s", sess->session_handle);
|
logprint(DEBUG, "dbus: start: found matching session %s", sess->session_handle);
|
||||||
cast = sess->screencast_instance;
|
cast = sess->screencast_instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,6 +461,7 @@ int xdpw_screencast_init(struct xdpw_state *state, const char *output_name, cons
|
||||||
screencast_vtable, state);
|
screencast_vtable, state);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
// TODO: clean up pipewire
|
||||||
xdpw_wlr_screencopy_finish(&state->screencast);
|
xdpw_wlr_screencopy_finish(&state->screencast);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast) {
|
||||||
logprint(TRACE, "wlroots: frame destroyed");
|
logprint(TRACE, "wlroots: frame destroyed");
|
||||||
|
|
||||||
if (cast->quit || cast->err) {
|
if (cast->quit || cast->err) {
|
||||||
|
// TODO: revisit the exit condition (remove quit?)
|
||||||
|
// and clean up sessions that still exist if err
|
||||||
|
// is the cause of the instance_destroy call
|
||||||
xdpw_screencast_instance_destroy(cast);
|
xdpw_screencast_instance_destroy(cast);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
@ -342,14 +345,14 @@ int xdpw_wlr_screencopy_init(struct xdpw_state *state) {
|
||||||
wl_display_dispatch(state->wl_display);
|
wl_display_dispatch(state->wl_display);
|
||||||
wl_display_roundtrip(state->wl_display);
|
wl_display_roundtrip(state->wl_display);
|
||||||
|
|
||||||
logprint(TRACE, "wayland: registry listeners run");
|
logprint(DEBUG, "wayland: registry listeners run");
|
||||||
|
|
||||||
wlr_init_xdg_outputs(ctx);
|
wlr_init_xdg_outputs(ctx);
|
||||||
|
|
||||||
wl_display_dispatch(state->wl_display);
|
wl_display_dispatch(state->wl_display);
|
||||||
wl_display_roundtrip(state->wl_display);
|
wl_display_roundtrip(state->wl_display);
|
||||||
|
|
||||||
logprint(TRACE, "wayland: xdg output listeners run");
|
logprint(DEBUG, "wayland: xdg output listeners run");
|
||||||
|
|
||||||
// make sure our wlroots supports shm protocol
|
// make sure our wlroots supports shm protocol
|
||||||
if (!ctx->shm) {
|
if (!ctx->shm) {
|
||||||
|
|
Loading…
Reference in a new issue