Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pipewire: Destroy registry object with remote #1319

Merged
merged 1 commit into from
Apr 1, 2024

Conversation

rmader
Copy link
Contributor

@rmader rmader commented Mar 31, 2024

This practically reintroduces commit fbe2653 which got reverted in ff8a8de, which I only discovered after coming up with this solution on its own. The only difference is that
discover_node_factory_sync() gets removed as it doesn't really make much sense to keep around.

The commit message of fbe2653 (by msizanoen1
[email protected])>

Currently, the PipeWire registry object is destroyed when
discover_node_factory_sync finishes its functionality. This causes
registry events to not be delivered to the global_removed_cb and
global_added_cb callbacks after discover_node_factory_sync, breaking
the functionality of the
org.freedesktop.portal.Camera.IsCameraPresent property in case of
camera device hot(un)plug.

This changes the discover_node_factory_sync function to store the
registry in the PipeWireRemote structure and destroy it in
pipewire_remote_destroy.

This holds true to this day and causes issues for the camera portal. Whatever crashes it caused at some point I can't reproduce - and Gnome-Shell, which has a very similar implementation for its camera monitor doesn't seem to suffer from crashes as well.

P.S.: the originally described issue:

breaking the functionality of the org.freedesktop.portal.Camera.IsCameraPresent property in case of camera device hot(un)plug.

does not describe the main problem that many people are facing: if Pipewire initializes cameras a little too late, the portal won't see them.


cc: @GeorgesStavracas, @msizanoen1

src/pipewire.c Outdated
@@ -245,7 +219,10 @@ pipewire_remote_destroy (PipeWireRemote *remote)
pw_loop_destroy_source (loop, g_steal_pointer (&remote->roundtrip_timeout));
}

spa_hook_remove (&remote->registry_listener);
Copy link
Contributor Author

@rmader rmader Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually possible that the crashes in fbe2653 were caused by not adding this.

Copy link
Member

@GeorgesStavracas GeorgesStavracas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. @wtay do you have thoughts on this?

@wtay
Copy link
Contributor

wtay commented Apr 1, 2024

LGTM. @wtay do you have thoughts on this?

It looks good to me.

@GeorgesStavracas GeorgesStavracas added this to the 1.20 milestone Apr 1, 2024
@GeorgesStavracas GeorgesStavracas added bug pipewire Issues and feature requests related to PipeWire usage in xdg-desktop-portal labels Apr 1, 2024
@rmader rmader force-pushed the fix-camera-portal-weirdness branch from ed48897 to 5177150 Compare April 1, 2024 22:17
@rmader
Copy link
Contributor Author

rmader commented Apr 1, 2024

Minor changes to silence compiler complaints, hopefully making the CI happy. Also some small wording changes in the commit message.

@GeorgesStavracas
Copy link
Member

This is showing up in CI:

