Bug 369203

Summary: CollectionFetchJob::exec() hangs forever
Product: [Frameworks and Libraries] Akonadi Reporter: Patrick Ohly <patrick.ohly>
Component: libakonadiAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED INTENTIONAL    
Severity: normal CC: dvratil, pino, tcl-kde
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Debian testing   
OS: Linux   
URL: https://bugs.freedesktop.org/show_bug.cgi?id=97609
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Patrick Ohly 2016-09-22 18:12:44 UTC
SyncEvolution uses the blocking API to execute jobs. That used to work fine with older Akonadi, but on Debian Stretch (= 4.14.10-5) it just hangs. Below is a stand-alone test program demonstrating the problem.

On Debian Jessie, the output is:
$ ./akonadi-lsDatabase "akonadi" opened using driver "QMYSQL" 
akonadi_ical_resource_0


On Debian Stretch:
$ ./akonadi-ls
^C
Shutting down "0x277afc0" ...

Here it got aborted after two hours.

Akonadi seems okay on Debian Stretch:
$ akonadictl status
Akonadi Control: running
Akonadi Server: running
akonadiprivate_log: search paths:  ("lib/x86_64-linux-gnu", "lib/x86_64-linux-gnu/qt5/plugins/", "lib/x86_64-linux-gnu/kf5/", "lib/x86_64-linux-gnu/kf5/plugins/", "/usr/lib/qt5/plugins/", "/usr/lib/x86_64-linux-gnu/qt5/plugins", "/usr/bin")
Akonadi Server Search Support: available (Remote Search)
Available Agent Types: akonadi_akonotes_resource, akonadi_birthdays_resource, akonadi_contacts_resource, akonadi_davgroupware_resource, akonadi_googlecalendar_resource, akonadi_googlecontacts_resource, akonadi_ical_resource, akonadi_icaldir_resource, akonadi_imap_resource, akonadi_invitations_agent, akonadi_kalarm_dir_resource, akonadi_kalarm_resource, akonadi_knut_resource, akonadi_kolab_resource, akonadi_maildir_resource, akonadi_maildispatcher_agent, akonadi_mbox_resource, akonadi_migration_agent, akonadi_mixedmaildir_resource, akonadi_newmailnotifier_agent, akonadi_notes_resource, akonadi_openxchange_resource, akonadi_pop3_resource, akonadi_vcard_resource, akonadi_vcarddir_resource

akonadiconsole shows that there are collections.

Reproducible: Always

Steps to Reproduce:
1. cat >akonadi-ls.cpp <<EOF
#include <iostream>
#include <memory>

#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>

#include <Akonadi/CollectionFetchJob>
#include <Akonadi/CollectionFetchScope>
#include <QStringList>

using namespace Akonadi;

/**
 * We take over ownership of jobs by storing them in smart pointers
 * (RAII).  This is how SyncEvolution does things and more predictable
 * than assuming that a future exec() call will auto-delete them as
 * part of its event processing.
 *
 * To avoid double frees, we need to disable auto-deletion.
 * This method does that. Use like this:
 * std::auto_ptr<CollectionStatisticsJob> statisticsJob(DisableAutoDelete(new CollectionStatisticsJob(m_collection)));
 */
template<class J> J *DisableAutoDelete(J *job) { job->setAutoDelete(false); return job; }

