Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 138980 - kde-functions.eclass: is-parent-package doesn't work; get-parent-package can cause pipe fail warning
Summary: kde-functions.eclass: is-parent-package doesn't work; get-parent-package can ...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] KDE (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: Gentoo KDE team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-07-03 03:41 UTC by Kevin F. Quinn (RETIRED)
Modified: 2006-07-03 06:07 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments
Reimplementation of get-parent-package, get-child-packages and is-parent-package using HERE docs (kde-functions.eclass.diff,1.61 KB, patch)
2006-07-03 03:47 UTC, Kevin F. Quinn (RETIRED)
Details | Diff
test script illustrating speed of various methods (kde-functions.sh,16.62 KB, text/plain)
2006-07-03 03:51 UTC, Kevin F. Quinn (RETIRED)
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kevin F. Quinn (RETIRED) gentoo-dev 2006-07-03 03:41:23 UTC
The use of subshells in get-parent-package, get-child-packages and is-parent-package is inadvisable (i.e. the "echo | while" structure).

This:

get-parent-package () {
    local target=$1 parent child
    echo "$KDE_DERIVATION_MAP" | while read parent child; do
        if [ "$target" == "$child" ]; then
            echo $parent
            return 1
        fi
    done
    [ "$?" == "0" ] && die "Package $target not found in KDE_DERIVATION_MAP, please report bug"
}

can generate warnings about pipe closure, when the while loop terminates before the echo has finished (it's a race, so doesn't always occur).  Note the tricks necessary with the return code to deal with that.

is-parent-package() {
    echo "$KDE_DERIVATION_MAP" | while read parent child; do
        [[ "${parent}" == "$1" ]] && return 1
    done
    return 0
}

fails because the "return 1" is in a subshell it does not set the return code of the function.  Also, if the function is to be used in an if statement (as appears to be the case); e.g.

    if is-parent-package $pkg}; then

it needs to return 0 for true and 1 for false.

In general, it's best to avoid using a pipe to do this sort of thing; not only is it slower as it spawns a sub-process, but variable assignments etc in the subshell are not reflected in the caller - it's easy to forget that the while loop is a subshell.  There are several ways to avoid them; the easiest is to use HERE docs.  I'll attach an example re-implementation of these functions using HERE docs that improves performance by 35% or more.


One other comment on the eclass in general; using '[' is a little slower than '[[', because it means forking a call to '['.  '[...]' can be exchanged for '[[...]]' everywhere in eclasses (some conditions may need to be modified for bash syntax, and quoting is not necessary with '[[') - this should yield a performance benefit.
Comment 1 Kevin F. Quinn (RETIRED) gentoo-dev 2006-07-03 03:47:17 UTC
Created attachment 90758 [details, diff]
Reimplementation of get-parent-package, get-child-packages and is-parent-package using HERE docs
Comment 2 Kevin F. Quinn (RETIRED) gentoo-dev 2006-07-03 03:51:54 UTC
Created attachment 90759 [details]
test script illustrating speed of various methods

For interest, here's a shell script I used to try a 'for' loop variant and the HERE doc variant, to get timing information and to test that the functions behave the way they should in comparison with the originals (aside from bugs in the originals).
Comment 3 Caleb Tennis (RETIRED) gentoo-dev 2006-07-03 05:09:09 UTC
Kev,

I'm all for you committing these changes if you're happy with them.
Comment 4 Kevin F. Quinn (RETIRED) gentoo-dev 2006-07-03 06:07:12 UTC
ok; committed :)

(for the record, the thing I said about '[' vs '[[' is not true, as '[' is a bash builtin)