==5383==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x563f7137e7cc bp 0x7ffc9daa0410 sp 0x7ffc9daa03c0 T0)
==5383==The signal is caused by a WRITE memory access.
==5383==Hint: address points to the zero page.
    #0 0x563f7137e7cc in spa_list_remove /usr/include/spa-0.2/spa/utils/list.h:76:19
    #1 0x563f7137d574 in spa_hook_remove /usr/include/spa-0.2/spa/utils/hook.h:376:2
    #2 0x563f7137d1db in pipewire_remote_destroy /src/builddir/../src/pipewire.c:222:3
    #3 0x563f7137dcd3 in pipewire_remote_new_sync /src/builddir/../src/pipewire.c:299:7
    #4 0x563f713393d1 in create_pipewire_remote /src/builddir/../src/camera.c:347:29
    #5 0x563f71338c9c in init_camera_tracker /src/builddir/../src/camera.c:409:8
    #6 0x563f71338558 in camera_init /src/builddir/../src/camera.c:434:8
    #7 0x7f35e1124fb9 in g_type_create_instance (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x3dfb9) (BuildId: 7c47809b4e688382aab4127a2e07496450c5e6b0)
    #8 0x7f35e110c0ec  (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x250ec) (BuildId: 7c47809b4e688382aab4127a2e07496450c5e6b0)
    #9 0x7f35e110d34c in g_object_new_with_properties (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x2634c) (BuildId: 7c47809b4e688382aab4127a2e07496450c5e6b0)
    #10 0x7f35e110de50 in g_object_new (/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x26e50) (BuildId: 7c47809b4e688382aab4127a2e07496450c5e6b0)
    #11 0x563f713383bd in camera_create /src/builddir/../src/camera.c:452:12
    #12 0x563f713b1401 in on_bus_acquired /src/builddir/../src/xdg-desktop-portal.c:277:37
    #13 0x7f35e125b385  (/lib/x86_64-linux-gnu/libgio-2.0.so.0+0x114385) (BuildId: 07bd46a1bb58e321e6aabc67135d054e6b78069d)
    #14 0x7f35e11f8e38  (/lib/x86_64-linux-gnu/libgio-2.0.so.0+0xb1e38) (BuildId: 07bd46a1bb58e321e6aabc67135d054e6b78069d)
    #15 0x7f35e11f905a  (/lib/x86_64-linux-gnu/libgio-2.0.so.0+0xb205a) (BuildId: 07bd46a1bb58e321e6aabc67135d054e6b78069d)
    #16 0x7f35e12570f1  (/lib/x86_64-linux-gnu/libgio-2.0.so.0+0x1100f1) (BuildId: 07bd46a1bb58e321e6aabc67135d054e6b78069d)
    #17 0x7f35e11f8e38  (/lib/x86_64-linux-gnu/libgio-2.0.so.0+0xb1e38) (BuildId: 07bd46a1bb58e321e6aabc67135d054e6b78069d)
    #18 0x7f35e11f8e7c  (/lib/x86_64-linux-gnu/libgio-2.0.so.0+0xb1e7c) (BuildId: 07bd46a1bb58e321e6aabc67135d054e6b78069d)
    #19 0x7f35e1375c43 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55c43) (BuildId: c74e800dfd5f72649d673b44292f4a817e45150b)
    #20 0x7f35e13cb257  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xab257) (BuildId: c74e800dfd5f72649d673b44292f4a817e45150b)
    #21 0x7f35e13752b2 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x552b2) (BuildId: c74e800dfd5f72649d673b44292f4a817e45150b)
    #22 0x563f713b0953 in main /src/builddir/../src/xdg-desktop-portal.c:442:3
    #23 0x7f35e0c12d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: c289da5071a3399de893d2af81d6a30c62646e1e)
    #24 0x7f35e0c12e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: c289da5071a3399de893d2af81d6a30c62646e1e)
    #25 0x563f711242a4 in _start (/src/builddir/src/xdg-desktop-portal+0xf02a4) (BuildId: 6658a4b46c407663f4e6c883d35fd38e1507d8a9)

@GeorgesStavracas
Copy link
Member

I think you can only call spa_hook_remove (&remote->registry_listener); if remote->registry exists

@rmader
Copy link
Contributor Author

rmader commented Apr 1, 2024

This is showing up in CI:

Oh wild. Maybe an issue with older Pipewire? Tests are passing fine locally:

