Forum: JRuby feature request: die when the main thread closes

Posted by Roger Pack (rogerdpack)
on 2010-08-07 15:50
Situation currently is that if you "accidentally" (or knowingly) start a
java background thread, ex:

java.awt.FileDialog.new(nil).show

when you exit your jruby main thread, the process hangs, waiting on
awt's thread, which ruby can't even see in its thread list.

Something to alleviate this would be a bit convenient, since we're used
to other threads dying when the main one does in MRI.
Thanks!
-r
Posted by Charles Nutter (headius)
on 2010-08-07 17:42
(Received via mailing list)
Hmm, for me, on OS X and JRuby master, this script does terminate
after the dialog has been dismissed.

For a case that doesn't exit:

javax.swing.JFrame.new('blah').show

You can add an explicit exit (Kernel#exit, in other words) that will
eventually call java.lang.System.exit and terminate the JVM, event
thread and all.

Is that satsifactory?

On Sat, Aug 7, 2010 at 8:50 AM, Roger Pack <lists@ruby-forum.com> wrote:
> Thanks!
>
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Posted by Roger Pack (rogerdpack)
on 2010-08-07 19:23
Charles Nutter wrote:
> Hmm, for me, on OS X and JRuby master, this script does terminate
> after the dialog has been dismissed.
> 
> For a case that doesn't exit:
> 
> javax.swing.JFrame.new('blah').show
> 
> You can add an explicit exit (Kernel#exit, in other words) that will
> eventually call java.lang.System.exit and terminate the JVM, event
> thread and all.
> 
> Is that satsifactory?

Almost, except that few people would intuitively know that that's what 
they have to do :P
Posted by Charles Nutter (headius)
on 2010-08-07 20:46
(Received via mailing list)
On Sat, Aug 7, 2010 at 12:23 PM, Roger Pack <lists@ruby-forum.com> 
wrote:
> Almost, except that few people would intuitively know that that's what
> they have to do :P

Yeah, I suppose the problem here is guessing developers' intent. If
you were writing the identical code in Java, you'd get the current
result: the non-daemon Swing event thread would keep the JVM alive.
There's various reasons for this, but perhaps the most important one
is that many GUI apps don't really have a "main" per se; they use
Swing events to drive the application.

We could actively make the "main" script exiting be a hard
System.exit, but we'd need to always know whether we were invoked from
a command line or invoked from an embedded environment. In the latter
case, a hard exit is the *absolutely wrong* thing to do, since it
would likely take down other threads and co-located applications.

So there's no one answer that solves every case cleanly. Requiring an
explicit exit when you've done something that starts the event thread
is a reasonably good middle ground; it enables people to force a hard
exit, but doesn't automatically force a hard exit for users that don't
want it.

We've gone round and round on this one for years and made no progress
finding a better option. But that doesn't mean there isn't one out
there we haven't discussed :)

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Posted by Trejkaz Xx (trejkaz)
on 2010-08-08 03:33
(Received via mailing list)
On Sun, Aug 8, 2010 at 3:23 AM, Roger Pack <lists@ruby-forum.com> wrote:
> Almost, except that few people would intuitively know that that's what
> they have to do :P

AWT developers are supposed to know that all code manipulating AWT
(this includes instantiating Component objects and calling show() and
so forth, but a lot more) should be run on the Event Dispatch Thread,
otherwise you can get all sorts of weird behaviour, including
deadlocks.

So actually, that script in the original post was actually using AWT
incorrectly in the first place.  It should have been using
invokeLater() to kick it over to the EDT.

Once that is done, you will find that in the case of most
applications, the main thread doesn't have a lot to do, so it's quite
normal for it to exit - thus you do want the application to keep
running.

Assuming you did still want to use the main thread as a kind of
"worker" thread and still push things over to the EDT using
invokeLater(), you can still make sure it exits by ensuring that the
AWT thread is not running when your main thread exits.  In the case of
this particular example, you are not calling dispose() on the
FileDialog, so its resources will actually be sitting around still,
and will generally hold the thread open (even though on OS X this does
not appear to be the case).  In a Swing application you would normally
set the default close operation instead of disposing it yourself,
except in circumstances where you had to check something before
allowing the window to close.

TX

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Posted by Roger Pack (rogerdpack)
on 2010-08-09 14:16
> Yeah, I suppose the problem here is guessing developers' intent. If
> you were writing the identical code in Java, you'd get the current
> result: the non-daemon Swing event thread would keep the JVM alive.
> There's various reasons for this, but perhaps the most important one
> is that many GUI apps don't really have a "main" per se; they use
> Swing events to drive the application.

So what you're saying is that typically with MRI GUI's they have a 
".main" but java GUI's don't necessarily have such?
Posted by Charles Nutter (headius)
on 2010-08-12 21:18
(Received via mailing list)
On Mon, Aug 9, 2010 at 7:16 AM, Roger Pack <lists@ruby-forum.com> wrote:
> So what you're saying is that typically with MRI GUI's they have a
> ".main" but java GUI's don't necessarily have such?

Trejkaz laid it out pretty neatly, but I'll say it this way: In many
Java GUI applications, the main thread is only used to bootstrap the
GUI elements and the workers that will feed it, and everything else
progresses from there in a mostly event-driven fashion. So it's not
uncommon to have the main thread for a GUI app exit while the GUI and
workers it started keep running.

In any case, if we were to have the main script's exit cause a hard
system exit, it would break Java/AWT/Swing developers expectations
about application lifecycle. This is one of those areas where the MRI
way just doesn't apply well to a JVM/Java pattern.

(To be honest, I don't like the MRI way very much, since if the main
thread exits even *accidentally*, all the worker threads you've
started immediately terminate)

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Posted by Roger Pack (rogerdpack)
on 2010-08-16 23:39
> (To be honest, I don't like the MRI way very much, since if the main
> thread exits even *accidentally*, all the worker threads you've
> started immediately terminate)

Yeah, for me I think it should be an option (and turned off by default), 
even in MRI.  I suppose if there's no easy work-around then as it is now 
works.
-r
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.