The usage mutexes are needed for existing ruby/perl/python bindings,
all of which have chosen to implement fragile (and unmaintainable imho,
caveat emptor) methods onto -lrpmbuild.
In order to add usage mutexes to Spec and Packages through memory
pools, I am introducing some modest memory leaks that hardly
mayyer, but will be visible with valgrind:
D: pool spec: created size 176 limit -1 flags -1
D: pool h: created size 212 limit -1 flags 0
--> spec 0x900f370 ++ 1 newSpec at spec.c:806
D: pool pkg: created size 84 limit -1 flags -1
--> pkg 0x90106e0 ++ 1 newPackage at spec.c:261
Note the sizes please, perhaps 1K will be leaked while exit'ing until I
create a place where the _specPool and _pkgPool can
be discarded.
*shrug*
73 de Jeff
On May 24, 2009, at 3:45 PM, Jeff Johnson wrote:
> RPM Package Manager, CVS Repository
> http://rpm5.org/cvs/
>
> ____________________________________________________________________________
>
> Server: rpm5.org Name: Jeff Johnson
> Root: /v/rpm/cvs Email: jbj@rpm5.org
> Module: rpm Date: 24-May-2009 21:45:26
> Branch: HEAD Handle: 2009052419452501
>
> Modified files:
> rpm CHANGES
> rpm/build poptBT.c rpmspec.h spec.c
>
> Log:
> - yarn: convert Package to usage mutex with refcounts.
> - yarn: convert Spec to usage mutex with refcounts.
>
> Summary:
> Revision Changes Path
> 1.2993 +2 -0 rpm/CHANGES
> 2.30 +10 -0 rpm/build/poptBT.c
> 2.80 +2 -0 rpm/build/rpmspec.h
> 2.200 +229 -86 rpm/build/spec.c
>
> ____________________________________________________________________________
>
> patch -p0 <<'@@ .'
> Index: rpm/CHANGES
>
> =
> =
> =
> =
> =
> =
> ======================================================================
> $ cvs diff -u -r1.2992 -r1.2993 CHANGES
> --- rpm/CHANGES 24 May 2009 18:36:10 -0000 1.2992
> +++ rpm/CHANGES 24 May 2009 19:45:25 -0000 1.2993
> @@ -1,5 +1,7 @@
>
> 5.2b1 -> 5.3a1
> + - jbj: yarn: convert Package to usage mutex with refcounts.
> + - jbj: yarn: convert Spec to usage mutex with refcounts.
> - jbj: yarn: convert DIGEST_CTX to usage mutex with refcounts.
> - jbj: eliminate (unused) DB_DBT_MALLOC flag while loading
> rpmdb headers.
> - jbj: bump sonames to libfoo-5.2.
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/build/poptBT.c
>
> =
> =
> =
> =
> =
> =
> ======================================================================
> $ cvs diff -u -r2.29 -r2.30 poptBT.c
> --- rpm/build/poptBT.c 31 Jul 2008 00:21:39 -0000 2.29
> +++ rpm/build/poptBT.c 24 May 2009 19:45:26 -0000 2.30
> @@ -21,6 +21,11 @@
> #include "debug.h"
>
> /*@unchecked@*/
> +extern int _pkg_debug;
> +/*@unchecked@*/
> +extern int _spec_debug;
> +
> +/*@unchecked@*/
> struct rpmBuildArguments_s rpmBTArgs;
>
> #define POPT_USECATALOG -1011
> @@ -218,6 +223,11 @@
> { "nosignature", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL,
> RPMCLI_POPT_NOSIGNATURE,
> N_("don't verify package signature(s)"), NULL },
>
> + { "pkgdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN,
> &_pkg_debug, -1,
> + N_("Debug Package objects"), NULL},
> + { "specdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN,
> &_spec_debug, -1,
> + N_("Debug Spec objects"), NULL},
> +
> { "nolang", '\0', POPT_ARGFLAG_DOC_HIDDEN, &noLang, POPT_NOLANG,
> N_("do not accept i18n msgstr's from specfile"), NULL},
> { "rmsource", '\0', 0, NULL, POPT_RMSOURCE,
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/build/rpmspec.h
>
> =
> =
> =
> =
> =
> =
> ======================================================================
> $ cvs diff -u -r2.79 -r2.80 rpmspec.h
> --- rpm/build/rpmspec.h 6 Apr 2009 00:21:21 -0000 2.79
> +++ rpm/build/rpmspec.h 24 May 2009 19:45:26 -0000 2.80
> @@ -104,6 +104,7 @@
> * The structure used to store values parsed from a spec file.
> */
> struct Spec_s {
> + struct rpmioItem_s _item; /*!< usage mutex and pool
> identifier. */
> /*@only@*/
> const char * specFile; /*!< Name of the spec file. */
> /*@only@*/
> @@ -194,6 +195,7 @@
> * The structure used to store values for a package.
> */
> struct Package_s {
> + struct rpmioItem_s _item; /*!< usage mutex and pool
> identifier. */
> /*@refcounted@*/
> Header header;
> /*@refcounted@*/
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/build/spec.c
>
> =
> =
> =
> =
> =
> =
> ======================================================================
> $ cvs diff -u -r2.199 -r2.200 spec.c
> --- rpm/build/spec.c 26 Mar 2009 20:09:01 -0000 2.199
> +++ rpm/build/spec.c 24 May 2009 19:45:26 -0000 2.200
> @@ -17,6 +17,12 @@
>
> #include "debug.h"
>
> +/*@unchecked@*/
> +int _pkg_debug;
> +
> +/*@unchecked@*/
> +int _spec_debug;
> +
> /*@-redecl@*/
> extern int specedit;
> /*@=redecl@*/
> @@ -141,48 +147,44 @@
> return ((lastp == NULL) ? RPMRC_FAIL : RPMRC_OK);
> }
>
> -Package newPackage(/*@unused@*/ Spec spec)
> +Package freePackage(Package pkg)
> {
> - Package p;
> -
> - p = xcalloc(1, sizeof(*p));
> -
> - p->header = headerNew();
> - p->ds = NULL;
> -
> - p->autoProv = ((_rpmbuildFlags & 0x1) != 0);
> - p->autoReq = ((_rpmbuildFlags & 0x2) != 0);
> -
> -#if 0
> - p->reqProv = NULL;
> - p->triggers = NULL;
> - p->triggerScripts = NULL;
> -#endif
> -
> - p->triggerFiles = NULL;
> +#ifdef DYING
> + if (pkg == NULL) return NULL;
>
> - p->fileFile = NULL;
> - p->fileList = NULL;
> -
> - p->cpioList = NULL;
> -
> - p->preInFile = NULL;
> - p->postInFile = NULL;
> - p->preUnFile = NULL;
> - p->postUnFile = NULL;
> - p->verifyFile = NULL;
> - p->sanityCheckFile = NULL;
> + pkg->preInFile = _free(pkg->preInFile);
> + pkg->postInFile = _free(pkg->postInFile);
> + pkg->preUnFile = _free(pkg->preUnFile);
> + pkg->postUnFile = _free(pkg->postUnFile);
> + pkg->verifyFile = _free(pkg->verifyFile);
> + pkg->sanityCheckFile = _free(pkg->sanityCheckFile);
>
> - p->specialDoc = NULL;
> + (void)headerFree(pkg->header);
> + pkg->header = NULL;
> + (void)rpmdsFree(pkg->ds);
> + pkg->ds = NULL;
> + pkg->fileList = rpmiobFree(pkg->fileList);
> + pkg->fileFile = _free(pkg->fileFile);
> + if (pkg->cpioList != NULL) {
> + rpmfi fi = pkg->cpioList;
> + pkg->cpioList = NULL;
> + fi = rpmfiFree(fi);
> + }
>
> - p->next = NULL;
> + pkg->specialDoc = rpmiobFree(pkg->specialDoc);
> + pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
> +#endif
>
> - return p;
> + (void)rpmioFreePoolItem((rpmioItem)pkg, __FUNCTION__,
> __FILE__, __LINE__);
> + return NULL;
> }
>
> -Package freePackage(Package pkg)
> +static void pkgFini(void * _pkg)
> + /*@modifies _pkg @*/
> {
> - if (pkg == NULL) return NULL;
> + Package pkg = _pkg;
> +
> + if (pkg == NULL) return; /* XXX assert? */
>
> pkg->preInFile = _free(pkg->preInFile);
> pkg->postInFile = _free(pkg->postInFile);
> @@ -205,9 +207,58 @@
>
> pkg->specialDoc = rpmiobFree(pkg->specialDoc);
> pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
> +}
>
> - pkg = _free(pkg);
> - return NULL;
> +/*@unchecked@*/ /*@only@*/ /*@null@*/
> +rpmioPool _pkgPool;
> +
> +static Package pkgGetPool(rpmioPool pool)
> +{
> + Package pkg;
> +
> + if (_pkgPool == NULL) {
> + _pkgPool = rpmioNewPool("pkg", sizeof(*pkg), -1, _pkg_debug,
> + NULL, NULL, pkgFini);
> + pool = _pkgPool;
> + }
> + return (Package) rpmioGetPool(pool, sizeof(*pkg));
> +}
> +
> +Package newPackage(/*@unused@*/ Spec spec)
> +{
> + Package pkg = pkgGetPool(_pkgPool);
> +
> + pkg->header = headerNew();
> + pkg->ds = NULL;
> +
> + pkg->autoProv = ((_rpmbuildFlags & 0x1) != 0);
> + pkg->autoReq = ((_rpmbuildFlags & 0x2) != 0);
> +
> +#if 0
> + pkg->reqProv = NULL;
> + pkg->triggers = NULL;
> + pkg->triggerScripts = NULL;
> +#endif
> +
> + pkg->triggerFiles = NULL;
> +
> + pkg->fileFile = NULL;
> + pkg->fileList = NULL;
> +
> + pkg->cpioList = NULL;
> +
> + pkg->preInFile = NULL;
> + pkg->postInFile = NULL;
> + pkg->preUnFile = NULL;
> + pkg->postUnFile = NULL;
> + pkg->verifyFile = NULL;
> + pkg->sanityCheckFile = NULL;
> +
> + pkg->specialDoc = NULL;
> +
> + pkg->next = NULL;
> +
> + return (Package)rpmioLinkPoolItem((rpmioItem)pkg,
> __FUNCTION__, __FILE__, __LINE__);
> }
>
> Package freePackages(Package packages)
> @@ -526,72 +577,91 @@
> return _free(st);
> }
>
> -Spec newSpec(void)
> +Spec freeSpec(Spec spec)
> {
> - Spec spec = xcalloc(1, sizeof(*spec));
> -
> - spec->specFile = NULL;
> +#ifdef DYING
> + struct ReadLevelEntry *rl;
>
> - spec->sl = newSl();
> - spec->st = newSt();
> + if (spec == NULL) return NULL;
>
> - spec->fileStack = NULL;
> - spec->lbuf_len = (size_t)rpmExpandNumeric("%{?
> _spec_line_buffer_size}%{!?_spec_line_buffer_size:100000}");
> - spec->lbuf = (char *)xcalloc(1, spec->lbuf_len);
> - spec->line = spec->lbuf;
> - spec->nextline = NULL;
> - spec->nextpeekc = '\0';
> - spec->lineNum = 0;
> - spec->readStack = xcalloc(1, sizeof(*spec->readStack));
> - spec->readStack->next = NULL;
> - spec->readStack->reading = 1;
> + spec->lbuf = _free(spec->lbuf);
>
> - spec->rootURL = NULL;
> - spec->prep = NULL;
> - spec->build = NULL;
> - spec->install = NULL;
> - spec->check = NULL;
> - spec->clean = NULL;
> - spec->foo = NULL;
> + spec->sl = freeSl(spec->sl);
> + spec->st = freeSt(spec->st);
> +
> + spec->prep = rpmiobFree(spec->prep);
> + spec->build = rpmiobFree(spec->build);
> + spec->install = rpmiobFree(spec->install);
> + spec->check = rpmiobFree(spec->check);
> + spec->clean = rpmiobFree(spec->clean);
> + spec->foo = tagStoreFree(spec->foo, spec->nfoo);
> spec->nfoo = 0;
>
> - spec->sources = NULL;
> - spec->packages = NULL;
> - spec->noSource = 0;
> - spec->numSources = 0;
> + spec->buildSubdir = _free(spec->buildSubdir);
> + spec->rootURL = _free(spec->rootURL);
> + spec->specFile = _free(spec->specFile);
>
> - spec->sourceRpmName = NULL;
> - spec->sourcePkgId = NULL;
> - spec->sourceHeader = headerNew();
> - spec->sourceCpioList = NULL;
> -
> - spec->buildSubdir = NULL;
> + closeSpec(spec);
>
> - spec->passPhrase = NULL;
> - spec->timeCheck = 0;
> - spec->cookie = NULL;
> + while (spec->readStack) {
> + rl = spec->readStack;
> + /*@-dependenttrans@*/
> + spec->readStack = rl->next;
> + /*@=dependenttrans@*/
> + rl->next = NULL;
> + rl = _free(rl);
> + }
> +
> + spec->sourceRpmName = _free(spec->sourceRpmName);
> + spec->sourcePkgId = _free(spec->sourcePkgId);
> + spec->sourceHeader = headerFree(spec->sourceHeader);
>
> - spec->BANames = NULL;
> - spec->BACount = 0;
> - spec->recursing = 0;
> - spec->toplevel = 1;
> - spec->BASpecs = NULL;
> + if (spec->sourceCpioList != NULL) {
> + rpmfi fi = spec->sourceCpioList;
> + spec->sourceCpioList = NULL;
> + fi = rpmfiFree(fi);
> + }
> +
> + if (!spec->recursing) {
> + if (spec->BASpecs != NULL)
> + while (spec->BACount--) {
> + /*@-unqualifiedtrans@*/
> + spec->BASpecs[spec->BACount] =
> + freeSpec(spec->BASpecs[spec->BACount]);
> + /*@=unqualifiedtrans@*/
> + }
> + /*@-compdef@*/
> + spec->BASpecs = _free(spec->BASpecs);
> + /*@=compdef@*/
> + }
> + spec->BANames = _free(spec->BANames);
>
> - spec->force = 0;
> - spec->anyarch = 0;
> + spec->passPhrase = _free(spec->passPhrase);
> + spec->cookie = _free(spec->cookie);
>
> -/*@i@*/ spec->macros = rpmGlobalMacroContext;
> +#ifdef WITH_LUA
> + { rpmlua lua = NULL; /* global state */
> + rpmluaDelVar(lua, "patches");
> + rpmluaDelVar(lua, "sources");
> + }
> +#endif
>
> - spec->_parseRCPOT = parseRCPOT; /* XXX hack around backward
> linkage. */
> + spec->sources = freeSources(spec->sources);
> + spec->packages = freePackages(spec->packages);
> +#endif
>
> - return spec;
> + (void)rpmioFreePoolItem((rpmioItem)spec, __FUNCTION__,
> __FILE__, __LINE__);
> +
> + return NULL;
> }
>
> -Spec freeSpec(Spec spec)
> +static void specFini(void * _spec)
> + /*@modifies _spec @*/
> {
> + Spec spec = _spec;
> struct ReadLevelEntry *rl;
>
> - if (spec == NULL) return NULL;
> + if (spec == NULL) return; /* XXX assert? */
>
> spec->lbuf = _free(spec->lbuf);
>
> @@ -658,9 +728,82 @@
> spec->sources = freeSources(spec->sources);
> spec->packages = freePackages(spec->packages);
>
> - spec = _free(spec);
> +}
> +
> +/*@unchecked@*/ /*@only@*/ /*@null@*/
> +rpmioPool _specPool;
> +
> +static Spec specGetPool(rpmioPool pool)
> +{
> + Spec spec;
> +
> + if (_specPool == NULL) {
> + _specPool = rpmioNewPool("spec", sizeof(*spec), -1, _spec_debug,
> + NULL, NULL, specFini);
> + pool = _specPool;
> + }
> + return (Spec) rpmioGetPool(pool, sizeof(*spec));
> +}
> +
> +Spec newSpec(void)
> +{
> + Spec spec = specGetPool(_specPool);
> +
> + spec->specFile = NULL;
> +
> + spec->sl = newSl();
> + spec->st = newSt();
> +
> + spec->fileStack = NULL;
> + spec->lbuf_len = (size_t)rpmExpandNumeric("%{?
> _spec_line_buffer_size}%{!?_spec_line_buffer_size:100000}");
> + spec->lbuf = (char *)xcalloc(1, spec->lbuf_len);
> + spec->line = spec->lbuf;
> + spec->nextline = NULL;
> + spec->nextpeekc = '\0';
> + spec->lineNum = 0;
> + spec->readStack = xcalloc(1, sizeof(*spec->readStack));
> + spec->readStack->next = NULL;
> + spec->readStack->reading = 1;
> +
> + spec->rootURL = NULL;
> + spec->prep = NULL;
> + spec->build = NULL;
> + spec->install = NULL;
> + spec->check = NULL;
> + spec->clean = NULL;
> + spec->foo = NULL;
> + spec->nfoo = 0;
>
> - return spec;
> + spec->sources = NULL;
> + spec->packages = NULL;
> + spec->noSource = 0;
> + spec->numSources = 0;
> +
> + spec->sourceRpmName = NULL;
> + spec->sourcePkgId = NULL;
> + spec->sourceHeader = headerNew();
> + spec->sourceCpioList = NULL;
> +
> + spec->buildSubdir = NULL;
> +
> + spec->passPhrase = NULL;
> + spec->timeCheck = 0;
> + spec->cookie = NULL;
> +
> + spec->BANames = NULL;
> + spec->BACount = 0;
> + spec->recursing = 0;
> + spec->toplevel = 1;
> + spec->BASpecs = NULL;
> +
> + spec->force = 0;
> + spec->anyarch = 0;
> +
> +/*@i@*/ spec->macros = rpmGlobalMacroContext;
> +
> + spec->_parseRCPOT = parseRCPOT; /* XXX hack around backward
> linkage. */
> +
> + return (Spec)rpmioLinkPoolItem((rpmioItem)spec, __FUNCTION__,
> __FILE__, __LINE__);
> }
>
> /*@only@*/
> @@ .
> ______________________________________________________________________
> RPM Package Manager http://rpm5.org
> CVS Sources Repository rpm-cvs@rpm5.org
Received on Sun May 24 21:52:19 2009