meson test
ninja: Entering directory `/home/robert/git/xdg-desktop-portal/build'
ninja: no work to do.
 1/24 xdg-desktop-portal / testdb                                    OK              0.01s   3 subtests passed
 2/24 xdg-desktop-portal / test-doc-portal                           OK              0.13s   5 subtests passed
 3/24 xdg-desktop-portal:portals / test-portals-background           OK              1.18s   5 subtests passed
 4/24 xdg-desktop-portal:portals / test-portals-color                OK              1.69s   5 subtests passed
 5/24 xdg-desktop-portal:portals / test-portals-camera               OK              1.73s   9 subtests passed
 6/24 xdg-desktop-portal:portals / test-portals-account              OK              1.91s   7 subtests passed
 7/24 xdg-desktop-portal:portals / test-portals-location             OK              1.15s   3 subtests passed
 8/24 xdg-desktop-portal:portals / test-portals-email                OK              1.96s   9 subtests passed
 9/24 xdg-desktop-portal:portals / test-portals-notification         OK              1.57s   6 subtests passed
10/24 xdg-desktop-portal:portals / test-portals-openuri              OK              1.74s   9 subtests passed
11/24 xdg-desktop-portal:portals / test-portals-prepareprint         OK              1.88s   7 subtests passed
12/24 xdg-desktop-portal:portals / test-portals-inhibit              OK              3.78s   8 subtests passed
13/24 xdg-desktop-portal:portals / test-portals-openfile             OK              2.67s   15 subtests passed
14/24 xdg-desktop-portal:portals / test-portals-print                OK              1.68s   7 subtests passed
15/24 xdg-desktop-portal:portals / test-portals-settings             OK              1.12s   1 subtests passed
16/24 xdg-desktop-portal:portals / test-portals-screenshot           OK              1.69s   6 subtests passed
17/24 xdg-desktop-portal:portals / test-portals-savefile             OK              1.87s   7 subtests passed
18/24 xdg-desktop-portal:portals / test-portals-trash                OK              1.18s   2 subtests passed
19/24 xdg-desktop-portal:portals / test-portals-wallpaper            OK              1.98s   6 subtests passed
20/24 xdg-desktop-portal:portals / limited-portals-savefile          OK              1.84s   7 subtests passed
21/24 xdg-desktop-portal:portals / limited-portals-openfile          OK              2.71s   15 subtests passed
22/24 xdg-desktop-portal / test-permission-store                     OK              0.05s   14 subtests passed
23/24 xdg-desktop-portal / test-xdp-utils                            OK              0.01s   6 subtests passed
24/24 xdg-desktop-portal / test-xdp-method-info                      OK              0.00s   2 subtests passed

Ok:                 24  
Expected Fail:      0   
Fail:               0   
Unexpected Pass:    0   
Skipped:            0   
Timeout:            0   

Full log written to /home/robert/git/xdg-desktop-portal/build/meson-logs/testlog.txt

@GeorgesStavracas
Copy link
Member

I think that's because CI doesn't have a running PipeWire server, so the code fails to create a PipeWire context and bails out early. I bet (hope) you have a working PipeWire setup on your computer 🙂

@rmader
Copy link
Contributor Author

rmader commented Apr 1, 2024

I think that's because CI doesn't have a running PipeWire server, so the code fails to create a PipeWire context and bails out early. I bet (hope) you have a working PipeWire setup on your computer 🙂

I tested that, too! And it seems to work fine on newer versions, but let me try.

@rmader rmader force-pushed the fix-camera-portal-weirdness branch from 5177150 to 6441dc9 Compare April 1, 2024 22:40
This practically reintroduces commit fbe2653 which got reverted
in ff8a8de, which I only discovered after coming up with this
solution on its own. The main difference is that
`discover_node_factory_sync()` gets removed as it doesn't really
make much sense to keep around, as well small clean up improvements.

The commit message of fbe2653 (by msizanoen1
<[email protected]>)>
```
Currently, the PipeWire registry object is destroyed when
discover_node_factory_sync finishes its functionality. This causes
registry events to not be delivered to the global_removed_cb and
global_added_cb callbacks after discover_node_factory_sync, breaking
the functionality of the
org.freedesktop.portal.Camera.IsCameraPresent property in case of
camera device hot(un)plug.

