mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-12-26 19:39:48 +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));
|
||||
goto error;
|
||||
}
|
||||
logprint(TRACE, "dbus: connected");
|
||||
logprint(DEBUG, "dbus: connected");
|
||||
|
||||
struct wl_display *wl_display = wl_display_connect(NULL);
|
||||
if (!wl_display) {
|
||||
logprint(ERROR, "wayland: failed to connect to display");
|
||||
goto error;
|
||||
}
|
||||
logprint(TRACE, "wlroots: wl_display connected");
|
||||
logprint(DEBUG, "wlroots: wl_display connected");
|
||||
|
||||
pw_init(NULL, 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");
|
||||
goto error;
|
||||
}
|
||||
logprint(TRACE, "pipewire: pw_loop created");
|
||||
logprint(DEBUG, "pipewire: pw_loop created");
|
||||
|
||||
struct xdpw_state state = {
|
||||
.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) {
|
||||
logprint(TRACE, "dbus: destroying session");
|
||||
logprint(DEBUG, "dbus: destroying session %p", sess);
|
||||
if (!sess) {
|
||||
return;
|
||||
}
|
||||
|
@ -65,7 +65,8 @@ void xdpw_session_destroy(struct xdpw_session *sess) {
|
|||
if (cast) {
|
||||
assert(cast->refcount > 0);
|
||||
--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) {
|
||||
cast->quit = true;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ void xdpw_pwr_stream_init(struct xdpw_screencast_instance *cast) {
|
|||
/* make an event to signal frame ready */
|
||||
cast->event =
|
||||
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,
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
logprint(TRACE, "pipewire: destroying stream");
|
||||
logprint(DEBUG, "pipewire: destroying stream");
|
||||
pw_stream_flush(cast->stream, false);
|
||||
pw_stream_disconnect(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) {
|
||||
assert(cast->refcount == 0);
|
||||
logprint(TRACE, "xdpw: destroying cast instance");
|
||||
assert(cast->refcount == 0); // Fails assert if called by screencast_finish
|
||||
logprint(DEBUG, "xdpw: destroying cast instance");
|
||||
wl_list_remove(&cast->link);
|
||||
xdpw_pwr_stream_destroy(cast);
|
||||
free(cast);
|
||||
|
@ -71,9 +71,17 @@ int setup_outputs(struct xdpw_screencast_context *ctx, struct xdpw_session *sess
|
|||
cast->with_cursor ? "with" : "without");
|
||||
|
||||
if (cast->target_output->id == out->id && cast->with_cursor == with_cursor) {
|
||||
sess->screencast_instance = cast;
|
||||
++cast->refcount;
|
||||
logprint(INFO, "xdpw: screencast instance %p has %d references", cast, cast->refcount);
|
||||
if (cast->refcount == 0) {
|
||||
logprint(DEBUG,
|
||||
"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;
|
||||
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +304,7 @@ static int method_screencast_select_sources(sd_bus_message *msg, void *data,
|
|||
error:
|
||||
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +374,7 @@ static int method_screencast_start(sd_bus_message *msg, void *data,
|
|||
struct xdpw_session *sess, *tmp_s;
|
||||
wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -453,6 +461,7 @@ int xdpw_screencast_init(struct xdpw_state *state, const char *output_name, cons
|
|||
screencast_vtable, state);
|
||||
|
||||
end:
|
||||
// TODO: clean up pipewire
|
||||
xdpw_wlr_screencopy_finish(&state->screencast);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast) {
|
|||
logprint(TRACE, "wlroots: frame destroyed");
|
||||
|
||||
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);
|
||||
return ;
|
||||
}
|
||||
|
@ -342,14 +345,14 @@ int xdpw_wlr_screencopy_init(struct xdpw_state *state) {
|
|||
wl_display_dispatch(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);
|
||||
|
||||
wl_display_dispatch(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
|
||||
if (!ctx->shm) {
|
||||
|
|
Loading…
Reference in a new issue