From: Gin Mendi on
Eleanor McHugh wrote:
> On 2 Sep 2009, at 05:55, Gin Mendi wrote:
>> Is there an approach I can use to solve this problem or do I just
>> simply
>> give up and use something else. I'm hoping some of the gurus here can
>> give me some information on what I can do.
>
> Do you have code available that we can study?

Thanks again for taking the time to read this!

require 'feed_library'

# my callback for the live feed
FEED_CALLBACK = DL.callback('0PL') { |result_list, count| }
if result_list
record = FeedRecord.new(result_list)
puts record.code
end
}

# handle used to request for a feed
handle = FeedLibrary::log_on("user", "password")

session = get_live_feed(handle, FEED_CALLBACK)

# my attempt to keep this running and waiting on the callback:
while true

end

Here's one I tried. Been playing around with different approaches. With
this method I noticed I always get the cross-thread violation when I use
the FeedRecord structure. If I don't use the structure and do something
else like using the struct! method I'm able to get away with the
callback being performed a couple of times then it eventually leads to a
cross-thread violation.
--
Posted via http://www.ruby-forum.com/.

From: Eleanor McHugh on
On 3 Sep 2009, at 03:08, Gin Mendi wrote:
> Thanks again for taking the time to read this!
>
> require 'feed_library'
>
> # my callback for the live feed
> FEED_CALLBACK = DL.callback('0PL') { |result_list, count| }
> if result_list
> record = FeedRecord.new(result_list)
> puts record.code
> end
> }
>
> # handle used to request for a feed
> handle = FeedLibrary::log_on("user", "password")
>
> session = get_live_feed(handle, FEED_CALLBACK)
>
> # my attempt to keep this running and waiting on the callback:
> while true
>
> end

No need to be uncivilised ;) Idiomatic Ruby for an endless loop is
better expressed as:

loop do
end

although that shouldn't make any difference to your program.

> Here's one I tried. Been playing around with different approaches.
> With
> this method I noticed I always get the cross-thread violation when I
> use
> the FeedRecord structure. If I don't use the structure and do
> something
> else like using the struct! method I'm able to get away with the
> callback being performed a couple of times then it eventually leads
> to a
> cross-thread violation.


Does get_live_feed use a separate thread internally? If so the cross-
thread violation could well be related to garbage collection of the
callback in which case you may need a separate callback instance for
each feed handle. Also I note that you're using a constant to hold the
callback, have you tried using a variable instead? Try turning off
garbage collection altogether and see whether that affects the errors
you receive. I've had some very amusing results doing that with DL
callbacks :)


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
----
raise ArgumentError unless @reality.responds_to? :reason


From: Gin Mendi on
Eleanor McHugh wrote:
> No need to be uncivilised ;) Idiomatic Ruby for an endless loop is
> better expressed as:
>
> loop do
> end
>

sweet thanks! Still trying to get a hang of ruby so tips like this are
great for me ;)

>
> Does get_live_feed use a separate thread internally? If so the cross-
> thread violation could well be related to garbage collection of the
> callback in which case you may need a separate callback instance for
> each feed handle. Also I note that you're using a constant to hold the
> callback, have you tried using a variable instead? Try turning off
> garbage collection altogether and see whether that affects the errors
> you receive. I've had some very amusing results doing that with DL
> callbacks :)
>

I'm unsure if get_live_feed uses a seperate thread. I just have the dll
and no source. If get_live_feed does use a seperate thread how would I
make a seperate feed handle? Does that mean I need to declare a new
callback and pass that each time I call live feed?

I tried using a variable but I still get the cross-thread violation. I
noticed though if I do not use the structure and use other methods to
display the data in the pointer I get more calls out of the callback
before I hit the cross-thread violation. Just wondering was it wrong to
use a constant for the callback?

I did some research on garbage collection. Is turning off garbage
collection simply GC.disable? If I do disable garbage collection does
that mean I have to run the free method on my pointers or put some extra
code to free up memory?

Thanks again for all the help :)
--
Posted via http://www.ruby-forum.com/.