int main(int argc, char **argv)
{
    KAboutData aboutData(// The program name used internally.
                         "syncevolution",
                         // The message catalog name
                         // If null, program name is used instead.
                         0,
                         // A displayable program name string.
                         ki18n("SyncEvolution"),
                         // The program version string.
                         "1.0",
                         // Short description of what the app does.
                         ki18n("Lets Akonadi synchronize with a SyncML Peer"),
                         // The license this code is released under
                         KAboutData::License_GPL,
                         // Copyright Statement
                         ki18n("(c) 2010-12"),
                         // Optional text shown in the About box.
                         // Can contain any information desired.
                         ki18n(""),
                         // The program homepage string.
                         "http://www.syncevolution.org/",
                         // The bug report email address
                         "syncevolution@syncevolution.org");

    KCmdLineArgs::init(argc, argv, &aboutData);
    KApplication app(false);

    //  std::unique_ptr<CollectionFetchJob> fetchJob(DisableAutoDelete(new CollectionFetchJob(Collection::root(),
    // CollectionFetchJob::Recursive)));
    CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive);

    fetchJob->fetchScope().setContentMimeTypes(QString("text/calendar").split(","));
    if (!fetchJob->exec()) {
        std::cerr << "Cannot fetch collections." << std::endl;
        return 1;
    }

    Collection::List collections = fetchJob->collections();
    foreach (const Collection &collection, collections) {
        std::cout << collection.name().toUtf8().constData() << std::endl;
    }
    return 0;
}
EOF
2. g++ -I/usr/include/KDE -I/usr/include/qt4 -I/usr/include/qt4/QtCore -g akonadi-ls.cpp -o akonadi-ls -lakonadi-kde -lkdecore -lkdeui -lQtCore 
3. ./akonadi-ls


Actual Results:  
It hangs. gdb stacktrace:

(gdb) where
#0  0x00007ffff5cf6080 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007ffff1487896 in g_main_context_iterate (priority=<optimized out>, n_fds=3, fds=0x6c8990, timeout=<optimized out>, context=0x64b370) at ././glib/gmain.c:4226
#2  0x00007ffff1487896 in g_main_context_iterate (context=context@entry=0x64b370, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ././glib/gmain.c:3922
#3  0x00007ffff14879ac in g_main_context_iteration (context=0x64b370, may_block=1) at ././glib/gmain.c:3988
#4  0x00007ffff6a10894 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
    at /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#5  0x00007ffff69de82f in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
    at /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#6  0x00007ffff69deb95 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
    at /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#7  0x00007ffff7527cb3 in KJob::exec() () at /usr/lib/libkdecore.so.5
#8  0x0000000000401823 in main(int, char**) (argc=1, argv=0x7fffffffdec8) at akonadi-ls.cpp:59

According to strace, nothing happens anymore at that point.

Expected Results:  
exec() should return.

The environment is the nightly SyncEvolution test setup with manually started D-Bus daemon and X11 provided by VNC, but users have reported this problem also in "normal" desktop environments (http://www.mail-archive.com/syncevolution@syncevolution.org/msg05012.html, Ubuntu 15.10 Wily at that time).
Comment 1 Pino Toscano 2018-01-04 23:47:01 UTC
(In reply to Patrick Ohly from comment #0)
> SyncEvolution uses the blocking API to execute jobs. That used to work fine
> with older Akonadi, but on Debian Stretch (= 4.14.10-5) it just hangs.

Debian packager here: note that the "akonadi" bits provided in Stretch, that use Qt4/kdelibs 4.x, are just the client libraries without the actual server; this was done to allow to keep in Debian kdepimlibs, and few applications using it.
The server you are running is the Qt5/Frameworks 5.x version of Akonadi (see e.g. the "search paths" lines in the akonadictl output).  Hence, I would not be surprised that stuff using akonadi 4.x would not work at all.

As unfortunate as it sounds, the solution I see in this case is to port the Akonadi integration in SyncEvolution to Akonadi 5.x (Qt5/Frameworks 5.x):
- the KDE project stopped releasing sources part of Applications releases that use kdelibs 4.x with Application 17.08.x (there are none since Applications 17.12.x)
- distributions are looking into reducing more and more anything based on Qt4/kdelibs 4.x (see for example https://bugs.debian.org/875215)

With my Debian hat: SyncEvolution is one of the very few sources in Debian testing (the future stable Buster) that uses akonadi 4.x/kdepimlibs 4.x, and for which I see no porting to Frameworks (or other solutions) in sight.  I am not sure whether we want/can carry them on in Buster, so consider this as a not-so-subtle hint to port SyncEvolution :-)
Comment 2 Daniel Vrátil 2018-08-27 21:45:57 UTC
Sorry, the KDE4/Qt4 version of PIM is no longer supported.