[KimDaBa] Re: WARNING about current CVS - STABLE again

Robert L Krawitz rlk at alum.mit.edu
Thu Jan 13 08:47:43 CET 2005


   From: "Jesper K. Pedersen" <blackie at blackie.dk>
   Date: Thu, 13 Jan 2005 13:30:19 +0100
   Cc: kimdaba at klaralvdalens-datakonsult.se

   On Thursday 13 January 2005 13:25, Robert L Krawitz wrote:
   |    From: "Jesper K. Pedersen" <blackie at blackie.dk>
   |    Date: Thu, 13 Jan 2005 11:23:10 +0100
   |    Cc: Robert L Krawitz <rlk at alum.mit.edu>
   |
   |    On Wednesday 12 January 2005 23:22, Jesper K. Pedersen wrote:
   |    | I've started working on the problem with page down (and it is much
   |    | much better now), but I'm touching the multithreaded code here, so
   |    | things do crash quite often when you scroll the thumbnail view, WATCH
   |    | OUT!
   |    |
   |    | Expect this to be over in a few days.
   |
   |    Now see, this made me spent all morning on kimdaba *tsk* *tsk*
   |
   | Despite everything else you possibly could have done :-)
   |
   |    Anyway, now it works again, and even though I've been scrolling up
   |    and down in any imaginable and even some unimaginable ways, it
   |    doesn't crash for me any more.
   |
   |    So enjoy the speed up in the thumbnail view.  Robert, please try
   |    and let me know if you still have any issues with it.
   |
   | Could you build a snapshot for it?

   Snapshot? Are you a snapshot user?

First observations:

1) Sometimes while scrolling the thumbnails repaint twice (flicker).

2) Build thumbnails locks up.  The two threads are:

(gdb) thread 1
[Switching to thread 1 (Thread 1095645760 (LWP 9775))]#0  0xffffe410 in ?? ()
(gdb) where
#0  0xffffe410 in ?? ()
#1  0xbfffe758 in ?? ()
#2  0x00000002 in ?? ()
#3  0x00000000 in ?? ()
#4  0x412bebfe in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#5  0x412bbc00 in _L_mutex_lock_33 () from /lib/tls/libpthread.so.0
#6  0x42000010 in ?? ()
#7  0x00000014 in ?? ()
#8  0x4106dc20 in __JCR_LIST__ () from /usr/lib/qt3/lib/libqt-mt.so.3
#9  0x425dcf88 in ?? ()
#10 0x09255970 in ?? ()
#11 0xbfffe778 in ?? ()
#12 0x40ea4b00 in QRealMutexPrivate::lock ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#13 0x40ea4b00 in QRealMutexPrivate::lock ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#14 0x40ea4934 in QMutex::lock () from /usr/lib/qt3/lib/libqt-mt.so.3
#15 0x0807533f in ImageManager::load ()
#16 0x080d527a in ThumbnailBuilder::generateNext ()
#17 0x080d543c in ThumbnailBuilder::pixmapLoaded ()
#18 0x08075293 in ImageManager::customEvent ()
#19 0x40c0303e in QObject::event () from /usr/lib/qt3/lib/libqt-mt.so.3
#20 0x40ba093f in QApplication::internalNotify ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#21 0x40ba24e9 in QApplication::notify () from /usr/lib/qt3/lib/libqt-mt.so.3
#22 0x4083c0ce in KApplication::notify () from /opt/kde3/lib/libkdecore.so.4
#23 0x40ba1780 in QApplication::sendPostedEvents ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#24 0x40ba1804 in QApplication::sendPostedEvents ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#25 0x40b4f374 in QEventLoop::processEvents ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#26 0x40bb85b1 in QEventLoop::enterLoop () from /usr/lib/qt3/lib/libqt-mt.so.3
#27 0x40bb83f6 in QEventLoop::exec () from /usr/lib/qt3/lib/libqt-mt.so.3
#28 0x40ba23bf in QApplication::exec () from /usr/lib/qt3/lib/libqt-mt.so.3
#29 0x08071cda in main ()
(gdb) thread 2
[Switching to thread 2 (Thread 1106336688 (LWP 9777))]#0  0xffffe410 in ?? ()
(gdb) where
#0  0xffffe410 in ?? ()
#1  0x41f15818 in ?? ()
#2  0x00000002 in ?? ()
#3  0x00000000 in ?? ()
#4  0x412bebfe in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#5  0x412bbc00 in _L_mutex_lock_33 () from /lib/tls/libpthread.so.0
#6  0x412bbea0 in pthread_mutex_unlock () from /lib/tls/libpthread.so.0
#7  0x40ea4b00 in QRealMutexPrivate::lock ()
   from /usr/lib/qt3/lib/libqt-mt.so.3