From: Eleanor McHugh on
On 5 Sep 2009, at 17:07, Gin Mendi wrote:
> Eleanor McHugh wrote:
>> loop do
>> end
>
> sweet thanks! Still trying to get a hang of ruby so tips like this are
> great for me ;)

I've been using Ruby for eight years now and I still find new ways of
expressing myself - it's a rich language :)

> I'm unsure if get_live_feed uses a seperate thread. I just have the
> dll
> and no source. If get_live_feed does use a seperate thread how would I
> make a seperate feed handle? Does that mean I need to declare a new
> callback and pass that each time I call live feed?

Not necessarily, but it's certainly an experiment I'd consider as part
of taming the problem. If you know C reasonably well I also recommend
taking a peak through /ext/dl in the Ruby sources. That's not for the
faint-hearted though.

> I tried using a variable but I still get the cross-thread violation. I
> noticed though if I do not use the structure and use other methods to
> display the data in the pointer I get more calls out of the callback
> before I hit the cross-thread violation. Just wondering was it wrong
> to
> use a constant for the callback?

It's best not to use a constant unless the object it refers to is
intended to last for the lifetime of the program. For one thing
constants in Ruby won't prevent assignment, nor are the objects they
refer to proof against state changes. If you really want constant
behaviour in some sense you need to freeze the object in question.

I'm uncertain whether this has any bearing on your particular callback
problem, but freezing the callback object would be yet another
diagnostic tool worth trying as any subsequent attempt to modify it
would raise an exception.

> I did some research on garbage collection. Is turning off garbage
> collection simply GC.disable? If I do disable garbage collection does
> that mean I have to run the free method on my pointers or put some
> extra
> code to free up memory?

No, it just means that while garbage collection is disabled your
unreferenced objects will remain in memory. Once you reenable it all
those dead objects will then be dealt with during the next collection
cycle, including freeing up any memory associated with DataPtr objects
you may have created with DL::malloc.

> Thanks again for all the help :)

That's what we're here for :)


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
----
raise ArgumentError unless @reality.responds_to? :reason


From: Gin Mendi on
Eleanor McHugh wrote:
>> I'm unsure if get_live_feed uses a seperate thread. I just have the
>> dll
>> and no source. If get_live_feed does use a seperate thread how would I
>> make a seperate feed handle? Does that mean I need to declare a new
>> callback and pass that each time I call live feed?
>
> Not necessarily, but it's certainly an experiment I'd consider as part
> of taming the problem. If you know C reasonably well I also recommend
> taking a peak through /ext/dl in the Ruby sources. That's not for the
> faint-hearted though.

I'm only learning C now as I was trying to look at the source code. At
first glance I couldn't understand anything there but I'll study it if I
run out of ideas. Anything in particular that I should study?

> No, it just means that while garbage collection is disabled your
> unreferenced objects will remain in memory. Once you reenable it all
> those dead objects will then be dealt with during the next collection
> cycle, including freeing up any memory associated with DataPtr objects
> you may have created with DL::malloc.

what about the pointers in the callback will those remain unreferrenced
or are they automatically freed when the callback ends?

Well I tried disabling GC as you suggested but I got the same result.
Here's what I did:

require 'feed_library'

module live_feed

# my callback for the live feed
fc = DL.callback('0PL') { |result_list, count| }
if result_list
record = FeedRecord.new(result_list)
puts record.code
end
}

# handle used to request for a feed
handle = FeedLibrary::log_on("user", "password")

if handle
GC.disable

session = get_live_feed(handle, fc)

loop do
end

GC.enable
end

end

I still got the cross-thread violation on rb_thread_schedule()

I tried changing the callback. Instead of using the struct class
FeedRecord I instead used the struct! method. So I made it simple just
to access 3 fields from the data structure:

fc = DL.callback('0PL') { |result_list, count| }
if result_list
result_list.struct('C16FF', :code, :value, :stat)
puts result_list[:code].pack('C16')
puts result_list[:value]
end
}

I instead got a crash where I would see the printout of the callback
with mixed in letters forming segmentation fault. Other runs would just
flat out crash back to the command prompt.
--
Posted via http://www.ruby-forum.com/.