[syslinux] [PATCH 2/4] chain.c: gpt's index/private.index mismatchfix, cosmetic iterator changes

Michal Soltys soltys at ziu.info
Tue Jul 27 16:57:32 PDT 2010


On 10-07-27 15:58, Miller, Shao wrote:
>
> Ok, I think it's just a difference in preference, then.  I think H.
> Peter has even expressed that it's not all that important to free() near
> a module-exit condition in these COMBOOT32 modules at this time. :)  I
> might have misunderstood him, however.
>

I don't really know that :) I haven't peeked inside syslinux that far 
yet. But my general approach to [de]allocation is to either do all of 
it, or not do it at all. If we do some, but skip the rest because it's 
not really important in the end and/or a bit inconvenient along the way 
- then it's just wrong, imho.

> In the original code:
> -----
>      return part;
>
> err_insane:
>
>      free(part->block);
>      part->block = NULL;
> err_ebr:
>
> out_finished:
>      free(part->private.ebr.parent->block);
>      free(part->private.ebr.parent);
>      free(part->block);
>      free(part);
>      return NULL;
> -----
> Essentially what I'm trying to do is say "this is what it means to clean
> up after an error" with the fall-through labels for erroring-out.
> You'll see that the error labels are lumped together underneath whatever
> their subject is.  The 'out' is, like you said, "nothing more to
> iterate," which is a condition we reach either due to an error, or due
> to an end condition.  That's why 'out_finished' is reached by the error
> unwinding.  The 'out_finished' is lumped together above its clean-up
> subject(s).
>

Yea, I know what you mean. I think.

  - alloc some "a"
  - bail on error to a:
  - alloc some "b"
  - bail on error to b:
...
  - something
    return [eventually]
...
b:
  - dealloc b
a:
  - dealloc a
  - return with error

get_first_partition() follows it to the letter +/-, similary 
next_mbr_part (besides that unreachable call). There's nothing wrong 
though with e.g. shifting "dealloc b" under a:, as long as we're 
properly guarded (or better, if it's simple enough to be bundled into 
one logical function, etc.)

(( theoretizing, I really prefer variable+single jump approach - even if 
for the sole reason that unwinding "linearly" is not always valid ))

But in ebr iterator, we already have everything possible allocated at 
the very beginning of the function, which generally comes down (in this 
case) to

err_insane:
err_ebr:
out_finished:
	free everything and leave

Regarding earlier unreachable function - if the iterator was expanded 
one or the other way, that function could be as well not enough, or too 
much - so it would need adjusting either way.

Anyway, what about doing the following:

err_something1:
err_something2:
...etc.
	part->free(part);
	return NULL;

Where free() (similary to next()) would be specfic to the iterator or 
generic. Well, sort-of virtual destructor defacto. It wouldn't expose 
internals, it can be naturally called from other functions, documentary 
value of different labels is kept (and comments can add more details).

Of course - I'm fine with either approach. It's a small detail after all.

Anyway, I'll prep the patches (I think 2 - one for iterator and 
allocation related things, the other for actual functionality). I have 
some extra ideas too. Feel free to adjust the patches afterwards.

> I think that you are suggesting that the code be rebalanced regarding
> the trade-off between "documenting what constitutes clean-up for what
> condition" versus "we know what needs cleaning up in any case across
> these functions, so do it in one place."  That's ok, but now your
> 'free_iter()' includes an explicit test for (and therefore has knowledge
> about) EBR iterators, rather than that knowledge being packed inside the
> EBR iteration function.  If we had more different kinds of iterators,
> free_iter() would start to fill up with more cases to consider.  We
> aren't likely to have more cases soon, so I really don't mind agreeing
> to the rebalancing you propose. :)  That was my rationale.
>

Well, it's true - I agree it's not pretty. But analogous thing is done 
in find_by_label or when handover area is created - peek inside 
interator's internals to check if it's perhaps a gpt one. Or when mbr 
iterator knows how to allocate and initalize ebr iterator. Well, 
regarding free_iter - mentioned above iterator-dependent free() should 
do the thing elegantly.

Maybe some simple function/variable reporting iterator type should be 
added ?





More information about the Syslinux mailing list