From: Eleanor McHugh on
On 8 Sep 2009, at 05:09, Gin Mendi wrote:
> 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?

If C is a new language to you then the Ruby sources are definitely not
the place to learn it.

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

They should also be freed. There are caveats and edge cases where this
might not be the case, but based on the code you've posted none of
those seem to apply.

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

Are you certain that in the case of no feed being available, you're
receiving a nil rather than a zero? Because if not then the following
condition will always be true and then there'll be times when you try
and access a non-existent feed.

> 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.


You could try installing Tenderlove's Never Say Die library from
github, it allows you to rescue segfaults which might allow you to
extract some useful program state or else continue as if nothing had
gone wrong (but that's a really bad idea in the majority of cases).

You might also try coding your wrapper with ruby-ffi rather than ruby/
dl.


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:
> Are you certain that in the case of no feed being available, you're
> receiving a nil rather than a zero? Because if not then the following
> condition will always be true and then there'll be times when you try
> and access a non-existent feed.

Yep handle will be nil if log_on fails or encounters an error.

>
> You could try installing Tenderlove's Never Say Die library from
> github, it allows you to rescue segfaults which might allow you to
> extract some useful program state or else continue as if nothing had
> gone wrong (but that's a really bad idea in the majority of cases).
>
> You might also try coding your wrapper with ruby-ffi rather than ruby/
> dl.
>

Ok I'll try looking and studying both of those suggestions. Might take a
while for me to redo with ffi but I'll post back here what the results
were.

You mentioned earlier that I may need a separate callback instance for
each feed handle:

> 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.

Sorry but I don't fully understand how I could go about doing this? How
would this work?

Also a little side problem I still haven't solved regarding my callback:

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
}

you'll notice I have a count parameter which is the number of records in
result_list. I assume result list is an array if count > 1. Been trying
to figure out how to extract each record if count > 1. Right now only
managed to do this with just one record as you can see. How could I
convert my pointer to an array then get each element/record? I'm
assuming result_list is an array. I tried result_list.ptr.to_a but that
just made the program crash back to the command prompt with no error.

Anyway thanks again for all the help!
--
Posted via http://www.ruby-forum.com/.