Re: idiom for cleanup + abort

From: Dennis Ruffer <druffer_at_worldnet.att.net>
Date: Fri, 30 Jan 2009 21:36:49 -0600

On Fri, Jan 30, 2009 at 8:27 PM, Elizabeth D Rather <erather_at_forth.com> wrote:
> Joel Reymont wrote:
>>
>> I'm trying to port C code that looks like this
>>
>> // This consumes a reference on dictRef.
>> kr = IOServiceGetMatchingServices(kIOMasterPortDefault, dictRef,
>> &iter);
>> if (KERN_SUCCESS != kr) {
>> fprintf(stderr, "IOServiceGetMatchingServices returned 0x%08x.\n",
>> kr);
>> CFRelease(dictRef);
>> return -1;
>> }
>>
>> This is for the Forth side of the Mac driver code for the IntellaSys
>> FORTHdrive [1] that I'm testing at the moment.
>>
>> My current Forth code looks like this:
>>
>> : LOOKUP-BLOCK-STORAGE-NUB ( -- svc | )
>> \ IOBlockStorageServices is our child in the I/O registry
>> ZSTR "IOBlockStorageServices" IOServiceMatching ( dictRef *)
>> ?DUP 0= ABORT" IOServiceMatching did not return a dictionary"
>> \ create an iterator over all matching IOService nubs
>> kIOMasterPortDefault OVER ITERATOR IOServiceGetMatchingServices
>> ABORT" IOServiceGetMatchingServices failed"
>> ...
>>
>> Obviously, this won't work since it will leave the dictRef hanging! I'd
>> like to create a wrapper around ABORT" but would appreciate advice (or
>> code!) since the implementation of ABORT" in SwiftForth is a bit over my
>> head :).
>>
> "Hanging" where? If ABORT" fires, it'll clear the stack.

Oops, sorry. I meant to answer Joel, but got busy watching a movie. ;)

The problem, Elizabeth, is that dictRef is a pointer to an OS resource
that needs to be release, not just discarded.

I wish I had backed up the code I was working on before my Mac died,
cause I had this part of it all working.

Joel, you have to factor the definitions so that the things that can
abort are buried within a catch frame. Then, when the catch returns,
by the called routine aborting, or not, you can release the dictRef.
This is a little conter intuative, and doesn't fit well with how
IntellaSys is using the results, but it is the "right" thing to do. ;)

So, your 1st abort can stay in the outer definition, cause you don't
have a dictRef at that point.

Put everything after the 1st abort into another definition and call it
like this:

    ['] funcName CATCH

As long as you are not trying to pass something to that definition,
you can probably just release the dictRef and then THROW the result of
the CATCH. Otherwise, you have to discard the number of stack items
within a DUP IF ... THEN phrase, making sure you preserve the TOS for
the THROW. If this isn't confusing enough, let me know if you are
still confused and I'll try to see if I can dig up, or recreate an
example for you.

DaR
----------------------------------------------------------------------
sftalk_at_forth.com The SwiftForth programming discussion email list
To unsubscribe, send subject "unsubscribe" to sftalk-request_at_forth.com
For list command help, send subject "help" to sftalk-request_at_forth.com
Message archives are located at http://www.forth.com/archive/sftalk
----------------------------------------------------------------------
This list is a forum for SwiftForth users. For product support and
bug reports, please send email to support_at_forth.com
----------------------------------------------------------------------
Received on Fri Jan 30 2009 - 19:37:14 PST


Subscribe to our e-mail list service. It's free for all SwiftForth and SwiftX users!

This archive was generated 03-Feb-2012. Archive updated nightly.