From kde-devel Sun Apr 18 20:58:40 2010 From: dantti85-dev () yahoo ! com ! br Date: Sun, 18 Apr 2010 20:58:40 +0000 To: kde-devel Subject: Help needed in print-manager using QThread Message-Id: <828265.9645.qm () web114209 ! mail ! gq1 ! yahoo ! com> X-MARC-Message: https://marc.info/?l=kde-devel&m=127162439330378 Hi all, As I posted into my blog I was working on a replacement to the python versions of printer-applet and kcm-printer using C++. The results you can see in in trunk/playground/base/print-manager/ r1112709. I'll enumerate the benefits here to avoid discussions: - it handles cups authentication correctly - it uses 13mb less of memory to just look for print jobs - the kcm module can show a different icon for the different kinds of printers and in the future I plan to read Mac icons to be able to show the manufacturer icon is available. - to the users I showed they found the UI easier Before I explain the problem I'm having I'll explain the dir structure: - print-manager-kcm, manages printers - print-queue, show the print queue - printd, a kded module that shows a systray icon whenever it founds a job - libqcups, it's a lib shared lib between only print-queue and print-manager-kcm, it is like a Qt binding of the cups api making it easier to extend and use, it manages the authentication and such.. The issue: all these parts are basically finished (need some polising still but already works), so now that I know cups api well enough and things works I decided to add the "add printer" UI, and I realized that the call would block the UI for 30 seconds, currently if you put a wrong password it also blocks till the password dialog is shown again (just like when you do su). Print-manager definitely needs threads, but it's library uses too many global variables which make it impossible to create a thread to every request, actually it is possible but as it creates a thread for each new thread you would need to type you password EVERY time you needed a privileged action (and no PolicyKit is not an option). What I did, created a singleton, which creates a thread that has a local event loop. this even loop allow us to send the request which give us a queue for free (so no problem with the global cups variables as long all cups requests are done in this thread - which is easy to do). Now to don't block the UI it invokes the thread method and start an event loop to be able to wait till his request was processed, the request receives the QEventLoop pointer to call loop->exit() when it finishes. If the thread needs to authenticate it calls the main thread with QueuedBlockConnection which makes the other call not be processed an thus not changing the infamous globals vars. This is beautiful if it really worked :P Thiago already helped me a lot, but now I'm with a complicated problem which I can't solve and is a bit hard to help without testing... How to test: $ kcmshell4 kcm_printer_manager this KCM has a timer which in 1 second updates the UI with new info, now everything in broken in the latest revision 1116183 so please only test what I'm saying otherwise you might not see the problem. only the getDest function and setShared goes to the cups thread function, so if we call them not at the same time there is no problem (ie disable timer). but if the timer is enable there are 3 things that can happen: - it works (yes sometimes it works) - it does not works and after you put you password the dialog quits but it never returns from exec() - it does not return from getDests nor setShared nor show the password dialog the worst case :P where these things are called: print-manager-kcm/PrinterModel.cpp # 64 dests = QCups::getDests(-1, requestAttr); libqcups/QCups.cpp # 174 QList QCups::getDests(int mask, const QStringList &requestedAttr) print-manager-kcm/PrintKCM.cpp # 71 m_updateT->start(); // QTimer that updates the model print-manager-kcm/PrinterDescription.cpp # 71 setIsShared(QCups::Dest::setShared(m_destName, m_isClass, sharedCB->isChecked())); libqcups/QCups.cpp # 331 bool QCups::Dest::setShared(const QString &destName, bool isClass, bool shared) the setShared will endup calling through the thread libqcups/QCups.cpp # 251 void NCups::showPasswordDlg(const QString &username, bool showErrorMessage) All the functions in QCups.cpp are declared in CupsActions.h I really really would like to have this included in KDE 4.5 but as the 26 day is getting near this is a bloker, that's why I really need help with skilled ppl that have experience with threads an gui... Thanks,________________________________ Daniel Nicoletti - KDE Developer http://dantti.wordpress.com When a wicked man dies, his hope perishes; all he expected from his power comes to nothing. Prov. 11:7 >> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<