summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2012-09-12 13:37:54 +0300
committerPanu Matilainen <pmatilai@redhat.com>2012-09-12 13:37:54 +0300
commita3bb7f59a7a3b75d2d13029e8a47b700bf8634dd (patch)
tree894986900d030ae016799db868bba9f6dd282d06
parent3226c2073a71818ab45de6784840ccdc28d07b46 (diff)
downloadlibrpm-tizen-a3bb7f59a7a3b75d2d13029e8a47b700bf8634dd.tar.gz
librpm-tizen-a3bb7f59a7a3b75d2d13029e8a47b700bf8634dd.tar.bz2
librpm-tizen-a3bb7f59a7a3b75d2d13029e8a47b700bf8634dd.zip
Add infastructure for global transaction set string pool
- Add a pool pointer to to ts members struct and a getter function - Grab the global pool for rpmte dependency- and file info creation, if its NULL then the sets will use private pools of their own. - Add the (currently) required magic voodoo rain-dance to freeze and unfreeze the pool as necessary wrt new element additions: for current rpmal and fingerprinting to work, the string pointers must be immovable. - This is infrastructure only: nothing creates the global pool yet, so everything is still using private pools.
-rw-r--r--lib/depends.c11
-rw-r--r--lib/rpmte.c14
-rw-r--r--lib/rpmts.c9
-rw-r--r--lib/rpmts.h7
-rw-r--r--lib/rpmts_internal.h2
-rw-r--r--lib/transaction.c10
6 files changed, 46 insertions, 7 deletions
diff --git a/lib/depends.c b/lib/depends.c
index 2ee7e0de5..e852344d3 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -101,6 +101,10 @@ static int removePackage(rpmts ts, Header h, rpmte depends)
return 0;
}
+ /* Ensure pool is writable */
+ if (tsmem->addedPackages != NULL)
+ rpmstrPoolUnfreeze(tsmem->pool);
+
p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL);
if (p == NULL)
return 1;
@@ -320,6 +324,9 @@ rpmal rpmtsCreateAl(rpmts ts, rpmElementTypes types)
rpmte p;
rpmtsi pi;
+ /* Required for now to lock string pointers in memory */
+ rpmstrPoolFreeze(rpmtsPool(ts));
+
al = rpmalCreate((rpmtsNElements(ts) / 4) + 1, rpmtsFlags(ts),
rpmtsColor(ts), rpmtsPrefColor(ts));
pi = rpmtsiInit(ts);
@@ -356,6 +363,10 @@ int rpmtsAddInstallElement(rpmts ts, Header h,
goto exit;
}
+ /* Ensure pool is writable */
+ if (tsmem->addedPackages != NULL)
+ rpmstrPoolUnfreeze(tsmem->pool);
+
p = rpmteNew(ts, h, TR_ADDED, key, relocs);
if (p == NULL) {
ec = 1;
diff --git a/lib/rpmte.c b/lib/rpmte.c
index 38a89f2df..8e8505244 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -99,7 +99,7 @@ static rpmfi getFI(rpmte p, Header h)
rpmRelocateFileList(p->relocs, p->nrelocs, p->fs, h);
}
}
- return rpmfiNew(NULL, h, RPMTAG_BASENAMES, fiflags);
+ return rpmfiNewPool(rpmtsPool(p->ts), h, RPMTAG_BASENAMES, fiflags);
}
/* stupid bubble sort, but it's probably faster here */
@@ -203,6 +203,7 @@ static void buildRelocs(rpmte p, Header h, rpmRelocation *relocs)
*/
static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
{
+ rpmstrPool tspool = rpmtsPool(p->ts);
struct rpmtd_s colls, bnames;
int rc = 1; /* assume failure */
@@ -241,12 +242,13 @@ static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
p->pkgFileSize = 0;
p->headerSize = headerSizeof(h, HEADER_MAGIC_NO);
+ /* XXX thisds not in global pool yet, but not strictly needed either */
p->thisds = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
- p->provides = rpmdsNew(h, RPMTAG_PROVIDENAME, 0);
- p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
- p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, 0);
- p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, 0);
- p->order = rpmdsNew(h, RPMTAG_ORDERNAME, 0);
+ p->provides = rpmdsNewPool(tspool, h, RPMTAG_PROVIDENAME, 0);
+ p->requires = rpmdsNewPool(tspool, h, RPMTAG_REQUIRENAME, 0);
+ p->conflicts = rpmdsNewPool(tspool, h, RPMTAG_CONFLICTNAME, 0);
+ p->obsoletes = rpmdsNewPool(tspool, h, RPMTAG_OBSOLETENAME, 0);
+ p->order = rpmdsNewPool(tspool, h, RPMTAG_ORDERNAME, 0);
/* Relocation needs to know file count before rpmfiNew() */
headerGet(h, RPMTAG_BASENAMES, &bnames, HEADERGET_MINMEM);
diff --git a/lib/rpmts.c b/lib/rpmts.c
index abf8a2bff..c8ecb9c59 100644
--- a/lib/rpmts.c
+++ b/lib/rpmts.c
@@ -584,6 +584,8 @@ void rpmtsEmpty(rpmts ts)
}
tsmem->orderCount = 0;
+ /* XXX emptying would be sufficient... */
+ tsmem->pool = rpmstrPoolFree(tsmem->pool);
removedHashEmpty(tsmem->removedPackages);
return;
}
@@ -927,6 +929,12 @@ tsMembers rpmtsMembers(rpmts ts)
return (ts != NULL) ? ts->members : NULL;
}
+rpmstrPool rpmtsPool(rpmts ts)
+{
+ tsMembers tsmem = rpmtsMembers(ts);
+ return (tsmem != NULL) ? tsmem->pool : NULL;
+}
+
rpmts rpmtsCreate(void)
{
rpmts ts;
@@ -974,6 +982,7 @@ rpmts rpmtsCreate(void)
}
tsmem = xcalloc(1, sizeof(*ts->members));
+ tsmem->pool = NULL;
tsmem->delta = 5;
tsmem->addedPackages = NULL;
tsmem->removedPackages = removedHashCreate(128, uintId, uintCmp, NULL, NULL);
diff --git a/lib/rpmts.h b/lib/rpmts.h
index 0b8d970e7..2f0dcaff8 100644
--- a/lib/rpmts.h
+++ b/lib/rpmts.h
@@ -527,6 +527,13 @@ int rpmtsSetNotifyCallback(rpmts ts,
rpmts rpmtsCreate(void);
/** \ingroup rpmts
+ * Return transaction global string pool handle
+ * @param ts transaction set
+ * @return string pool handle (weak ref)
+ */
+rpmstrPool rpmtsPool(rpmts ts);
+
+/** \ingroup rpmts
* Add package to be installed to transaction set.
*
* The transaction set is checked for duplicate package names.
diff --git a/lib/rpmts_internal.h b/lib/rpmts_internal.h
index 5d3240cf0..a9429106a 100644
--- a/lib/rpmts_internal.h
+++ b/lib/rpmts_internal.h
@@ -2,6 +2,7 @@
#define _RPMTS_INTERNAL_H
#include <rpm/rpmts.h>
+#include <rpm/rpmstrpool.h>
#include "lib/rpmal.h" /* XXX availablePackage */
#include "lib/fprint.h"
@@ -11,6 +12,7 @@ typedef struct diskspaceInfo_s * rpmDiskSpaceInfo;
/* Transaction set elements information */
typedef struct tsMembers_s {
+ rpmstrPool pool; /*!< Global string pool */
removedHash removedPackages; /*!< Set of packages being removed. */
rpmal addedPackages; /*!< Set of packages being installed. */
diff --git a/lib/transaction.c b/lib/transaction.c
index bbe29a53b..624077786 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1475,6 +1475,7 @@ static int rpmtsProcess(rpmts ts)
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
{
int rc = -1; /* assume failure */
+ tsMembers tsmem = rpmtsMembers(ts);
rpmlock lock = NULL;
rpmps tsprobs = NULL;
/* Force default 022 umask during transaction for consistent results */
@@ -1521,7 +1522,6 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
/* If unfiltered problems exist, free memory and return. */
if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS) || (rpmpsNumProblems(tsprobs))) {
- tsMembers tsmem = rpmtsMembers(ts);
rc = tsmem->orderCount;
goto exit;
}
@@ -1530,6 +1530,14 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
tsprobs = rpmpsFree(tsprobs);
rpmtsCleanProblems(ts);
+ /*
+ * Free up the global string pool unless we expect it to be needed
+ * again. During the transaction, private pools will be used for
+ * rpmfi's etc.
+ */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS)))
+ tsmem->pool = rpmstrPoolFree(tsmem->pool);
+
/* Actually install and remove packages, get final exit code */
rc = rpmtsProcess(ts) ? -1 : 0;