From: Eleanor McHugh on 8 Sep 2009 07:28 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 8 Sep 2009 23:04
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/. |