Implement a transaction set change notification callback
Add support for an optional callback hook for reveiving notifications about added and deleted transaction elements. This lets API clients easily track which elements get created and/or replaced by a single rpmtsAddFoo() call and adjust their own book-keeping accordingly. Also makes for an easy place to set application private data pointers for newly added elements. Currently there's no way to delete individual transaction elements from the API but that can happen via rpmtsEmpty(), which we do send notifications for. rpmtsFree() does NOT send notification though, it would be precarious and most likely totally pointless to do so when the ts is being torn down.
This commit is contained in:
parent
45449d5acf
commit
257077a60c
|
@ -135,6 +135,7 @@ static int removePackage(rpmts ts, Header h, rpmte depends)
|
|||
|
||||
tsmem->order[tsmem->orderCount] = p;
|
||||
tsmem->orderCount++;
|
||||
rpmtsNotifyChange(ts, RPMTS_EVENT_ADD, p, depends);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -430,6 +431,7 @@ static int addPackage(rpmts ts, Header h,
|
|||
oc = findPos(ts, tscolor, p, (op == RPMTE_UPGRADE));
|
||||
/* If we're replacing a previously added element, free the old one */
|
||||
if (oc >= 0 && oc < tsmem->orderCount) {
|
||||
rpmtsNotifyChange(ts, RPMTS_EVENT_DEL, tsmem->order[oc], p);
|
||||
rpmalDel(tsmem->addedPackages, tsmem->order[oc]);
|
||||
tsmem->order[oc] = rpmteFree(tsmem->order[oc]);
|
||||
/* If newer NEVR was already added, we're done */
|
||||
|
@ -450,6 +452,8 @@ static int addPackage(rpmts ts, Header h,
|
|||
if (oc == tsmem->orderCount) {
|
||||
tsmem->orderCount++;
|
||||
}
|
||||
rpmtsNotifyChange(ts, RPMTS_EVENT_ADD, p, NULL);
|
||||
|
||||
|
||||
if (tsmem->addedPackages == NULL) {
|
||||
tsmem->addedPackages = rpmalCreate(ts, 5);
|
||||
|
|
21
lib/rpmts.c
21
lib/rpmts.c
|
@ -707,6 +707,7 @@ void rpmtsEmpty(rpmts ts)
|
|||
rpmtsClean(ts);
|
||||
|
||||
for (int oc = 0; oc < tsmem->orderCount; oc++) {
|
||||
rpmtsNotifyChange(ts, RPMTS_EVENT_DEL, tsmem->order[oc], NULL);
|
||||
tsmem->order[oc] = rpmteFree(tsmem->order[oc]);
|
||||
}
|
||||
|
||||
|
@ -759,6 +760,8 @@ rpmts rpmtsFree(rpmts ts)
|
|||
if (ts->nrefs > 1)
|
||||
return rpmtsUnlink(ts);
|
||||
|
||||
/* Don't issue element change callbacks when freeing */
|
||||
rpmtsSetChangeCallback(ts, NULL, NULL);
|
||||
rpmtsEmpty(ts);
|
||||
|
||||
(void) rpmtsCloseDB(ts);
|
||||
|
@ -940,6 +943,15 @@ void * rpmtsNotify(rpmts ts, rpmte te,
|
|||
return ptr;
|
||||
}
|
||||
|
||||
int rpmtsNotifyChange(rpmts ts, int event, rpmte te, rpmte other)
|
||||
{
|
||||
int rc = 0;
|
||||
if (ts && ts->change) {
|
||||
rc = ts->change(event, te, other, ts->changeData);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rpmtsNElements(rpmts ts)
|
||||
{
|
||||
int nelements = 0;
|
||||
|
@ -1042,6 +1054,15 @@ int rpmtsSetNotifyCallback(rpmts ts,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int rpmtsSetChangeCallback(rpmts ts, rpmtsChangeFunction change, void *data)
|
||||
{
|
||||
if (ts != NULL) {
|
||||
ts->change = change;
|
||||
ts->changeData = data;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsMembers rpmtsMembers(rpmts ts)
|
||||
{
|
||||
return (ts != NULL) ? ts->members : NULL;
|
||||
|
|
33
lib/rpmts.h
33
lib/rpmts.h
|
@ -179,6 +179,26 @@ enum rpmtxnFlags_e {
|
|||
};
|
||||
typedef rpmFlags rpmtxnFlags;
|
||||
|
||||
typedef enum rpmtsEvent_e {
|
||||
RPMTS_EVENT_ADD = 1,
|
||||
RPMTS_EVENT_DEL = 2,
|
||||
} rpmtsEvent;
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Transaction change callback type.
|
||||
*
|
||||
* On explicit install/erase add events, "other" is NULL, on implicit
|
||||
* add events (erasures due to obsolete/upgrade, replaced by newer)
|
||||
* it points to the replacing package.
|
||||
*
|
||||
* @param event Change event (see rpmtsEvent enum)
|
||||
* @param te Transaction element
|
||||
* @param other Related transaction element (or NULL)
|
||||
* @param data Application private data from rpmtsSetChangeCallback()
|
||||
*/
|
||||
typedef int (*rpmtsChangeFunction)
|
||||
(int event, rpmte te, rpmte other, void *data);
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Perform dependency resolution on the transaction set.
|
||||
*
|
||||
|
@ -585,6 +605,19 @@ int rpmtsSetNotifyCallback(rpmts ts,
|
|||
rpmCallbackFunction notify,
|
||||
rpmCallbackData notifyData);
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Set transaction change callback function and argument.
|
||||
*
|
||||
* The change callback gets called when transaction elements are added,
|
||||
* replaced or removed from a transaction set.
|
||||
*
|
||||
* @param ts transaction set
|
||||
* @param notify element change callback
|
||||
* @param data element change callback private data
|
||||
* @return 0 on success
|
||||
*/
|
||||
int rpmtsSetChangeCallback(rpmts ts, rpmtsChangeFunction notify, void *data);
|
||||
|
||||
/** \ingroup rpmts
|
||||
* Create an empty transaction set.
|
||||
* @return new transaction set
|
||||
|
|
|
@ -51,6 +51,9 @@ struct rpmts_s {
|
|||
rpmCallbackFunction notify; /*!< Callback function. */
|
||||
rpmCallbackData notifyData; /*!< Callback private data. */
|
||||
|
||||
rpmtsChangeFunction change; /*!< Change callback function. */
|
||||
void *changeData; /*!< Change callback private data. */
|
||||
|
||||
rpmprobFilterFlags ignoreSet;
|
||||
/*!< Bits to filter current problems. */
|
||||
|
||||
|
@ -123,6 +126,10 @@ RPM_GNUC_INTERNAL
|
|||
rpmRC runScript(rpmts ts, rpmte te, Header h, ARGV_const_t prefixes,
|
||||
rpmScript script, int arg1, int arg2);
|
||||
|
||||
|
||||
RPM_GNUC_INTERNAL
|
||||
int rpmtsNotifyChange(rpmts ts, int event, rpmte te, rpmte other);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue