[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-hardware-devel
Subject:    Re: [Kde-hardware-devel] multithreading restrictions?
From:       Marcel Wiesweg <marcel.wiesweg () gmx ! de>
Date:       2008-02-11 18:37:35
Message-ID: 200802111937.36417.marcel.wiesweg () gmx ! de
[Download RAW message or body]

> Le Sunday 18 November 2007, Marcel Wiesweg a écrit :
> > I have a bit more for you:
> > For testing, I have added this call to the UI thread, before the worker
> > thread starts.
> >
> > >From the worker thread, when the call is executed again, I then get
> > > about 8 of
> >
> > these error messages:
> >
> > QObject: Cannot create children for a parent that is in a different
> > thread. (Parent is Solid::Backends::Hal::HalDevice(0x83f4f88), parent's
> > thread is QThread(0x82e33f8), current thread is
> > Digikam::ScanController(0x83ddbc0)
>
> Once again, would you mind making a test case for this?

The attached test case is an attempt to isolate the Solid code that was 
causing the problem. The part is copied from digikam source without change. 
With this case, I can reproduce the "Cannot create children for a parent that 
is in a different thread" problem; this is caused when the call is executed 
in two threads at the same time. If you exchange the two lines t.start() and 
t.solid(), then it does not occur.

I have not been able to reproduce the original few-seconds-lockup problem with 
this testcase though. I don't know what is needed to trigger this.
In the meantime, I have worked around the problem by moving the actual Solid 
call to the main thread with a blocking queued signal in digikam, so it's not 
causing trouble at the moment.

>
> I can't seem to reproduce your issues.
>
> Now just curious, why do you use a thread in the first place? If that's
> only for a call to Device::list* that looks like overkill.

It's a worker thread that initializes the database and scans the collection. 
To find out which parts of the collection are available, it needs to know the 
hardware situation. The UI thread is displaying progress info in the time.

Marcel

>
> Regards.



["testsolid.cpp" (text/x-c++src)]

#include <QThread>
#include <QDebug>
#include <QApplication>
#include <QList>

#include "kapplication.h"

#include <solid/device.h>
#include <solid/deviceinterface.h>
#include <solid/deviceinterface.h>
#include <solid/devicenotifier.h>
#include <solid/storageaccess.h>
#include <solid/storagedrive.h>
#include <solid/storagevolume.h>
#include <solid/opticaldisc.h>
#include <solid/predicate.h>


class SolidVolumeInfo
{
public:
    QString path; // mount path of volume, with trailing slash
    QString uuid; // UUID as from Solid
    QString label; // volume label (think of CDs)
    bool isRemovable; // may be removed
    bool isOpticalDisc;

    bool isNull() const { return path.isNull(); }
};

class Thread : public QThread
{
public:

    Thread()
    {
    }

    void run()
    {
        solid();
    }

    void solid()
    {
        QList<SolidVolumeInfo> volumes;
        qDebug() << "Starting list operation";
        QList<Solid::Device> devices = \
Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);  qDebug() << "got \
listFromType" << endl;

        foreach(Solid::Device accessDevice, devices)
        {
            // check for StorageAccess
            if (!accessDevice.is<Solid::StorageAccess>())
                continue;

            Solid::StorageAccess *access = accessDevice.as<Solid::StorageAccess>();

            if (!access->isAccessible())
                continue;

            // check for StorageDrive
            Solid::Device driveDevice;
            for (Solid::Device currentDevice = accessDevice; currentDevice.isValid(); \
currentDevice = currentDevice.parent())  {
                if (currentDevice.is<Solid::StorageDrive>())
                {
                    driveDevice = currentDevice;
                    break;
                }
            }
            if (!driveDevice.isValid())
                continue;

            Solid::StorageDrive *drive = driveDevice.as<Solid::StorageDrive>();

            // check for StorageVolume
            Solid::Device volumeDevice;
            for (Solid::Device currentDevice = accessDevice; currentDevice.isValid(); \
currentDevice = currentDevice.parent())  {
                if (currentDevice.is<Solid::StorageVolume>())
                {
                    volumeDevice = currentDevice;
                    break;
                }
            }
            if (!volumeDevice.isValid())
                continue;

            Solid::StorageVolume *volume = volumeDevice.as<Solid::StorageVolume>();

            SolidVolumeInfo info;
            info.path = access->filePath();
            if (!info.path.endsWith("/"))
                info.path += "/";
            info.uuid = volume->uuid();
            info.label = volume->label();
            info.isRemovable = drive->isRemovable();
            info.isOpticalDisc = volumeDevice.is<Solid::OpticalDisc>();

            volumes << info;
        }
    }
};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    Thread t;

    t.start();
    t.solid();

    QEventLoop l;
    l.exec();
}


["CMakeLists.txt" (text/plain)]

PROJECT(testsolid)
FIND_PACKAGE(KDE4 REQUIRED)
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} )

SET(KDE4ProjectSources testsolid.cpp )

KDE4_ADD_EXECUTABLE(testsolid ${KDE4ProjectSources} )

TARGET_LINK_LIBRARIES(testsolid ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS} )

_______________________________________________
Kde-hardware-devel mailing list
Kde-hardware-devel@kde.org
https://mail.kde.org/mailman/listinfo/kde-hardware-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic