41
41
* Trigger processing algorithms:
44
* There is a separate queue (`deferred trigproc list') for triggers
45
* `relevant' to what we just did; when we find something triggered `now'
44
* There is a separate queue (‘deferred trigproc list’) for triggers
45
* ‘relevant’ to what we just did; when we find something triggered ‘now’
46
46
* we add it to that queue (unless --no-triggers).
49
49
* We want to prefer configuring packages where possible to doing
50
50
* trigger processing, but we want to prefer trigger processing to
51
* cycle-breaking and dependency forcing. This is achieved as
51
* cycle-breaking and dependency forcing. This is achieved as
54
54
* Each time during configure processing where a package D is blocked by
55
55
* only (ie Depends unsatisfied but would be satisfied by) a t-awaiter W
56
* we make a note of (one of) W's t-pending, T. (Only the last such T.)
56
* we make a note of (one of) W's t-pending, T. (Only the last such T.)
57
57
* (If --no-triggers and nonempty argument list and package isn't in
58
58
* argument list then we don't do this.)
60
60
* Each time in packages.c where we increment dependtry, we instead see
61
* if we have encountered such a t-pending T. If we do, we trigproc T
61
* if we have encountered such a t-pending T. If we do, we trigproc T
62
62
* instead of incrementing dependtry and this counts as having done
63
63
* something so we reset sincenothing.
66
66
* For --triggers-only and --configure, we go through each thing in the
67
67
* argument queue (the add_to_queue queue) and check what its state is
68
* and if appropriate we trigproc it. If we didn't have a queue (or had
68
* and if appropriate we trigproc it. If we didn't have a queue (or had
69
69
* just --pending) we search all triggers-pending packages and add them
70
70
* to the deferred trigproc list.
73
73
* Before quitting from most operations, we trigproc each package in the
74
* deferred trigproc list. This may (if not --no-triggers) of course add
74
* deferred trigproc list. This may (if not --no-triggers) of course add
75
75
* new things to the deferred trigproc list.
78
* Note that `we trigproc T' must involve trigger cycle detection and
79
* also automatic setting of t-awaiters to t-pending or installed. In
78
* Note that ‘we trigproc T’ must involve trigger cycle detection and
79
* also automatic setting of t-awaiters to t-pending or installed. In
80
80
* particular, we do cycle detection even for trigger processing in the
81
81
* configure dependtry loop (and it is OK to do it for explicitly
82
82
* specified packages from the command line arguments; duplicates are
83
83
* removed by packages.c:process_queue).
87
/*========== deferred trigger queue ==========*/
86
/*========== Deferred trigger queue. ==========*/
89
88
static struct pkg_queue deferred = PKG_QUEUE_INIT;
116
115
if (setjmp(ejbuf)) {
117
error_unwind(ehflag_bombout);
116
pop_error_context(ehflag_bombout);
120
push_error_handler(&ejbuf, print_error_perpackage, pkg->name);
119
push_error_context_jump(&ejbuf, print_error_perpackage,
122
122
pkg->clientdata->trigprocdeferred = NULL;
125
set_error_display(NULL, NULL);
126
error_unwind(ehflag_normaltidy);
125
pop_error_context(ehflag_normaltidy);
130
* Called by modstatdb_note.
131
133
trig_activate_packageprocessing(struct pkginfo *pkg)
207
211
/* Now we compare hare to tortoise.
208
212
* We want to find a trigger pending in tortoise which is not in hare
209
213
* if we find such a thing we have proved that hare isn't a superset
210
* of tortoise and so that we haven't found a loop (yet).
214
* of tortoise and so that we haven't found a loop (yet). */
212
215
for (tortoise_pkg = tortoise->pkgs;
214
217
tortoise_pkg = tortoise_pkg->next) {
245
/* Oh dear. hare is a superset of tortoise. We are making no progress. */
248
/* Oh dear. hare is a superset of tortoise. We are making no
246
250
fprintf(stderr, _("%s: cycle found while processing triggers:\n chain of"
247
251
" packages whose triggers are or may be responsible:\n"),
250
254
for (tcn = tortoise; tcn; tcn = tcn->next) {
251
255
fprintf(stderr, "%s%s", sep, tcn->then_processed->name);
304
312
printf(_("Processing triggers for %s ...\n"), pkg->name);
305
313
log_action("trigproc", pkg);
307
varbufreset(&namesarg);
315
varbuf_reset(&namesarg);
308
316
for (tp = pkg->trigpend_head; tp; tp = tp->next) {
309
varbufaddc(&namesarg, ' ');
310
varbufaddstr(&namesarg, tp->name);
317
varbuf_add_char(&namesarg, ' ');
318
varbuf_add_str(&namesarg, tp->name);
312
varbufaddc(&namesarg, 0);
320
varbuf_end_str(&namesarg);
314
/* Setting the status to halfconfigured
315
* causes modstatdb_note to clear pending triggers.
322
/* Setting the status to half-configured
323
* causes modstatdb_note to clear pending triggers. */
317
324
pkg->status = stat_halfconfigured;
318
325
modstatdb_note(pkg);
358
365
transitional_interest_callback_ro(trig, user);
369
* cstatus might be msdbrw_readonly if we're in --no-act mode, in which
370
* case we don't write out all of the interest files etc. but we do
371
* invent all of the activations for our own benefit.
362
374
trig_transitional_activate(enum modstatdb_rw cstatus)
364
/* cstatus might be _read if we're in --no-act mode, in which
365
* case we don't write out all of the interest files etc.
366
* but we do invent all of the activations for our own benefit.
368
376
struct pkgiterator *it;
369
377
struct pkginfo *pkg;
373
while ((pkg = iterpkgnext(it))) {
379
it = pkg_db_iter_new();
380
while ((pkg = pkg_db_iter_next(it))) {
374
381
if (pkg->status <= stat_halfinstalled)
376
383
debug(dbg_triggersdetail, "trig_transitional_activate %s %s",
381
388
transitional_interest_callback :
382
389
transitional_interest_callback_ro, NULL, pkg);
391
pkg_db_iter_free(it);
385
393
if (cstatus >= msdbrw_write) {
386
394
modstatdb_checkpoint();
387
395
trig_file_interests_save();
391
/*========== hook setup ==========*/
399
/*========== Hook setup. ==========*/
393
401
static struct filenamenode *
394
402
th_proper_nn_find(const char *name, bool nonew)