Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Thread safety of Display.syncExec()
Thread safety of Display.syncExec() [message #460729] Tue, 06 September 2005 04:45 Go to next message
Mark McLaren is currently offline Mark McLarenFriend
Messages: 45
Registered: July 2009
Member
It seems to me the Display.syncExec() is not thread-safe. For example, at
the end of a long operation (performed outside the UI thread), I would be
tempted to do this:

if (!display.isDisposed()) {
display.syncExec(new Runnable() {
public void run() {
if (!display.isDisposed()) {
// Update screen
}
}
}
}


The problem is that the display could be disposed AFTER the first
isDisposed() call but BEFORE the syncExec() call.

A workaround is to synchronize the threads 'manually' by listening for the
dispose event, but shouldn't syncExec() really be thread-safe?
Re: Thread safety of Display.syncExec() [message #460730 is a reply to message #460729] Tue, 06 September 2005 06:30 Go to previous messageGo to next message
cloudor Mising name is currently offline cloudor Mising nameFriend
Messages: 34
Registered: July 2009
Member
The runnable object is queued rather than executed right now. The word "sync" means your current thread is blocked until the runnable is finished.
Re: Thread safety of Display.syncExec() [message #460737 is a reply to message #460730] Tue, 06 September 2005 13:04 Go to previous messageGo to next message
Mark McLaren is currently offline Mark McLarenFriend
Messages: 45
Registered: July 2009
Member
Cloudor Pu wrote:

> The runnable object is queued rather than executed right now. The word
"sync" means your current thread is blocked until the runnable is finished.

Yes, that's what normally happens. But if the display is disposed,
syncExec immediately throws an SWTException - so how can I ensure this
doesn't happen?

The obvious answer is to check if the display is disposed before making
the syncExec() call like this...

if (!display.isDisposed()) {
display.syncExec(new Runnable() {
public void run() {
if (!display.isDisposed()) {
// Update screen
}
}
}
}


... but I don't think that will always work.
Re: Thread safety of Display.syncExec() [message #460746 is a reply to message #460737] Tue, 06 September 2005 16:27 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: richkulp.us.NO_SPAM.ibm.com

You should not need to check if the display is disposed WITHIN the
runnable. The runnable will not be executed if the display was disposed
because it is the display that does the execution of the runnable. If it
was disposed it wouldn't execute.

You can either check if disposed before, or just put your
display.syncExec() within a try/catch for SWTException.

However, what makes you think the display will ever be disposed by the
time your are finished? I've done many jobs and never ran into this
situation.

--
Thanks,
Rich Kulp
Re: Thread safety of Display.syncExec() [message #460753 is a reply to message #460746] Wed, 07 September 2005 00:28 Go to previous messageGo to next message
Mark McLaren is currently offline Mark McLarenFriend
Messages: 45
Registered: July 2009
Member
Rich Kulp wrote:

> You should not need to check if the display is disposed WITHIN the
> runnable. The runnable will not be executed if the display was disposed
> because it is the display that does the execution of the runnable. If it
> was disposed it wouldn't execute.

Yep you are right, I don't need to check within the runnable - my mistake.


> You can either check if disposed before, or just put your
> display.syncExec() within a try/catch for SWTException.

Although the first option you mention is very common, I don't think it is
100% reliable - the display.syncExec() can on rare occasions still throw
an error because it may have been disposed by another thread. That is:

if (!display.isDisposed()) {
// display could now be disposed in another thread
display.syncExec(myRunnable);
}

Funnily enough, the syncExec() method itself has the same problem (at
least on windows). Here it is with my comment added:

public void syncExec (Runnable runnable) {
if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
// could now be disposed in another thread, which sets
// synchronizer to null, so we get a NullPointerException
synchronizer.syncExec (runnable);
}


I hadn't considered the "catch SWTException" approach - it would probably
be the best solution if it wasn't for the above bug in syncExec().


> However, what makes you think the display will ever be disposed by the
> time your are finished? I've done many jobs and never ran into this
> situation.

Are you saying you always prevent the user from closing the main shell
while you run a long operation? Otherwise I can't see how you can be sure
the display still exists at the end of the operation.

In my application, I am creating a 'Print Preview' dialog, but still want
the user to be able to cancel the dialog before the preview has been
generated. Nothing stops her from closing the entire app, so I need to
check the display still exists once the print preview has been generated.
Re: Thread safety of Display.syncExec() [message #460767 is a reply to message #460753] Wed, 07 September 2005 01:07 Go to previous messageGo to next message
Steve Northover is currently offline Steve NorthoverFriend
Messages: 1636
Registered: July 2009
Senior Member
You need to shut down your threads before you dispose the display. Turns
out that while the display is being disposed, another thread can be
syncExec()'ing. In that case, what should happen? If the display is too
far gone, it may be unable to exec your runnable because it has given back
some needed operating system resources but if it doesn't run the runnable,
you wait forever. It's complicated.

See https://bugs.eclipse.org/bugs/show_bug.cgi?id=76182.

"Mark McLaren" <noone@nowhere.com> wrote in message
news:5cf10b519a21424fa317a2b99f32fa8f$1@www.eclipse.org...
> Rich Kulp wrote:
>
> > You should not need to check if the display is disposed WITHIN the
> > runnable. The runnable will not be executed if the display was disposed
> > because it is the display that does the execution of the runnable. If it
> > was disposed it wouldn't execute.
>
> Yep you are right, I don't need to check within the runnable - my mistake.
>
>
> > You can either check if disposed before, or just put your
> > display.syncExec() within a try/catch for SWTException.
>
> Although the first option you mention is very common, I don't think it is
> 100% reliable - the display.syncExec() can on rare occasions still throw
> an error because it may have been disposed by another thread. That is:
>
> if (!display.isDisposed()) {
> // display could now be disposed in another thread
> display.syncExec(myRunnable);
> }
>
> Funnily enough, the syncExec() method itself has the same problem (at
> least on windows). Here it is with my comment added:
>
> public void syncExec (Runnable runnable) {
> if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
> // could now be disposed in another thread, which sets
> // synchronizer to null, so we get a NullPointerException
> synchronizer.syncExec (runnable);
> }
>
>
> I hadn't considered the "catch SWTException" approach - it would probably
> be the best solution if it wasn't for the above bug in syncExec().
>
>
> > However, what makes you think the display will ever be disposed by the
> > time your are finished? I've done many jobs and never ran into this
> > situation.
>
> Are you saying you always prevent the user from closing the main shell
> while you run a long operation? Otherwise I can't see how you can be sure
> the display still exists at the end of the operation.
>
> In my application, I am creating a 'Print Preview' dialog, but still want
> the user to be able to cancel the dialog before the preview has been
> generated. Nothing stops her from closing the entire app, so I need to
> check the display still exists once the print preview has been generated.
>
>
>
>
>
Re: Thread safety of Display.syncExec() [message #460791 is a reply to message #460753] Wed, 07 September 2005 07:42 Go to previous messageGo to next message
Stefan Langer is currently offline Stefan LangerFriend
Messages: 236
Registered: July 2009
Senior Member
As far as I understand you, your operation doesnot make sense once the
main app is closed. So if your method throws a SWTException the
application is allready closed meaning you can simply catch the
exception and ignore it (logging it as a warning might still be a good
idea so you can recap).
More problematic would be a case where your operation has to finish when
the application is closed down but then you don't have any gui to report
anything back to so your operation might as well use a asyncExec and
simply try to update the display as it sees fit.
In both cases I would say it is acceptable to simply catch the
SWTException and ignore the consequences.

Regards
Stefan

Mark McLaren wrote:
> Rich Kulp wrote:
>
>> You should not need to check if the display is disposed WITHIN the
>> runnable. The runnable will not be executed if the display was
>> disposed because it is the display that does the execution of the
>> runnable. If it was disposed it wouldn't execute.
>
>
> Yep you are right, I don't need to check within the runnable - my mistake.
>
>
>> You can either check if disposed before, or just put your
>> display.syncExec() within a try/catch for SWTException.
>
>
> Although the first option you mention is very common, I don't think it
> is 100% reliable - the display.syncExec() can on rare occasions still
> throw an error because it may have been disposed by another thread.
> That is:
>
> if (!display.isDisposed()) {
> // display could now be disposed in another thread
> display.syncExec(myRunnable);
> }
>
> Funnily enough, the syncExec() method itself has the same problem (at
> least on windows). Here it is with my comment added:
>
> public void syncExec (Runnable runnable) {
> if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
> // could now be disposed in another thread, which sets
> // synchronizer to null, so we get a NullPointerException
> synchronizer.syncExec (runnable);
> }
>
>
> I hadn't considered the "catch SWTException" approach - it would
> probably be the best solution if it wasn't for the above bug in syncExec().
>
>> However, what makes you think the display will ever be disposed by the
>> time your are finished? I've done many jobs and never ran into this
>> situation.
>
>
> Are you saying you always prevent the user from closing the main shell
> while you run a long operation? Otherwise I can't see how you can be
> sure the display still exists at the end of the operation.
> In my application, I am creating a 'Print Preview' dialog, but still
> want the user to be able to cancel the dialog before the preview has
> been generated. Nothing stops her from closing the entire app, so I
> need to check the display still exists once the print preview has been
> generated.
>
>
>
>
>
Re: Thread safety of Display.syncExec() [message #460813 is a reply to message #460767] Wed, 07 September 2005 21:16 Go to previous messageGo to next message
John Arthorne is currently offline John ArthorneFriend
Messages: 176
Registered: July 2009
Senior Member
I think the correct bug reference is:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=106984
--

Steve Northover wrote:
> You need to shut down your threads before you dispose the display. Turns
> out that while the display is being disposed, another thread can be
> syncExec()'ing. In that case, what should happen? If the display is too
> far gone, it may be unable to exec your runnable because it has given back
> some needed operating system resources but if it doesn't run the runnable,
> you wait forever. It's complicated.
>
> See https://bugs.eclipse.org/bugs/show_bug.cgi?id=76182.
>
> "Mark McLaren" <noone@nowhere.com> wrote in message
> news:5cf10b519a21424fa317a2b99f32fa8f$1@www.eclipse.org...
>
>>Rich Kulp wrote:
>>
>>
>>>You should not need to check if the display is disposed WITHIN the
>>>runnable. The runnable will not be executed if the display was disposed
>>>because it is the display that does the execution of the runnable. If it
>>> was disposed it wouldn't execute.
>>
>>Yep you are right, I don't need to check within the runnable - my mistake.
>>
>>
>>
>>>You can either check if disposed before, or just put your
>>>display.syncExec() within a try/catch for SWTException.
>>
>>Although the first option you mention is very common, I don't think it is
>>100% reliable - the display.syncExec() can on rare occasions still throw
>>an error because it may have been disposed by another thread. That is:
>>
>>if (!display.isDisposed()) {
>> // display could now be disposed in another thread
>> display.syncExec(myRunnable);
>>}
>>
>>Funnily enough, the syncExec() method itself has the same problem (at
>>least on windows). Here it is with my comment added:
>>
>>public void syncExec (Runnable runnable) {
>> if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
>> // could now be disposed in another thread, which sets
>> // synchronizer to null, so we get a NullPointerException
>> synchronizer.syncExec (runnable);
>>}
>>
>>
>>I hadn't considered the "catch SWTException" approach - it would probably
>>be the best solution if it wasn't for the above bug in syncExec().
>>
>>
>>
>>>However, what makes you think the display will ever be disposed by the
>>>time your are finished? I've done many jobs and never ran into this
>>>situation.
>>
>>Are you saying you always prevent the user from closing the main shell
>>while you run a long operation? Otherwise I can't see how you can be sure
>>the display still exists at the end of the operation.
>>
>>In my application, I am creating a 'Print Preview' dialog, but still want
>>the user to be able to cancel the dialog before the preview has been
>>generated. Nothing stops her from closing the entire app, so I need to
>>check the display still exists once the print preview has been generated.
>>
>>
>>
>>
>>
>
>
>
Re: Thread safety of Display.syncExec() [message #460857 is a reply to message #460753] Thu, 08 September 2005 23:44 Go to previous message
No real name is currently offline No real nameFriend
Messages: 97
Registered: July 2009
Member
In general, if you have a long runing task, you also need to provide
cancel buttons and options. You can implement this catching disposing
signals and programatically shuting down threads, starting from worker
threads.
Worker threads should check periodically and shutdow themself and
trigger real shutdown. Note that this type of handling is relatively simple.
Normally System.exit(0) should work.

> In my application, I am creating a 'Print Preview' dialog, but still want
> the user to be able to cancel the dialog before the preview has been
> generated. Nothing stops her from closing the entire app, so I need to
> check the display still exists once the print preview has been generated.
Previous Topic:Drop Target on a Browser
Next Topic:cannot find view
Goto Forum:
  


Current Time: Thu Apr 25 03:32:56 GMT 2024

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

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

Back to the top