Thread Deadlock on Ruby 1.8.7

J

Jayce Meade

Hey everyone.

I'm running into a bit of a problem, what I'm trying to do is =
basically use one ruby script to initiate the main program, so that when =
I want to restart the program, it literally exits, going all the way =
back to the starter script so that all the files loaded by the main =
script are loaded anew when the starter script runs the program again.

I have achieved this by using system(), but it started two ruby =
processes so I tried using Thread.new{} instead since all thread =
variables are local to that thread, thus all my files and variables are =
unassigned when the thread terminates. It runs wonderfully, but when I =
call the quit command, I get a deadlock error from the main program's =
quit method. Here's the terminal output from basic start to error:

[System] Welcome to Ecko!
[System] Loading configuration...
[12:24:10 PM][System] Configuration loaded. Running integrity checks...
[12:24:10 PM][System] System data is stable. Displaying info...
[12:24:10 PM][System] Please read the release notes for important =
information.
[12:24:10 PM][System] Starting Ecko 0.3.83 Beta RC2.
[12:24:10 PM][Connection] Checking for stored authtoken.
[12:24:10 PM][Connection] Found stored authtoken.
[12:24:10 PM][Connection] Logged in as v-Ecko-v
[12:24:10 PM][Connection] Joining default chatrooms: Botdom
[12:24:10 PM][Connection] Joined #Botdom [ok]
[12:24:39 PM][Botdom] ** AzimuthDragon has joined.
[12:24:41 PM][Botdom] <AzimuthDragon> |]quit
deadlock 0x294c1fc: sleep:J(0x2e6e07c) (main) - Ecko.rb:32
deadlock 0x2e6e07c: sleep:- - C:/Documents and Settings/User/My =
Documents/NetBe
ansProjects/Ecko Beta 2 RC2/lib/System/Core/Communication.class.rb:555
C:/Documents and Settings/User/My Documents/NetBeansProjects/Ecko Beta 2 =
RC2/lib
/System/Core/Communication.class.rb:555: Thread(0x2e6e07c): deadlock =
(fatal)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
Ecko has shut down. Would you like to run it again? (y/n)

This program logs into a chat room, by the way.

Here's the starting sequence: Run Ecko.bat -> Ecko.rb -> main.rb

The batch file displays the 'Run again?' messages, for when the ruby =
script itself terminates, Ecko.rb is the initation script, and main.rb =
is the program's main file. The program can be run just by using =
main.rb, but the terminal closes when the program terminates.

I'm also using this initiation script to recognize errors, before it was =
just checking the exit code. Here's the code for the initation script =
and the method that quits the main program when used:

ecko =3D Thread.new { require 'main.rb' } # < Starts the main script, =
the main script runs itself when it's loaded, so requiring it is all =
that needs to be done.
ecko.join # < I think this is being used right, it's so that the =
initiation script doesn't continue running while the thread is alive. =
This is also as far as the initation script gets.
case ecko["exitstatus"] # < Exit code is stored here manually by the =
main program, see the below code for more info.

That's all the relevant code for the initiation script, here's the main =
program's quit code:

when 'quit'
say(c, 'Exiting....')
@joined.each { |chan| log(chan, "\n----- Left #{chan} at =
#{Time.now.strftime("%I:%M:%S %p")} (Quit command was used) -----\n")} # =
< Logs the quit to the chatroom logs.
self.disconnect() # < Disconnects from chatroom.
Thread.current["exitstatus"] =3D 0 # < Sets the exitstatus for 0 since =
this is a normal exit.
Thread.stop # < Kills the thread, if I did it right, the program dies =
when this is executed.
true

That's the code used to close the main program, and it dies on =
Thread.stop.

What am I doing wrong?

- Jayce
 
J

Joel VanderWerf

Jayce said:
when 'quit'
say(c, 'Exiting....')
@joined.each { |chan| log(chan, "\n----- Left #{chan} at #{Time.now.strftime("%I:%M:%S %p")} (Quit command was used) -----\n")} # < Logs the quit to the chatroom logs.
self.disconnect() # < Disconnects from chatroom.
Thread.current["exitstatus"] = 0 # < Sets the exitstatus for 0 since this is a normal exit.
Thread.stop # < Kills the thread, if I did it right, the program dies when this is executed.
true

That's the code used to close the main program, and it dies on Thread.stop.

Given your description, wouldn't Thread.exit be the right method, not
Thread.stop ?
 
J

Jayce Meade

Eh, probably. I was looking through it all, was more curious about the
deadlock, I went to Google for threading answers, and the page I found
didn't mention Thread#exit, so, didn't think to look up other methods. I'll
give it a try.

Thank you!

--------------------------------------------------
From: "Joel VanderWerf" <[email protected]>
Sent: Monday, February 23, 2009 4:21 PM
Jayce said:
when 'quit'
say(c, 'Exiting....')
@joined.each { |chan| log(chan, "\n----- Left #{chan} at
#{Time.now.strftime("%I:%M:%S %p")} (Quit command was used) -----\n")} #
< Logs the quit to the chatroom logs.
self.disconnect() # < Disconnects from chatroom.
Thread.current["exitstatus"] = 0 # < Sets the exitstatus for 0 since
this is a normal exit.
Thread.stop # < Kills the thread, if I did it right, the program dies
when this is executed.
true

That's the code used to close the main program, and it dies on
Thread.stop.

Given your description, wouldn't Thread.exit be the right method, not
Thread.stop ?
 
J

Jayce Meade

It worked, thank you. I am curious though, what exactly causes the deadlock,
in most cases?

--------------------------------------------------
From: "Jayce Meade" <[email protected]>
Sent: Monday, February 23, 2009 4:33 PM
Eh, probably. I was looking through it all, was more curious about the
deadlock, I went to Google for threading answers, and the page I found
didn't mention Thread#exit, so, didn't think to look up other methods.
I'll give it a try.

Thank you!

--------------------------------------------------
From: "Joel VanderWerf" <[email protected]>
Sent: Monday, February 23, 2009 4:21 PM
Jayce said:
when 'quit'
say(c, 'Exiting....')
@joined.each { |chan| log(chan, "\n----- Left #{chan} at
#{Time.now.strftime("%I:%M:%S %p")} (Quit command was used) -----\n")} #
< Logs the quit to the chatroom logs.
self.disconnect() # < Disconnects from chatroom.
Thread.current["exitstatus"] = 0 # < Sets the exitstatus for 0 since
this is a normal exit.
Thread.stop # < Kills the thread, if I did it right, the program dies
when this is executed.
true

That's the code used to close the main program, and it dies on
Thread.stop.

Given your description, wouldn't Thread.exit be the right method, not
Thread.stop ?
 
J

Joel VanderWerf

Jayce said:
It worked, thank you. I am curious though, what exactly causes the
deadlock, in most cases?

Perhaps all threads were in the sleep/stop state?
 
J

Jayce Meade

True, if I had the starter script paused so that the main program could
execute, an improper exit would kill the running thread and never resume the
main one, would it?

:) Thanks for the help, I really appreciate it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top