srd: add support for SIGROKDECODE_PATH environment variable The optional SIGROKDECODE_DIR environment variable accepts a single directory specification. The SIGROKDECODE_PATH variable accepts a list of directories to search protocol decoders. The list separator is platform dependent (colon or semicolon). Empty items are explicitly ignored. Both variables get evaluated. Behaviour remains backwards compatible, just gets extended for improved usability.
srd: add TODO comment on the SIGROKDECODE_DIR env var's motivation A comment in the srd.c implementation suggests that the environment variable SIGROKDECODE_DIR would serve debugging purposes and would override other incarnations of available decoders. I disagree with either of these interpretations. Add a TODO comment, the phrase may need an update or rework.
Fix memory leak in print_searchpaths() ==175453== 522 bytes in 8 blocks are definitely lost in loss record 2,923 of 3,201 ==175453== at 0x4C2EBAB: malloc (vg_replace_malloc.c:299) ==175453== by 0x59E9BB5: PyObject_Malloc (in /usr/lib64/libpython3.6m.so.1.0) ==175453== by 0x5A35A76: PyBytes_FromStringAndSize (in /usr/lib64/libpython3.6m.so.1.0) ==175453== by 0x4E3FA6E: print_searchpaths (srd.c:173) ==175453== by 0x4E3FA6E: srd_init (srd.c:287) ==175453== by 0x4034BE: test_session_reset_nodata (session.c:238) ==175453== by 0x53E51D5: srunner_run_tagged (in /usr/lib64/libcheck.so.0.0.0) ==175453== by 0x401237: main (main.c:51)
Fix bad memory accesses during srd_exit() When the decoder and session unload functions are called they remove themselves from the list. The code walking the list must be careful to avoid accessing the next pointer which might now be invalid. The g_slist_foreach() takes care of this. Reports from Valgrind before fix: ==175436== Invalid read of size 8 -- ==175436== Address 0xe3f2598 is 8 bytes inside a block of size 16 free'd ==175436== at 0x4C2FDAC: free (vg_replace_malloc.c:530) ==175436== by 0x563C541: g_free (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x5654783: g_slice_free1 (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x56552A2: g_slist_remove (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x4E3FEFF: srd_session_destroy (session.c:343) ==175436== by 0x4E3F5C7: srd_exit (srd.c:311) ==175436== by 0x40336F: test_inst_new (inst.c:40) ==175436== by 0x53E51D5: srunner_run_tagged (in /usr/lib64/libcheck.so.0.0.0) ==175436== by 0x401237: main (main.c:51) ==175436== Block was alloc'd at ==175436== at 0x4C2EBAB: malloc (vg_replace_malloc.c:299) ==175436== by 0x563C435: g_malloc (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x5654056: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x5655797: g_slist_append (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x4E3FC75: srd_session_new (session.c:71) ==175436== by 0x403345: test_inst_new (inst.c:37) ==175436== by 0x53E51D5: srunner_run_tagged (in /usr/lib64/libcheck.so.0.0.0) ==175436== by 0x401237: main (main.c:51)
srd.c: Fix a compiler warning with gcc 8. srd.c: In function ‘srd_searchpaths_get’: srd.c:399:40: warning: cast between incompatible function types from ‘gchar * (*)(const gchar *)’ {aka ‘char * (*)(const char *)’} to ‘void * (*)(const void *, void *)’ [-Wcast-function-type] return g_slist_copy_deep(searchpaths, (GCopyFunc)g_strdup, NULL); ^ Upstream glib issue / documentation change: https://gitlab.gnome.org/GNOME/glib/issues/1492 https://gitlab.gnome.org/pwithnall/glib/commit/e81f4c2acea5ada6ae989426e462613f7c612cac
srd_exit(): Fix a -Wcast-function-type compiler warning. srd.c: In function ‘srd_exit’: srd.c:310:28: warning: cast between incompatible function types from ‘int (*)(struct srd_session *)’ to ‘void (*)(void *, void *)’ [-Wcast-function-type] g_slist_foreach(sessions, (GFunc)srd_session_destroy, NULL); ^
Acquire/release the Python GIL where needed to avoid threading issues. With these additions, frontends can now call libsigrokdecode API functions from different threads without running into threading issues. The backend releases the GIL when it is performing tasks that might take a while and it doesn't need to run Python/C API calls during that time. This allows frontends to run multiple PD stacks (in multiple frontend threads) "at the same time" in a time-sharing, "interlocked" manner. Whenever one of the decoders is inside e.g. self.wait() it releases the GIL and thus allows other decoders to do some work in the mean time. The user-visible effect is that for use-cases such as running 3 different decoder stacks at the same time for an acquisition, the user will not have to wait for PD 1 to finish decoding, then wait for PD 2 to finish decoding, and only *then* being able to see annotations from PD 3. Instead, all three PDs will decode some chunks of data from time to time, thus the user is able to inspect annotations from all 3 PDs while the acquisition and decoding is still going on.