Skip to main content



      Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » SWT Thread problem under Linux (GTK)
SWT Thread problem under Linux (GTK) [message #437646] Wed, 09 June 2004 09:22 Go to next message
Eclipse UserFriend
Hi,
I'm dealing with an SWT Exception under Linux (gtk):
I need to create a new display object in a different thread to show a
download progress bar. Every 500ms the progress bar needs to be
refreshed....

public class DownloadProgressThread extends Thread {

public void run() {
Display display = new Display();
Shell s = new Shell(display);
........
display.timerExec(500,new Runnable() {
public void run() {
startRefresh();
}
});

.....
}

public void startRefresh() {
......
display.timerExec(500,new Runnable() {
public void run() {
startRefresh();
}
});

}

During the process the main UI-Thread (related to the thread of the
principal Display) throws an "Invalid Thread Access" SWTException and dies.

org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:2689)
at org.eclipse.swt.SWT.error(SWT.java:2614)
at org.eclipse.swt.SWT.error(SWT.java:2585)
at org.eclipse.swt.widgets.Widget.error(Widget.java:374)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:311)
at org.eclipse.swt.widgets.Control.getShell(Control.java:1597)
at org.eclipse.swt.widgets.Control.getPath(Control.java:1566)
at org.eclipse.swt.widgets.Shell.setActiveControl(Shell.java:86 6)
at org.eclipse.swt.widgets.Control.sendFocusEvent(Control.java: 2196)
at org.eclipse.swt.widgets.Control.gtk_event_after(Control.java :1717)
at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1189)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:3040 )
at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(Native Method)
at org.eclipse.swt.widgets.Display.eventProc(Display.java:839)
at org.eclipse.swt.internal.gtk.OS.gtk_main_iteration(Native Method)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :2252)
at
it.symlabs.sato.client.fileshare.SWTMainPanel.showGUI(SWTMai nPanel.java:288)
at it.symlabs.sato.client.fileshare.SWTMainPanel.main(SWTMainPa nel.java:266)


Why does it access to the display of the main composite, if I create a
new one?

I've tested the application under Windows and works fine.

Maybe it's a bug of the Display implementation under Linux-GTK. It seems
like events destinated to the second thread/Display are dispatched to
the first thread/Display, which tries to access the controls of the
other thread/Display and throws the exception.

Anyone has encountred the same problem? Any ideas?

Thanks in advance.

Maurizio Pillitu
Re: SWT Thread problem under Linux (GTK) [message #437726 is a reply to message #437646] Wed, 09 June 2004 13:01 Go to previous messageGo to next message
Eclipse UserFriend
Are multiple displays supported under GTK? I'm not sure about that..

Also, why do you need to open up a second display just to show a progress
dialog?
This progress dialog will not be owned by the main window of your app.

Can't you just periodically call
display.asynchExec(update-the-progress-of-your-bar) from the worker thread,
where 'display' is the display object of your main thread?

Regards,
Ivan


"Maurizio Pillitu" <m.pillitu@symlabs.it> wrote in message
news:ca6r4h$uc7$1@eclipse.org...
> Hi,
> I'm dealing with an SWT Exception under Linux (gtk):
> I need to create a new display object in a different thread to show a
> download progress bar. Every 500ms the progress bar needs to be
> refreshed....
>
> public class DownloadProgressThread extends Thread {
>
> public void run() {
> Display display = new Display();
> Shell s = new Shell(display);
> ........
> display.timerExec(500,new Runnable() {
> public void run() {
> startRefresh();
> }
> });
>
> .....
> }
>
> public void startRefresh() {
> ......
> display.timerExec(500,new Runnable() {
> public void run() {
> startRefresh();
> }
> });
>
> }
>
> During the process the main UI-Thread (related to the thread of the
> principal Display) throws an "Invalid Thread Access" SWTException and
dies.
>
> org.eclipse.swt.SWTException: Invalid thread access
> at org.eclipse.swt.SWT.error(SWT.java:2689)
> at org.eclipse.swt.SWT.error(SWT.java:2614)
> at org.eclipse.swt.SWT.error(SWT.java:2585)
> at org.eclipse.swt.widgets.Widget.error(Widget.java:374)
> at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:311)
> at org.eclipse.swt.widgets.Control.getShell(Control.java:1597)
> at org.eclipse.swt.widgets.Control.getPath(Control.java:1566)
> at org.eclipse.swt.widgets.Shell.setActiveControl(Shell.java:86 6)
> at org.eclipse.swt.widgets.Control.sendFocusEvent(Control.java: 2196)
> at org.eclipse.swt.widgets.Control.gtk_event_after(Control.java :1717)
> at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1189)
> at org.eclipse.swt.widgets.Display.windowProc(Display.java:3040 )
> at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(Native Method)
> at org.eclipse.swt.widgets.Display.eventProc(Display.java:839)
> at org.eclipse.swt.internal.gtk.OS.gtk_main_iteration(Native Method)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :2252)
> at
>
it.symlabs.sato.client.fileshare.SWTMainPanel.showGUI(SWTMai nPanel.java:288)
> at
it.symlabs.sato.client.fileshare.SWTMainPanel.main(SWTMainPa nel.java:266)
>
>
> Why does it access to the display of the main composite, if I create a
> new one?
>
> I've tested the application under Windows and works fine.
>
> Maybe it's a bug of the Display implementation under Linux-GTK. It seems
> like events destinated to the second thread/Display are dispatched to
> the first thread/Display, which tries to access the controls of the
> other thread/Display and throws the exception.
>
> Anyone has encountred the same problem? Any ideas?
>
> Thanks in advance.
>
> Maurizio Pillitu
Re: SWT Thread problem under Linux (GTK) [message #437729 is a reply to message #437726] Wed, 09 June 2004 15:51 Go to previous messageGo to next message
Eclipse UserFriend
Ivan Markov wrote:
> Are multiple displays supported under GTK? I'm not sure about that..
>
It's a good question; really I don't know... I must read the GTK
documentation.

> Also, why do you need to open up a second display just to show a progress
> dialog?
> This progress dialog will not be owned by the main window of your app.
>
> Can't you just periodically call
> display.asynchExec(update-the-progress-of-your-bar) from the worker thread,
> where 'display' is the display object of your main thread?
>

No, because I need to block the main thread; I've to realize a long
running operation that cannot be transferred to another thread because
draws on the main window.

Thanks
Maurizio Pillitu

> Regards,
> Ivan
>
>
> "Maurizio Pillitu" <m.pillitu@symlabs.it> wrote in message
> news:ca6r4h$uc7$1@eclipse.org...
>
>>Hi,
>>I'm dealing with an SWT Exception under Linux (gtk):
>>I need to create a new display object in a different thread to show a
>>download progress bar. Every 500ms the progress bar needs to be
>>refreshed....
>>
>>public class DownloadProgressThread extends Thread {
>>
>>public void run() {
>> Display display = new Display();
>> Shell s = new Shell(display);
>> ........
>> display.timerExec(500,new Runnable() {
>> public void run() {
>> startRefresh();
>> }
>> });
>>
>> .....
>>}
>>
>>public void startRefresh() {
>> ......
>> display.timerExec(500,new Runnable() {
>> public void run() {
>> startRefresh();
>> }
>> });
>>
>>}
>>
>>During the process the main UI-Thread (related to the thread of the
>>principal Display) throws an "Invalid Thread Access" SWTException and
>
> dies.
>
>>org.eclipse.swt.SWTException: Invalid thread access
>>at org.eclipse.swt.SWT.error(SWT.java:2689)
>>at org.eclipse.swt.SWT.error(SWT.java:2614)
>>at org.eclipse.swt.SWT.error(SWT.java:2585)
>>at org.eclipse.swt.widgets.Widget.error(Widget.java:374)
>>at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:311)
>>at org.eclipse.swt.widgets.Control.getShell(Control.java:1597)
>>at org.eclipse.swt.widgets.Control.getPath(Control.java:1566)
>>at org.eclipse.swt.widgets.Shell.setActiveControl(Shell.java:86 6)
>>at org.eclipse.swt.widgets.Control.sendFocusEvent(Control.java: 2196)
>>at org.eclipse.swt.widgets.Control.gtk_event_after(Control.java :1717)
>>at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1189)
>>at org.eclipse.swt.widgets.Display.windowProc(Display.java:3040 )
>>at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(Native Method)
>>at org.eclipse.swt.widgets.Display.eventProc(Display.java:839)
>>at org.eclipse.swt.internal.gtk.OS.gtk_main_iteration(Native Method)
>>at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :2252)
>>at
>>
>
> it.symlabs.sato.client.fileshare.SWTMainPanel.showGUI(SWTMai nPanel.java:288)
>
>>at
>
> it.symlabs.sato.client.fileshare.SWTMainPanel.main(SWTMainPa nel.java:266)
>
>>
>>Why does it access to the display of the main composite, if I create a
>>new one?
>>
>>I've tested the application under Windows and works fine.
>>
>>Maybe it's a bug of the Display implementation under Linux-GTK. It seems
>>like events destinated to the second thread/Display are dispatched to
>>the first thread/Display, which tries to access the controls of the
>>other thread/Display and throws the exception.
>>
>>Anyone has encountred the same problem? Any ideas?
>>
>>Thanks in advance.
>>
>> Maurizio Pillitu
>
>
>
Re: SWT Thread problem under Linux (GTK) [message #437731 is a reply to message #437729] Wed, 09 June 2004 15:10 Go to previous messageGo to next message
Eclipse UserFriend
> > Also, why do you need to open up a second display just to show a
progress
> > dialog?
> > This progress dialog will not be owned by the main window of your app.
> >
> > Can't you just periodically call
> > display.asynchExec(update-the-progress-of-your-bar) from the worker
thread,
> > where 'display' is the display object of your main thread?
> >
>
> No, because I need to block the main thread; I've to realize a long
> running operation that cannot be transferred to another thread because
> draws on the main window.

I don't quite understand that. What do you mean by 'I need to block the main
thread'?
Do you mean that ***at the same time while the worker thread is running your
operation*** the main thread also does something CPU intensive, like drawing
all the time, not in onPaint()?

I don't believe this is the case. Could you elaborate a bit?
Re: SWT Thread problem under Linux (GTK) [message #437778 is a reply to message #437731] Thu, 10 June 2004 06:20 Go to previous messageGo to next message
Eclipse UserFriend
Ivan Markov wrote:
> I don't quite understand that. What do you mean by 'I need to block the main
> thread'?
> Do you mean that ***at the same time while the worker thread is running your
> operation*** the main thread also does something CPU intensive, like drawing
> all the time, not in onPaint()?
>
> I don't believe this is the case. Could you elaborate a bit?
>

Hi Ivan, thanks for your interest on our problem.

The problem is that we have a single Thread, called "main", that handles
the SWT interface with the common :

shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}


At a certain point the user press on a button, and we start drawing on a
canvas. This is fine as long as the operation is relatively short. Due
to the impossibility to access to the canvas from another thread, and by
the fact that data are generated by an external library to which we
don't have source access, we cannot move this operation on a different
thread. Even worse, since the UI interface has been designed and
approved by the various steps of committers we cannot change it.

So we thought to launch another thread, create a new display, open a new
shell, and display a progress bar and some other informations calling
timerExec to periodically redraw :

public class ProgressThread extends Thread {

public void run() {
try {
Display display = new Display();
Shell shell = new Shell(display);
ProgressWidnow progressWindow = new ProgressWindow(shell, SWT.NULL);
shell.setLayout(new org.eclipse.swt.layout.FillLayout());
Rectangle shellBounds = shell.computeTrim(0,0,246,151);
shell.setSize(shellBounds.width, shellBounds.height);
shell.open();
shell.forceActive();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
} catch (Exception e) {
e.printStackTrace();
}
}

}


This way we should have a second thread ruuning SWT. Teorically, events
for the main window should be received and dispatched by the main
thread, that owns that Display, while events for the progress window
should be received and dispatched by the second thread, that owns the
second Display. This is true in windows, and it works perfectly, but
seems that it's not true under linux GTK.

In Linux events for the progress window arrive to the main thread, and
from there it tries to access the controls owned by the second thread
throwing IllegalThreadAccess exceptions.

Any idea?

Ciao,
Simone Gianni
Re: SWT Thread problem under Linux (GTK) [message #437781 is a reply to message #437778] Thu, 10 June 2004 07:35 Go to previous messageGo to next message
Eclipse UserFriend
Hi Simone,

Thanks for the thoroughful explanation.

> At a certain point the user press on a button, and we start drawing on a
> canvas. This is fine as long as the operation is relatively short. Due
> to the impossibility to access to the canvas from another thread,

Just wanted to mention that you are actually _allowed_ to draw on a canvas,
owned by the event lop ("main") thread from another thread.
You can create a 'new GC(canvas-object)' in the main thread, pass this to
the background thread and then call methods on the GC from the background
thread. I learned this just recently, when my own SWT port started to fail
with recent Eclipse3 milestone.. Note: only draws are allowed, i.e. methods
on GC/Image.

> This way we should have a second thread ruuning SWT. Teorically, events
> for the main window should be received and dispatched by the main
> thread, that owns that Display, while events for the progress window
> should be received and dispatched by the second thread, that owns the
> second Display. This is true in windows, and it works perfectly, but
> seems that it's not true under linux GTK.

Seems so, but I'm in no way expert in SWT/GTK.
It hink this question deserves attention from Steve Northover or some of the
other SWT developers.
Maybe you could ping these guys on the platform-swt-dev mailing list (which
is otherwise for SWT development topics only), to get their attention on
your problem.


> In Linux events for the progress window arrive to the main thread, and
> from there it tries to access the controls owned by the second thread
> throwing IllegalThreadAccess exceptions.

It is really strange that you are actually able to process these events in
the main thread at all..
You said it was busy drawing, right? So it is not running its event loop...

Anyways, if only you could figure out how to call into the 3rd party lib
from the background thread, this may solve the problem, bc as I said - draws
from a background thread are allowed..

Regards,
Ivan
Re: SWT Thread problem under Linux (GTK) [message #438442 is a reply to message #437646] Thu, 24 June 2004 08:29 Go to previous messageGo to next message
Eclipse UserFriend
Nothing to do with your primary problem, but,
won't you have an "stack overflow" problem since startRefresh
calls itself several times?

iran

On Wed, 09 Jun 2004 13:22:45 +0000, Maurizio Pillitu wrote:

> public class DownloadProgressThread extends Thread {
>
> public void run() {
> Display display = new Display();
> Shell s = new Shell(display);
> ........
> display.timerExec(500,new Runnable() {
> public void run() {
> startRefresh();
> }
> });
>
> .....
> }
>
> public void startRefresh() {
> ......
> display.timerExec(500,new Runnable() {
> public void run() {
> startRefresh();
> }
> });
>
> }
>
Re: SWT Thread problem under Linux (GTK) [message #438567 is a reply to message #438442] Sun, 27 June 2004 19:43 Go to previous messageGo to next message
Eclipse UserFriend
No, it's not calling itself, it tells the Display thread to call the
function again after 500 milliseconds, and so on, and so on, so the
stack is never overflowed.

Ciao,
Simone Gianni

Iran wrote:
> Nothing to do with your primary problem, but,
> won't you have an "stack overflow" problem since startRefresh
> calls itself several times?
>
> iran
>
> On Wed, 09 Jun 2004 13:22:45 +0000, Maurizio Pillitu wrote:
>
>
>>public class DownloadProgressThread extends Thread {
>>
>>public void run() {
>> Display display = new Display();
>> Shell s = new Shell(display);
>> ........
>> display.timerExec(500,new Runnable() {
>> public void run() {
>> startRefresh();
>> }
>> });
>>
>> .....
>>}
>>
>>public void startRefresh() {
>> ......
>> display.timerExec(500,new Runnable() {
>> public void run() {
>> startRefresh();
>> }
>> });
>>
>>}
>>
>
>
Re: SWT Thread problem under Linux (GTK) [message #438670 is a reply to message #437646] Tue, 29 June 2004 12:51 Go to previous messageGo to next message
Eclipse UserFriend
I am having a similar problem.
However, mine is with changing text in a text field from a thread.
A bit of investigation found this message on the Widget class in the
javadoc:
"It is also an error to call widget methods from any thread that is
different from the thread that created the widget."

I guess I need to put a loop and listener in the parent thread after
starting the child thread just to change a bit of text.

Kind of sucks but, I shall persist.

Maurizio Pillitu wrote:

> Hi,
> I'm dealing with an SWT Exception under Linux (gtk):
> I need to create a new display object in a different thread to show a
> download progress bar. Every 500ms the progress bar needs to be
> refreshed....
>
> public class DownloadProgressThread extends Thread {
>
> public void run() {
> Display display = new Display();
> Shell s = new Shell(display);
> ........
> display.timerExec(500,new Runnable() {
> public void run() {
> startRefresh();
> }
> });
>
> .....
> }
>
> public void startRefresh() {
> ......
> display.timerExec(500,new Runnable() {
> public void run() {
> startRefresh();
> }
> });
>
> }
>
> During the process the main UI-Thread (related to the thread of the
> principal Display) throws an "Invalid Thread Access" SWTException and
> dies.
>
> org.eclipse.swt.SWTException: Invalid thread access
> at org.eclipse.swt.SWT.error(SWT.java:2689)
> at org.eclipse.swt.SWT.error(SWT.java:2614)
> at org.eclipse.swt.SWT.error(SWT.java:2585)
> at org.eclipse.swt.widgets.Widget.error(Widget.java:374)
> at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:311)
> at org.eclipse.swt.widgets.Control.getShell(Control.java:1597)
> at org.eclipse.swt.widgets.Control.getPath(Control.java:1566)
> at org.eclipse.swt.widgets.Shell.setActiveControl(Shell.java:86 6)
> at org.eclipse.swt.widgets.Control.sendFocusEvent(Control.java: 2196)
> at org.eclipse.swt.widgets.Control.gtk_event_after(Control.java :1717)
> at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1189)
> at org.eclipse.swt.widgets.Display.windowProc(Display.java:3040 )
> at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(Native Method)
> at org.eclipse.swt.widgets.Display.eventProc(Display.java:839)
> at org.eclipse.swt.internal.gtk.OS.gtk_main_iteration(Native Method)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :2252)
> at
>
it.symlabs.sato.client.fileshare.SWTMainPanel.showGUI(SWTMai nPanel.java:288)
> at
> it.symlabs.sato.client.fileshare.SWTMainPanel.main(SWTMainPa nel.java:266)
>
>
> Why does it access to the display of the main composite, if I create a
> new one?
>
> I've tested the application under Windows and works fine.
>
> Maybe it's a bug of the Display implementation under Linux-GTK. It seems
> like events destinated to the second thread/Display are dispatched to
> the first thread/Display, which tries to access the controls of the
> other thread/Display and throws the exception.
>
> Anyone has encountred the same problem? Any ideas?
>
> Thanks in advance.
>
> Maurizio Pillitu
Re: SWT Thread problem under Linux (GTK) [message #438674 is a reply to message #438670] Tue, 29 June 2004 14:05 Go to previous message
Eclipse UserFriend
I'm posting this in case others might find it useful.

Further digging finds the
Display.asyncExec(Runnable) method.
Javadocs are a wonderful thing.

This solved my problem.


Paul Davis wrote:

> I am having a similar problem.
> However, mine is with changing text in a text field from a thread.
> A bit of investigation found this message on the Widget class in the
> javadoc:
> "It is also an error to call widget methods from any thread that is
> different from the thread that created the widget."
>
> I guess I need to put a loop and listener in the parent thread after
> starting the child thread just to change a bit of text.
>
> Kind of sucks but, I shall persist.
>
> Maurizio Pillitu wrote:
>
>> Hi,
>> I'm dealing with an SWT Exception under Linux (gtk):
>> I need to create a new display object in a different thread to show a
>> download progress bar. Every 500ms the progress bar needs to be
>> refreshed....
>>
>> public class DownloadProgressThread extends Thread {
>>
>> public void run() {
>> Display display = new Display();
>> Shell s = new Shell(display);
>> ........
>> display.timerExec(500,new Runnable() {
>> public void run() {
>> startRefresh();
>> }
>> });
>>
>> .....
>> }
>>
>> public void startRefresh() {
>> ......
>> display.timerExec(500,new Runnable() {
>> public void run() {
>> startRefresh();
>> }
>> });
>>
>> }
>>
>> During the process the main UI-Thread (related to the thread of the
>> principal Display) throws an "Invalid Thread Access" SWTException and
>> dies.
>>
>> org.eclipse.swt.SWTException: Invalid thread access
>> at org.eclipse.swt.SWT.error(SWT.java:2689)
>> at org.eclipse.swt.SWT.error(SWT.java:2614)
>> at org.eclipse.swt.SWT.error(SWT.java:2585)
>> at org.eclipse.swt.widgets.Widget.error(Widget.java:374)
>> at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:311)
>> at org.eclipse.swt.widgets.Control.getShell(Control.java:1597)
>> at org.eclipse.swt.widgets.Control.getPath(Control.java:1566)
>> at org.eclipse.swt.widgets.Shell.setActiveControl(Shell.java:86 6)
>> at org.eclipse.swt.widgets.Control.sendFocusEvent(Control.java: 2196)
>> at org.eclipse.swt.widgets.Control.gtk_event_after(Control.java :1717)
>> at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1189)
>> at org.eclipse.swt.widgets.Display.windowProc(Display.java:3040 )
>> at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(Native Method)
>> at org.eclipse.swt.widgets.Display.eventProc(Display.java:839)
>> at org.eclipse.swt.internal.gtk.OS.gtk_main_iteration(Native Method)
>> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :2252)
>> at
>>
>
it.symlabs.sato.client.fileshare.SWTMainPanel.showGUI(SWTMai nPanel.java:288)
>> at
>> it.symlabs.sato.client.fileshare.SWTMainPanel.main(SWTMainPa nel.java:266)
>>
>>
>> Why does it access to the display of the main composite, if I create a
>> new one?
>>
>> I've tested the application under Windows and works fine.
>>
>> Maybe it's a bug of the Display implementation under Linux-GTK. It seems
>> like events destinated to the second thread/Display are dispatched to
>> the first thread/Display, which tries to access the controls of the
>> other thread/Display and throws the exception.
>>
>> Anyone has encountred the same problem? Any ideas?
>>
>> Thanks in advance.
>>
>> Maurizio Pillitu
Previous Topic:RCP question: how to fill the Perspective Bar with all the perspectives
Next Topic:swt 3.0 full support for mac osx?
Goto Forum:
  


Current Time: Sat Jul 05 04:42:50 EDT 2025

Powered by FUDForum. Page generated in 0.03913 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top