[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

"stack level too deep"... because Threads keep their "starting" stack

Sam Roberts

2/11/2005 4:20:00 AM

It appears threads keep their callers stack. Reasonable. But they do
this when their caller was a thread, and it can lead to problems.

Is there any way to strip your calling context, or does it break the
language somehow? Is it needed for purposes other than debugging?

Cheers,
Sam


$ ruby18 xthrd.rb
................................................................................................................................................................................................................................stack level too deep

$ cat xthrd.rb

$stdout.sync = true

class Cache
def resweep( period )
Thread.new do
begin
#sleep( period )
sweep_cache
rescue
puts $!
# $!.backtrace.each { |s| puts s }
exit 1
end
# then return, so we cease to exist, freeing our resources... right?
end
end

def sweep_cache
$stdout.write "."
resweep(1)
end

end


c = Cache.new

c.resweep(1)

loop do
sleep 60
end


^^^^^^^^^^^^


What I was trying to do was when I saw something needed to be done to
the cache in some amount of seconds, spin off a Thread that would sleep
for those seconds, then do the work.

However, the work might involve noticing new work to be done some time.
So, spin off another thread to do the work, and finish your own work. No
problem... ???

I'm going to do this differently, but I thought it was interesting and
unexpected.



3 Answers

Yukihiro Matsumoto

2/11/2005 4:25:00 AM

0

Hi,

In message "Re: "stack level too deep"... because Threads keep their "starting" stack"
on Fri, 11 Feb 2005 13:19:53 +0900, Sam Roberts <sroberts@uniserve.com> writes:

|Is there any way to strip your calling context, or does it break the
|language somehow? Is it needed for purposes other than debugging?

No way to strip. It's a limitation of the current thread
implementation.

matz.


Mark Hubbart

2/11/2005 11:02:00 PM

0

Hi,

On Fri, 11 Feb 2005 13:25:05 +0900, Yukihiro Matsumoto
<matz@ruby-lang.org> wrote:
> Hi,
>
> In message "Re: "stack level too deep"... because Threads keep their "starting" stack"
> on Fri, 11 Feb 2005 13:19:53 +0900, Sam Roberts <sroberts@uniserve.com> writes:
>
> |Is there any way to strip your calling context, or does it break the
> |language somehow? Is it needed for purposes other than debugging?
>
> No way to strip. It's a limitation of the current thread
> implementation.

This might work. This is only lightly tested, so there might be hidden
bugs, or issues I didn't think of. And it's not exactly the prettiest
code :) Just a quick POC.


## unstacker.rb
require 'thread'

class Thread
THREADS_TO_CREATE = []
THREAD_CREATION_MUTEX = Mutex.new
class ThreadUnstacker < Thread
alias_method :kill!, :kill
def kill() false end
end
UNSTACKER = ThreadUnstacker.new do
loop do
sleep
request = THREADS_TO_CREATE.shift
request[:thread] = Thread.new &request[:proc]
request[:requester].wakeup
end
end
def self.unstack(&block)
request = {}
request[:proc] = block
request[:requester] = Thread.current
THREAD_CREATION_MUTEX.synchronize do
THREADS_TO_CREATE << request
UNSTACKER.wakeup
sleep until request[:thread]
end # sync
request[:thread]
end
end


## irb session:

irb> def recurse(times, &block)
irb> times.zero?? block.call : recurse(times-1, &block)
irb> end
==>nil
irb> recurse(2000){Thread.new{puts "caller.size: #{caller.size}"}}
caller.size: 2008
==>#<Thread:0x579644 dead>
irb> recurse(2000){Thread.unstack{puts "caller.size: #{caller.size}"}}
caller.size: 12
==>#<Thread:0x5a3278 dead>

cheers,
Mark


nobu.nokada

2/11/2005 11:35:00 PM

0

Hi,

At Fri, 11 Feb 2005 13:25:05 +0900,
Yukihiro Matsumoto wrote in [ruby-talk:130440]:
> |Is there any way to strip your calling context, or does it break the
> |language somehow? Is it needed for purposes other than debugging?
>
> No way to strip. It's a limitation of the current thread
> implementation.

[ruby-dev:21556]

--
Nobu Nakada