After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 737769 - fs: Keep TrackerCrawler alive across async calls
fs: Keep TrackerCrawler alive across async calls
Status: RESOLVED FIXED
Product: tracker
Classification: Core
Component: Miners
1.0.x
Other All
: Normal normal
: ---
Assigned To: tracker-general
Depends on:
Blocks:
 
 
Reported: 2014-10-02 08:48 UTC by Debarshi Ray
Modified: 2014-10-14 13:47 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
libtracker-miner: Keep the crawler alive across async calls (1.62 KB, patch)
2014-10-02 08:49 UTC, Debarshi Ray
committed Details | Review

Description Debarshi Ray 2014-10-02 08:48:15 UTC
Another 1.0/0.16 issue that I spotted while looking at bug 737768 See the patch.
Comment 1 Debarshi Ray 2014-10-02 08:49:10 UTC
Created attachment 287565 [details] [review]
libtracker-miner: Keep the crawler alive across async calls
Comment 2 Martyn Russell 2014-10-03 10:40:56 UTC
Comment on attachment 287565 [details] [review]
libtracker-miner: Keep the crawler alive across async calls

Looks right to me and what we should have been doing from the beginning.

Thanks Debarshi ;)
Comment 3 Debarshi Ray 2014-10-05 09:46:14 UTC
Comment on attachment 287565 [details] [review]
libtracker-miner: Keep the crawler alive across async calls

Pushed to tracker-1.0 and tracker-0.16. I will check the newer branches now.
Comment 4 Debarshi Ray 2014-10-14 13:17:12 UTC
I don't think this is relevant to master or tracker-1.2. The code has changed a bit, and this bug is not present there.

For the record, the relevant bits read like this now:

static void
data_provider_end_cb (GObject      *object,
                      GAsyncResult *result,
                      gpointer      user_data)
{
        DataProviderData *dpd;
        GError *error = NULL;
        gboolean cancelled;

        dpd = user_data;

        cancelled = g_cancellable_is_cancelled (dpd->cancellable);

        tracker_data_provider_end_finish (TRACKER_DATA_PROVIDER (object), result, &error);

        if (error) {
                if (!cancelled) {
                        GFile *parent;
                        gchar *uri;

                        parent = dpd->dir_info->node->data;
                        uri = g_file_get_uri (parent);

                        g_warning ("Could not end data provider for container / directory '%s', %s",
                                   uri, error ? error->message : "no error given");

                        g_free (uri);
                }

                g_clear_error (&error);
        }

        data_provider_data_free (dpd);
}

static void
data_provider_end (TrackerCrawler    *crawler,
                   DirectoryRootInfo *info)
{
        DataProviderData *dpd;

        g_return_if_fail (info != NULL);

        if (info->dpd == NULL) {
                /* Nothing to do */
                return;
        }

        /* We detach the DataProviderData from the DirectoryRootInfo                                                  
         * here so it's not freed early. We can't use                                                                 
         * DirectoryRootInfo as user data for the async function below                                                
         * because it's freed before that callback will be called.                                                    
         */
        dpd = info->dpd;
        info->dpd = NULL;

        if (dpd->enumerator) {
                /* Reset cancellation, we need to perform this even                                                   
                 * if we were cancelled previously.                                                                   
                 */
                g_cancellable_reset (dpd->cancellable);

                tracker_data_provider_end_async (crawler->priv->data_provider,
                                                 dpd->enumerator,
                                                 G_PRIORITY_LOW,
                                                 dpd->cancellable,
                                                 data_provider_end_cb,
                                                 dpd);
        } else {
                data_provider_data_free (dpd);
        }
}

The TrackerCrawler object is held with a reference inside the DataProviderData structure, and since that is kept alive across the tracker_data_provider_end_async call, we should not have a problem.
Comment 5 Martyn Russell 2014-10-14 13:47:38 UTC
Great, thanks for clarifying Debarshi! :)