chiark / gitweb /
disobedience/choose-search.c: Fix segfault when search terms change.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 9 Jan 2016 01:37:36 +0000 (01:37 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 9 Jan 2016 01:37:36 +0000 (01:37 +0000)
The observed problem:  Sometimes, when typing search terms into the box,
DisObedience crashes.  This seems to happen more often when the server
is slow to respond.

Here's what's going on.  Suppose that a search finds some results.  Then
`choose_make_visible' tries to expand the tree to display them.  If some
of the results aren't populated in the tree yet, then
`choose_make_one_visible' arranges to fetch the necessary information
from the server and informs its caller, `choose_make_visible', that
it'll have to try again later.  When this happens, `choose_make_visible'
hooks itself onto the `choose-more-tracks' event and waits for the
information to arrive.

Suppose that, while this is happening, the user edits the search terms;
a new search starts, but this one returns no results.  Then
`choose_search_completed' zaps the `choose_search_results' vector and
returns.

Now the metadata from the old search arrives from the server;
`choose_make_visible' is called back.  There are now no search results,
so it thinks its work is done and tries to scroll the list widget so
that the first result is visible -- but the result vector has been
clobbered.  Result: misery.

To fix this, cancel the `choose-more-tracks' event handler when a new
search finishes.  Now we can't get into this situation any more.

disobedience/choose-search.c

index 60df2ec..83d3f74 100644 (file)
@@ -289,6 +289,11 @@ static void choose_search_completed(void attribute((unused)) *v,
    * left over from the old search. */
   choose_auto_collapse();
   choose_search_hash = hash_new(1);
+  /* If we were still setting up the chooser to show previous search results
+   * then turn that off now.  We'll turn it back on again if necessary. */
+  event_cancel(choose_inserted_handle);
+  choose_inserted_handle = 0;
+  /* Start showing the results of our search. */
   if(nvec) {
     for(int n = 0; n < nvec; ++n)
       hash_add(choose_search_hash, vec[n], "", HASH_INSERT);