Thread Deadlock on Ruby 1.8.7


#1

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] |]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)

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 = 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”] = 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

#2

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” removed_email_address@domain.invalid
Sent: Monday, February 23, 2009 4:21 PM
To: “ruby-talk ML” removed_email_address@domain.invalid
Subject: Re: Thread Deadlock on Ruby 1.8.7


#3

Jayce M. wrote:

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 ?


#4

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


From: “Jayce M.” removed_email_address@domain.invalid
Sent: Monday, February 23, 2009 4:33 PM
To: “ruby-talk ML” removed_email_address@domain.invalid
Subject: Re: Thread Deadlock on Ruby 1.8.7


#5

Jayce M. wrote:

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?


#6

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?

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


From: “Joel VanderWerf” removed_email_address@domain.invalid
Sent: Monday, February 23, 2009 4:53 PM
To: “ruby-talk ML” removed_email_address@domain.invalid
Subject: Re: Thread Deadlock on Ruby 1.8.7