This changes the discover_node_factory_sync function to store the
registry in the PipeWireRemote structure and destroy it in
pipewire_remote_destroy.
```

This holds true to this day and causes issues for the camera portal,
most importantly causing a race condition where cameras that were not
yet available during initialization would never get recognized.

Whatever crashes it caused at some point I can't reproduce - and
Gnome-Shell, which has a very similar implementation for its camera
monitor doesn't seem to suffer from crashes as well.
@rmader rmader force-pushed the fix-camera-portal-weirdness branch from 6441dc9 to e3b5b7b Compare April 1, 2024 22:45
@GeorgesStavracas GeorgesStavracas added this pull request to the merge queue Apr 1, 2024
Merged via the queue into flatpak:main with commit 24d29bf Apr 1, 2024
4 checks passed
@GeorgesStavracas
Copy link
Member

Looks like our investigation was correct 🙂

Merged

@rmader
Copy link
Contributor Author

rmader commented Apr 1, 2024

Looks like our investigation was correct 🙂

Yours ;)

Thanks!

@rmader
Copy link
Contributor Author

rmader commented Apr 2, 2024

@GeorgesStavracas: given that this is a bug fix, what do you think about a 1.18 backport / 1.18.3 release?

@ebassi
Copy link
Collaborator

ebassi commented Apr 2, 2024

From Matrix:

Georges Stavracas (feaneron): might be worth backporting

Since 1.20 is not on the near horizon, a backport would probably be best.

@Sodivad
Copy link
Contributor

Sodivad commented Jun 11, 2024

This seems to have re-introduced the crash for me that caused the original revert in ff8a8de

#0  0x00007e3328cfcc15 in  () at /usr/lib/x86_64-linux-gnu/pipewire-0.3/libpipewire-module-protocol-native.so
#1  0x00007e3328d0392b in  () at /usr/lib/x86_64-linux-gnu/pipewire-0.3/libpipewire-module-protocol-native.so
#2  0x00007e332ca35d42 in pw_proxy_destroy () at /lib/x86_64-linux-gnu/libpipewire-0.3.so.0
#3  0x0000590cb425f10a in pipewire_remote_destroy (remote=0x7e331400f440) at ../src/pipewire.c:225
#4  0x0000590cb426c9fe in handle_open_pipewire_remote
    (object=0x590cb53a58f0, invocation=0x7e331c018480, in_fd_list=0x0, arg_session_handle=0x7e3314009740 "/org/freedesktop/portal/desktop/session/1_120/obs5", arg_options=0x7e331c015940) at ../src/screen-cast.c:1005
#5  0x00007e332c4cfe2e in  () at /lib/x86_64-linux-gnu/libffi.so.8
#6  0x00007e332c4cc493 in  () at /lib/x86_64-linux-gnu/libffi.so.8
#7  0x00007e332cae216d in g_cclosure_marshal_generic () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#8  0x00007e332cadbd2f in g_closure_invoke () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9  0x00007e332caf7624 in  () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x0000590cb41ddb26 in _xdp_dbus_screen_cast_skeleton_handle_method_call
    (connection=0x590cb52db030, sender=0x7e331c019c30 ":1.120", object_path=0x7e331c015390 "/org/freedesktop/portal/desktop", interface_name=0x590cb539dab0 "org.freedesktop.portal.ScreenCast", method_name=0x7e331c018130 "OpenPipeWireRemote", parameters=0x590cb53afc80, invocation=0x7e331c018480, user_data=0x590cb53a58f0) at src/xdp-dbus.c:48592
#11 0x00007e332cc4c15e in  () at /lib/x86_64-linux-gnu/libgio-2.0.so.0
#12 0x00007e332cbd9194 in  () at /lib/x86_64-linux-gnu/libgio-2.0.so.0
#13 0x00007e332cd88714 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#14 0x00007e332cd85ab1 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#15 0x00007e332c694ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#16 0x00007e332c726850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

I am on 7209054

grulja added a commit to grulja/xdg-desktop-portal that referenced this pull request Aug 9, 2024
This is causing a crash with older PipeWire clients. Partly undoes flatpak#1319
which introduced this issue.

Fixes flatpak#1407
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug pipewire Issues and feature requests related to PipeWire usage in xdg-desktop-portal
Projects
No open projects
Status: Triaged
Development

Successfully merging this pull request may close these issues.

5 participants