Clean up progress callbacks in fsm/psm machinery
authorPanu Matilainen <pmatilai@redhat.com>
Thu, 5 Jan 2012 12:48:22 +0000 (14:48 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Thu, 5 Jan 2012 14:05:10 +0000 (16:05 +0200)
- Move notifications from fsm to psm side for sanity and symmetry,
  psm already has members to hold the callback state.
- Replace PSM_NOTIFY "state" with a helper function that both
  fsm and psm itself use (except for error callbacks which are
  a bit different)
- Init psm->total early, this doesn't change and can now be
  used to refer to "all done" value whatever it happens to be,
  instead of magic "100" values etc.
- Packages with no files are now handled through the same path
  as everything else from progress reporting pov, we just skip calls
  to fsm if there are no files.
- Issue stop callbacks for install as well. While INST_CLOSE_FILE
  can be (and is currently) used to detect this condition, its
  conceptually an entirely different thing.
- Fix erasure callback parameters, they were reversed (starting from
  total and ending with 0, ehh...)

lib/fsm.c
lib/fsm.h
lib/psm.c

index 8ef4b70..8df04b3 100644 (file)
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -627,12 +627,6 @@ int fsmSetup(FSM_t fsm, fileStage goal,
     fsm->digestalgo = rpmfiDigestAlgo(fi);
     fsm->psm = psm;
 
-    if (fsm->goal == FSM_PKGINSTALL) {
-       fsm->archivePos = 0;
-       rpmtsNotify(ts, te, RPMCALLBACK_INST_START,
-                   fsm->archivePos, fi->archiveSize);
-    }
-
     fsm->archiveSize = archiveSize;
     if (fsm->archiveSize)
        *fsm->archiveSize = 0;
@@ -1891,14 +1885,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
        break;
     case FSM_NOTIFY:           /* XXX move from fsm to psm -> tsm */
        if (fsm->goal == FSM_PKGINSTALL) {
-           rpmts ts = fsmGetTs(fsm);
-           rpmte te = fsmGetTe(fsm);
-           rpmfi fi = fsmGetFi(fsm);
-           if (fsm->cpioPos > fsm->archivePos) {
-               fsm->archivePos = fsm->cpioPos;
-               rpmtsNotify(ts, te, RPMCALLBACK_INST_PROGRESS,
-                       fsm->archivePos, fi->archiveSize);
-           }
+           rpmpsmNotify(fsm->psm, RPMCALLBACK_INST_PROGRESS, fsm->cpioPos);
        }
        break;
     case FSM_UNDO:
index 5d33fce..f98ff8a 100644 (file)
--- a/lib/fsm.h
+++ b/lib/fsm.h
@@ -225,6 +225,8 @@ int fsmTeardown(FSM_t fsm);
 RPM_GNUC_INTERNAL
 int fsmNext(FSM_t fsm, fileStage nstage);
 
+RPM_GNUC_INTERNAL
+void rpmpsmNotify(rpmpsm psm, int what, rpm_loff_t amount);
 #ifdef __cplusplus
 }
 #endif
index 36bdebd..79cf0f8 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -37,7 +37,6 @@ typedef enum pkgStage_e {
     PSM_FINI           =  6,
 
     PSM_CREATE         = 17,
-    PSM_NOTIFY         = 22,
     PSM_DESTROY                = 23,
 
     PSM_SCRIPT         = 53,
@@ -655,6 +654,25 @@ static rpmpsm rpmpsmNew(rpmts ts, rpmte te)
     return psm;
 }
 
+void rpmpsmNotify(rpmpsm psm, int what, rpm_loff_t amount)
+{
+    if (psm) {
+       int changed = 0;
+       if (amount > psm->amount) {
+           psm->amount = amount;
+           changed = 1;
+       }
+       if (what && what != psm->what) {
+           psm->what = what;
+           changed = 1;
+       }
+       if (changed) {
+          rpmtsNotify(psm->ts, psm->te, psm->what, psm->amount, psm->total);
+       }
+    }
+}
+
+
 static int runFsm(rpmpsm psm, FD_t payload)
 {
     int sc, ec;
@@ -733,6 +751,9 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
        if (psm->goal == PKG_INSTALL) {
            psm->scriptArg = psm->npkgs_installed + 1;
 
+           psm->amount = 0;
+           psm->total = fi->archiveSize ? fi->archiveSize : 100;
+
            /* HACK: reinstall abuses te instance to remove old header */
            if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)
                markReplacedInstance(ts, psm->te);
@@ -756,6 +777,9 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
        }
        if (psm->goal == PKG_ERASE) {
            psm->scriptArg = psm->npkgs_installed - 1;
+
+           psm->amount = 0;
+           psm->total = rpmfiFC(fi) ? rpmfiFC(fi) : 100;
        }
        break;
     case PSM_PRE:
@@ -801,33 +825,29 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
        break;
     case PSM_PROCESS:
        if (psm->goal == PKG_INSTALL) {
-           FD_t payload = NULL;
-           int fsmrc;
+           int fsmrc = 0;
 
            if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)  break;
 
-           /* XXX Synthesize callbacks for packages with no files. */
-           if (rpmfiFC(fi) <= 0) {
-               rpmtsNotify(ts, psm->te, RPMCALLBACK_INST_START, 0, 100);
-               rpmtsNotify(ts, psm->te, RPMCALLBACK_INST_PROGRESS, 100, 100);
-               break;
-           }
+           rpmpsmNotify(psm, RPMCALLBACK_INST_START, 0);
+           /* make sure first progress call gets made */
+           rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, 0);
 
-           payload = rpmtePayload(psm->te);
-           if (payload == NULL) {
-               rc = RPMRC_FAIL;
-               break;
-           }
+           if (rpmfiFC(fi) > 0) {
+               FD_t payload = rpmtePayload(psm->te);
+               if (payload == NULL) {
+                   rc = RPMRC_FAIL;
+                   break;
+               }
 
-           fsmrc = runFsm(psm, payload);
+               fsmrc = runFsm(psm, payload);
 
-           Fclose(payload);
+               Fclose(payload);
+           }
 
-           /* XXX make sure progress is closed out */
-           psm->what = RPMCALLBACK_INST_PROGRESS;
-           psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
-           psm->total = psm->amount;
-           rpmpsmNext(psm, PSM_NOTIFY);
+           /* XXX make sure progress reaches 100% */
+           rpmpsmNotify(psm, 0, psm->total);
+           rpmpsmNotify(psm, RPMCALLBACK_INST_STOP, psm->total);
 
            if (fsmrc) {
                rpmlog(RPMLOG_ERR,
@@ -843,30 +863,20 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
            }
        }
        if (psm->goal == PKG_ERASE) {
-           int fc = rpmfiFC(fi);
-
            if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)  break;
 
-           /* XXX Synthesize callbacks for packages with no files. */
-           if (rpmfiFC(fi) <= 0) {
-               rpmtsNotify(ts, psm->te, RPMCALLBACK_UNINST_START, 0, 100);
-               rpmtsNotify(ts, psm->te, RPMCALLBACK_UNINST_STOP, 0, 100);
-               break;
-           }
-
-           psm->what = RPMCALLBACK_UNINST_START;
-           psm->amount = fc;           /* XXX W2DO? looks wrong. */
-           psm->total = fc;
-           rpmpsmNext(psm, PSM_NOTIFY);
+           rpmpsmNotify(psm, RPMCALLBACK_UNINST_START, 0);
+           /* make sure first progress call gets made */
+           rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, 0);
 
            /* XXX should't we log errors from here? */
-           rc = runFsm(psm, NULL) ? RPMRC_FAIL : RPMRC_OK;
-
-           psm->what = RPMCALLBACK_UNINST_STOP;
-           psm->amount = 0;            /* XXX W2DO? looks wrong. */
-           psm->total = fc;
-           rpmpsmNext(psm, PSM_NOTIFY);
+           if (rpmfiFC(fi) > 0) {
+               rc = runFsm(psm, NULL) ? RPMRC_FAIL : RPMRC_OK;
+           }
 
+           /* XXX make sure progress reaches 100% */
+           rpmpsmNotify(psm, 0, psm->total);
+           rpmpsmNotify(psm, RPMCALLBACK_UNINST_STOP, psm->total);
        }
        break;
     case PSM_POST:
@@ -962,9 +972,6 @@ static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
 
     case PSM_CREATE:
        break;
-    case PSM_NOTIFY:
-       rpmtsNotify(ts, psm->te, psm->what, psm->amount, psm->total);
-       break;
     case PSM_DESTROY:
        break;
     case PSM_SCRIPT:   /* Run current package scriptlets. */