#8  0x40ea4934 in QMutex::lock () from /usr/lib/qt3/lib/libqt-mt.so.3
#9  0x08074fcf in ImageManager::next ()
#10 0x0807633d in ImageLoader::run ()
#11 0x40b9a185 in QThreadInstance::start () from /usr/lib/qt3/lib/libqt-mt.so.3
#12 0x412ba9dd in start_thread () from /lib/tls/libpthread.so.0
#13 0x41484ffa in clone () from /lib/tls/libc.so.6

It looks like the problem is that ImageManager::customEvent() locks
the image manager while calling back to the client.  The client
(thumbnailbuilder in this case) calls ImageManager::instance()->load,
which of course tries to take the mutex.  This fix takes care of it,
by doing the callback after the lock has been cleared.

*** imagemanager.cpp.~1.32.~	2005-01-13 05:20:23.000000000 -0500
--- imagemanager.cpp	2005-01-13 08:44:46.689659016 -0500
***************
*** 102,129 ****
  
  void ImageManager::customEvent( QCustomEvent* ev )
  {
!     QMutexLocker dummy(&_lock );
!     if ( ev->type() == 1001 )  {
!         ImageEvent* iev = dynamic_cast<ImageEvent*>( ev );
!         if ( !iev )  {
!             Q_ASSERT( iev );
!             return;
!         }
! 
!         ImageRequest* request = iev->loadInfo();
!         QImage image = iev->image();
! 
!         if ( _clientList.find( request ) != 0 )  {
!             // If it is not in the map, then it has been canceled (though ::stop) since the request.
!             ImageClient* client = request->client();
! 
!             client->pixmapLoaded( request->fileName(), QSize(request->width(), request->height()), request->fullSize(), request->angle(), image, request->loadedOK() );
!             _clientList.remove(request);
!             if ( _currentLoading == request )
!                 _currentLoading = 0;
!             delete request;
!         }
!     }
  }
  
  ImageEvent::ImageEvent( ImageRequest* request, const QImage& image )
--- 102,146 ----
  
  void ImageManager::customEvent( QCustomEvent* ev )
  {
!     QString fileName;
!     QSize requestSize;
!     QSize fullSize;
!     int angle = -1;
!     QImage image;
!     bool loadedOK = false;
!     ImageClient *client = 0;
! 
!     do {
! 	QMutexLocker dummy(&_lock );
! 	if ( ev->type() == 1001 )  {
! 	    ImageEvent* iev = dynamic_cast<ImageEvent*>( ev );
! 	    if ( !iev )  {
! 		Q_ASSERT( iev );
! 		return;
! 	    }
! 
! 	    ImageRequest* request = iev->loadInfo();
! 	    image = iev->image();
! 
! 	    if ( _clientList.find( request ) != 0 )  {
! 		// If it is not in the map, then it has been canceled (though ::stop) since the request.
! 		client = request->client();
! 
! 		fileName = request->fileName();
! 		requestSize = QSize(request->width(), request->height());
! 		fullSize = request->fullSize();
! 		angle = request->angle();
! 		loadedOK = request->loadedOK();
! 		_clientList.remove(request);
! 		if ( _currentLoading == request )
! 		    _currentLoading = 0;
! 		delete request;
! 	    }
! 	}
!     } while (0);
!     if (client)
!       client->pixmapLoaded(fileName, requestSize, fullSize, angle, image,
! 			   loadedOK);
  }
  
  ImageEvent::ImageEvent( ImageRequest* request, const QImage& image )


-- 
Robert Krawitz                                     <rlk at alum.mit.edu>

Tall Clubs International  --  http://www.tall.org/ or 1-888-IM-TALL-2
Member of the League for Programming Freedom -- mail lpf at uunet.uu.net
Project lead for Gimp Print   --    http://gimp-print.sourceforge.net

"Linux doesn't dictate how I work, I dictate how Linux works."
--Eric Crampton



More information about the KimDaBa mailing list