Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 236149 - Deadlock creating image outside UI thread on Linux
Summary: Deadlock creating image outside UI thread on Linux
Status: RESOLVED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: PC Linux-GTK
: P3 normal with 2 votes (vote)
Target Milestone: ---   Edit
Assignee: Silenio Quarti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-06-06 17:40 EDT by Chris Lee CLA
Modified: 2008-07-02 17:54 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lee CLA 2008-06-06 17:40:37 EDT
Build ID: I20080530-1730

This is probably a different issue than the bug 50639 of the same description...

We have a background thread which creates images for consumption by the UI thread. In our scenario, we also have another resource used by these threads, around which we use locking (I'll call it "A"). It seems on Linux that running the display queue and creating an image both require a lock as well (I'll call it "D").

As a note, this works fine on both Windows and Mac - the "D" lock doesn't seem to exist in those platforms.

The rough workflow breakdown: 
1. A UI Thread event occurs which spawns our background thread
2. Our background thread starts up, locks resource "A".
3. UI thread continues executing UI events, comes across an event which requires resource "A", blocks on it.
4. Background thread tries to create image. This is where the deadlock occurs - Image.init(ImageData) line: 960 requires a lock which is currently owned by the display thread while it is processing events.
5. We're now in the scenario where the background thread owns "A" and is waiting for "D", while the UI thread owns "D" and is waiting for "A".

Here are the relevant part of my stack traces:

Thread [main] (Suspended)     
      Unsafe.park(boolean, long) line: not available [native method]    
      LockSupport.park(Object) line: not available    
      AbstractQueuedSynchronizer$ConditionObject.awaitUninterruptibly() line: not available [local variables unavailable] 
      [..Code that eventually requires lock on "A"..]
      EventTable.sendEvent(Event) line: 84      
      FigureCanvas(Widget).sendEvent(Event) line: 1154      
      FigureCanvas(Widget).sendEvent(int, Event, boolean) line: 1178    
      FigureCanvas(Widget).sendEvent(int, Event) line: 1163 
      FigureCanvas(Control).gtk_expose_event(int, int) line: 2650 
      FigureCanvas(Composite).gtk_expose_event(int, int) line: 667      
      FigureCanvas(Canvas).gtk_expose_event(int, int) line: 155   
      FigureCanvas(Widget).windowProc(int, int, int) line: 1535   
      FigureCanvas(Control).windowProc(int, int, int) line: 4448  
      Display.windowProc(int, int, int) line: 4096    
      OS._gtk_main_do_event(int) line: not available [native method]    
      OS.gtk_main_do_event(int) line: 5783      
      Display.eventProc(int, int) line: 1175    
      OS._g_main_context_iteration(int, boolean) line: not available [native method]      
      OS.g_main_context_iteration(int, boolean) line: 1541  
      Display.readAndDispatch() line: 3028      
      Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2382    
      Workbench.runUI() line: 2346  
      Workbench.access$4(Workbench) line: 2198  
      Workbench$5.run() line: 493   
      Realm.runWithDefault(Realm, Runnable) line: 288 
      Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 488    
      PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149   
      Application.run(Object) line: 44    
      NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]     
      NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available   
      DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available     
      Method.invoke(Object, Object...) line: not available  
      EclipseAppContainer.callMethodWithException(Object, String, Class[], Object[]) line: 574   
      EclipseAppHandle.run(Object) line: 195    
      EclipseAppLauncher.runApplication(Object) line: 110   
      EclipseAppLauncher.start(Object) line: 79 
      EclipseStarter.run(Object) line: 382      
      EclipseStarter.run(String[], Runnable) line: 179      
      NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]     
      NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available   
      DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available     
      Method.invoke(Object, Object...) line: not available  
      Main.invokeFramework(String[], URL[]) line: 549 
      Main.basicRun(String[]) line: 504   
      Main.run(String[]) line: 1236 
      Main.main(String[]) line: 1212      



Thread [Background-3] (Suspended)     
      Object.wait(long) line: not available [native method] 
      Lock(Object).wait() line: 485 
      Lock.lock() line: 34    
      OS.gdk_pixbuf_new(int, boolean, int, int, int) line: 3080   
      Image.init(ImageData) line: 960     
      Image.<init>(Device, ImageData) line: 400 
      ImageCreator.createImage() line: 60    
      [.. Code flow that acquires lock on "A" ..]
      ThreadPoolExecutor$Worker.runTask(Runnable) line: not available   
      ThreadPoolExecutor$Worker.run() line: not available   
      Thread.run() line: not available
Comment 1 Steve Northover CLA 2008-06-19 13:18:10 EDT
You won't be able to wait inside call-in on GTK.  SWT locks all access to the operating system on that platform using a single lock so that X Windows doesn't explode underneath when accessed from different threads.  The lock is released just before SWT goes to sleep, allowing other threads to run.  If you don't go back to sleep, then you can get deadlock.

The work around is to run code in asyncExec() in the GUI thread in situations where this happens.  I'm really sorry about this but given the underlying X Windows constraints, there just isn't a better solution.
Comment 2 Steve Northover CLA 2008-07-02 17:54:12 EDT
Sorry, we WONTFIX this.