aboutsummaryrefslogtreecommitdiffstats
path: root/URPM.xs
diff options
context:
space:
mode:
Diffstat (limited to 'URPM.xs')
-rw-r--r--URPM.xs240
1 files changed, 120 insertions, 120 deletions
diff --git a/URPM.xs b/URPM.xs
index 62def76..b49f8d1 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -40,6 +40,16 @@ struct s_Transaction {
rpmTransactionSet ts;
};
+struct s_TransactionData {
+ SV* callback_open;
+ SV* callback_close;
+ SV* callback_trans;
+ SV* callback_uninst;
+ SV* callback_inst;
+ long min_delta;
+ SV *data; /* chain with another data user provided */
+};
+
typedef rpmdb URPM__DB;
typedef struct s_Transaction* URPM__Transaction;
typedef struct s_Package* URPM__Package;
@@ -676,6 +686,103 @@ read_config_files() {
static void callback_empty(void) {}
+static void *rpmRunTransactions_callback(const void *h,
+ const rpmCallbackType what,
+ const unsigned long amount,
+ const unsigned long total,
+ const void * pkgKey,
+ void * data) {
+ static int last_amount;
+ static FD_t fd = NULL;
+ static struct timeval tprev;
+ static struct timeval tcurr;
+ long delta;
+ int i;
+ struct s_TransactionData *td = data;
+ SV *callback = NULL;
+ char *callback_type = NULL;
+ char *callback_subtype = NULL;
+
+ switch (what) {
+ case RPMCALLBACK_INST_OPEN_FILE:
+ callback = td->callback_open; callback_type = "open"; break;
+
+ case RPMCALLBACK_INST_CLOSE_FILE:
+ callback = td->callback_close; callback_type = "close"; break;
+
+ case RPMCALLBACK_TRANS_START:
+ case RPMCALLBACK_TRANS_PROGRESS:
+ case RPMCALLBACK_TRANS_STOP:
+ callback = td->callback_trans; callback_type = "trans"; break;
+
+ case RPMCALLBACK_UNINST_START:
+ case RPMCALLBACK_UNINST_PROGRESS:
+ case RPMCALLBACK_UNINST_STOP:
+ callback = td->callback_uninst; callback_type = "uninst"; break;
+
+ case RPMCALLBACK_INST_START:
+ case RPMCALLBACK_INST_PROGRESS:
+ callback = td->callback_inst; callback_type = "inst"; break;
+ }
+
+ if (callback != NULL) {
+ switch (what) {
+ case RPMCALLBACK_TRANS_START:
+ case RPMCALLBACK_UNINST_START:
+ case RPMCALLBACK_INST_START:
+ callback_subtype = "start"; break;
+ gettimeofday(&tprev, NULL);
+
+ case RPMCALLBACK_TRANS_PROGRESS:
+ case RPMCALLBACK_UNINST_PROGRESS:
+ case RPMCALLBACK_INST_PROGRESS:
+ callback_subtype = "progress";
+ gettimeofday(&tcurr, NULL);
+ delta = 1000000 * (tcurr.tv_sec - tprev.tv_sec) + (tcurr.tv_usec - tprev.tv_usec);
+ if (delta < td->min_delta && amount < total - 1)
+ callback = NULL; /* avoid calling too often a given callback */
+ else
+ tprev = tcurr;
+ break;
+
+ case RPMCALLBACK_TRANS_STOP:
+ case RPMCALLBACK_UNINST_STOP:
+ callback_subtype = "stop"; break;
+ }
+
+ if (callback != NULL) {
+ /* now, a callback will be called for sure */
+ dSP;
+ PUSHMARK(sp);
+ XPUSHs(td->data);
+ XPUSHs(sv_2mortal(newSVpv(callback_type, 0)));
+ XPUSHs(pkgKey != NULL ? sv_2mortal(newSViv((int)pkgKey - 1)) : &PL_sv_undef);
+ if (callback_subtype != NULL) {
+ XPUSHs(sv_2mortal(newSVpv(callback_subtype, 0)));
+ XPUSHs(sv_2mortal(newSViv(amount)));
+ XPUSHs(sv_2mortal(newSViv(total)));
+ }
+ PUTBACK;
+ i = call_sv(callback, callback == td->callback_open ? G_SCALAR : G_DISCARD);
+ SPAGAIN;
+ if (i != 1 && callback == td->callback_open) croak("callback_open should return a file handle");
+ if (i == 1) {
+ i = POPi;
+ fd = fdDup(i);
+ fd = fdLink(fd, "persist perl-URPM");
+ PUTBACK;
+ } else if (callback == td->callback_close) {
+ fd = fdFree(fd, "persist perl-URPM");
+ if (fd) {
+ fdClose(fd);
+ fd = NULL;
+ }
+ }
+ }
+ }
+ return fd;
+}
+
MODULE = URPM PACKAGE = URPM::Package PREFIX = Pkg_
void
@@ -1712,16 +1819,10 @@ Trans_DESTROY(trans)
int
Trans_add_package(trans, pkg, update)
URPM::Transaction trans
- SV* pkg
+ URPM::Package pkg
int update
- PREINIT:
- URPM__Package _pkg;
CODE:
- if (sv_derived_from(ST(0), "URPM::Package")) {
- IV tmp = SvIV((SV*)SvRV(ST(0)));
- _pkg = INT2PTR(URPM__Package,tmp);
- } else croak("pkg is not of type URPM::Package");
- RETVAL = _pkg->h && rpmtransAddPackage(trans->ts, _pkg->h, NULL, /* SvREFCNT_inc(pkg) */ pkg, update, NULL) == 0;
+ RETVAL = (pkg->flag & FLAG_ID) <= FLAG_ID_MAX && pkg->h != NULL && rpmtransAddPackage(trans->ts, pkg->h, NULL, (void *)(1+(pkg->flag & FLAG_ID)), update, NULL) == 0;
OUTPUT:
RETVAL
@@ -1818,113 +1919,12 @@ Trans_run(trans, data, ...)
SV *data
PREINIT:
/* available callback:
- callback(data, 'open'|'close', pkg)
- callback(data, 'trans'|'uninst'|'inst', pkg, 'start'|'progress'|'stop', amount, total)
+ callback(data, 'open'|'close', id|undef)
+ callback(data, 'trans'|'uninst'|'inst', id|undef, 'start'|'progress'|'stop', amount, total)
*/
- SV* callback_open = NULL;
- SV* callback_close = NULL;
- SV* callback_trans = NULL;
- SV* callback_uninst = NULL;
- SV* callback_inst = NULL;
- int min_delta = 200000;
+ struct s_TransactionData td = { NULL, NULL, NULL, NULL, NULL, 100000, data };
rpmProblemSet probs;
int i;
- void *rpmRunTransactions_callback(const void *h,
- const rpmCallbackType what,
- const unsigned long amount,
- const unsigned long total,
- const void * pkgKey,
- void * data) {
- static int last_amount;
- static FD_t fd = NULL;
- static struct timeval tprev;
- static struct timeval tcurr;
- long delta;
- int i;
- SV *callback = NULL;
- char *callback_type = NULL;
- char *callback_subtype = NULL;
-
- switch (what) {
- case RPMCALLBACK_INST_OPEN_FILE:
- callback = callback_open; callback_type = "open"; break;
-
- case RPMCALLBACK_INST_CLOSE_FILE:
- callback = callback_close; callback_type = "close"; break;
-
- case RPMCALLBACK_TRANS_START:
- case RPMCALLBACK_TRANS_PROGRESS:
- case RPMCALLBACK_TRANS_STOP:
- callback = callback_trans; callback_type = "trans"; break;
-
- case RPMCALLBACK_UNINST_START:
- case RPMCALLBACK_UNINST_PROGRESS:
- case RPMCALLBACK_UNINST_STOP:
- callback = callback_uninst; callback_type = "uninst"; break;
-
- case RPMCALLBACK_INST_START:
- case RPMCALLBACK_INST_PROGRESS:
- callback = callback_inst; callback_type = "inst"; break;
- }
-
- if (callback != NULL) {
- switch (what) {
- case RPMCALLBACK_TRANS_START:
- case RPMCALLBACK_UNINST_START:
- case RPMCALLBACK_INST_START:
- callback_subtype = "start"; break;
-
- case RPMCALLBACK_TRANS_PROGRESS:
- case RPMCALLBACK_UNINST_PROGRESS:
- case RPMCALLBACK_INST_PROGRESS:
- gettimeofday(&tcurr, NULL);
- delta = 1000000 * (tcurr.tv_sec - tprev.tv_sec) + (tcurr.tv_usec - tprev.tv_usec);
- if (delta > 200000 || amount >= total - 1)
- callback_subtype = "progress";
- else
- callback = NULL; /* avoid calling too often a given callback */
- break;
-
- case RPMCALLBACK_TRANS_STOP:
- case RPMCALLBACK_UNINST_STOP:
- callback_subtype = "stop"; break;
- }
-
- if (callback != NULL) {
- /* now, a callback will be called for sure */
- dSP;
- PUSHMARK(sp);
- XPUSHs(data);
- XPUSHs(sv_2mortal(newSVpv(callback_type, 0)));
- XPUSHs((SV *)pkgKey);
- if (callback_subtype != NULL) {
- XPUSHs(sv_2mortal(newSVpv(callback_subtype, 0)));
- XPUSHs(sv_2mortal(newSViv(amount)));
- XPUSHs(sv_2mortal(newSViv(total)));
- }
- PUTBACK;
- i = perl_call_sv(callback, callback == callback_open ? G_SCALAR : G_DISCARD);
- SPAGAIN;
- if (i != 1 && callback == callback_open) croak("callback_open should return a file handle");
- if (i == 1) {
- i = POPi;
- fd = fdDup(i);
- fd = fdLink(fd, "persist perl-URPM");
- PUTBACK;
- return fd;
- }
- if (callback == callback_close) {
- /* REFDEC on pkgKey */
- fd = fdFree(fd, "persist perl-URPM");
- if (fd) {
- fdClose(fd);
- fd = NULL;
- }
- }
- }
- }
- return NULL;
- }
PPCODE:
for (i = 2; i < items-1; i+=2) {
STRLEN len;
@@ -1932,19 +1932,19 @@ Trans_run(trans, data, ...)
if (len >= 9 && !memcmp(s, "callback_", 9)) {
if (len == 9+4 && !memcmp(s+9, "open", 4))
- callback_open = ST(i+1);
+ td.callback_open = ST(i+1);
else if (len == 9+5 && !memcmp(s+9, "close", 5))
- callback_close = ST(i+1);
+ td.callback_close = ST(i+1);
else if (len == 9+5 && !memcmp(s+9, "trans", 5))
- callback_trans = ST(i+1);
+ td.callback_trans = ST(i+1);
else if (len == 9+6 && !memcmp(s+9, "uninst", 6))
- callback_uninst = ST(i+1);
- else if (len == 9+6 && !memcmp(s+9, "inst", 4))
- callback_inst = ST(i+1);
+ td.callback_uninst = ST(i+1);
+ else if (len == 9+4 && !memcmp(s+9, "inst", 4))
+ td.callback_inst = ST(i+1);
} else if (len == 5 && !memcmp(s, "delta", 5))
- min_delta = SvIV(ST(i+1));
+ td.min_delta = SvIV(ST(i+1));
}
- if (rpmRunTransactions(trans->ts, rpmRunTransactions_callback, NULL, NULL, &probs, 0, 0)) {
+ if (rpmRunTransactions(trans->ts, rpmRunTransactions_callback, &td, NULL, &probs, 0, 0)) {
EXTEND(SP, probs->numProblems);
for (i = 0; i < probs->numProblems; i++) {
const char *pkgNEVR = (probs->probs[i].pkgNEVR ? probs->probs[i].pkgNEVR : "");