GNOME Bugzilla – Bug 638941
registry scan/loading race and inconsistency
Last modified: 2011-01-10 10:42:26 UTC
Created attachment 177785 [details] rm test-registry.reg && rm pipelines/gio && GST_DEBUG=2,check:5,*LOAD*:5,*REG*:5 make check -j5 > log-plugin2 2>&1 When running the unit tests in -base, the gio test sometimes fails with the following error : Running suite(s): gio 0%: Checks: 1, Failures: 1, Errors: 0 pipelines/gio.c:96:F:general:test_memory_stream:0: Assertion 'src != NULL' failed FAIL: pipelines/gio What's actually happening is that it actually attempted to load the libgstgio from /usr/lib, which was blacklisted and therefore had zero features. And obviously... it couldn't create a giostreamsrc element since that plugin doesn't have one. The local source libgstgio.so does exist, is valid, has all the features. This only happens with the subprocess scanning. This is one is tricky... so bare with me for the explanations (debug logs attached). The registry scan (to create/update test-registry.reg) does the following: * The parent process scans the various paths for potential .so * It checks if a potential .so isn't already register * If there isn't already a registered plugin with the same basename (libgstFOO.so) it sends it to the child process to be scanned * CHILD : processes the incoming .so, checks it against a potential whitelist, and eventually returns the information back to the parent process * The parent process receives plugin info from the child process and calls gst_registry_add_plugin() * If a plugin with the same basename isn't already present it adds it * If a plugin with the same basename is already present it replaces it with the new one Where the race happens: * parent scans potential .so in local source (including the local libgstgio.so) and sends it to child * CHILD : eventually sends it back (stress-word : eventually) * parent scans system-wide paths for potential .so (including libgstgio.so). => The problem is that the child might have not sent back the result from scanning the local libgstgio.so at that time. And therefore the parent process thinks libgstgio.so is a new plugin and sends it to the child process to scan * CHILD : sends back the results from scanning the local libgstgio.so * PARENT : adds it to registry * CHILD : scans system-wide libgstgio.so, but since we have a whitelist and it's not in it it is marked as blacklisted and no features are added to it and sends it back to the parent * PARENT : adds system-wide libgstgio.so to registry. There already is an existing libgstgio.so .... and it therefore replaces it by the new (system-wide, blacklisted, 0 features) libgstgio.so => FAILURE ENSUES How to solve this: in gst_registry_add_plugin, if there's already an existing same-basename plugin... check if either the new or existing plugin is blacklisted and make a *smart* choice on whether to replace the existing plugin by the new one or ignore the new one.
Actually, my proposed fix needs to be fine-tuned, because you could very well end up in the situation where a plugin (with the same exact location) was modified and isn't working anymore. So we shouldn't just check the basename, but actually the full path.
Created attachment 177822 [details] [review] registry: Don't replace valid existing plugins by blacklisted ones Only replace existing plugins by blacklisted ones if they correspond to the exact same plugin. If they're not the same, keep the existing valid one. Fixes #638941
commit 8edee55a3a2241ef4d83df6ec405bc4ba6ba42f0 Author: Edward Hervey <bilboed@bilboed.com> Date: Sat Jan 8 14:52:27 2011 +0100 registry: Don't replace valid existing plugins by blacklisted ones Only replace existing plugins by blacklisted ones if they correspond to the exact same plugin. If they're not the same, keep the existing valid one. Fixes #638941