int xbps_set_pkg_state_installed(struct xbps_handle *xhp, const char *pkgver, pkg_state_t state) { xbps_dictionary_t pkgd; char *pkgname; int rv = 0; assert(pkgver != NULL); pkgd = xbps_pkgdb_get_pkg(xhp, pkgver); if (pkgd == NULL) { pkgd = xbps_dictionary_create(); if (pkgd == NULL) return ENOMEM; if (!xbps_dictionary_set_cstring_nocopy(pkgd, "pkgver", pkgver)) { xbps_object_release(pkgd); return EINVAL; } if ((rv = set_new_state(pkgd, state)) != 0) { xbps_object_release(pkgd); return rv; } pkgname = xbps_pkg_name(pkgver); assert(pkgname); if (!xbps_dictionary_set(xhp->pkgdb, pkgname, pkgd)) { xbps_object_release(pkgd); free(pkgname); return EINVAL; } free(pkgname); xbps_object_release(pkgd); } else { if ((rv = set_new_state(pkgd, state)) != 0) return rv; pkgname = xbps_pkg_name(pkgver); assert(pkgname); if (!xbps_dictionary_set(xhp->pkgdb, pkgname, pkgd)) { free(pkgname); return EINVAL; } free(pkgname); } return rv; }
int xbps_set_pkg_state_dictionary(xbps_dictionary_t dict, pkg_state_t state) { assert(xbps_object_type(dict) == XBPS_TYPE_DICTIONARY); return set_new_state(dict, state); }
void mfd::EventSender::handle_lifecycle_event( MirLifecycleState state) { mp::EventSequence seq; auto protobuf_life_event = seq.mutable_lifecycle_event(); protobuf_life_event->set_new_state(state); send_event_sequence(seq, {}); }
void VolumeDriverError::report(const VolumeId& volid, VolumeFailOverState old_state, VolumeFailOverState new_state) noexcept { try { events::Event ev; auto msg = ev.MutableExtension(events::dtl_state_transition); msg->set_volume_name(volid.str()); msg->set_old_state(translate_foc_state(old_state)); msg->set_new_state(translate_foc_state(new_state)); report(ev); } CATCH_STD_ALL_LOG_IGNORE("Failed to report DTL state transition event, volume " << volid << ", old state " << old_state << ", new state " << new_state); TODO("AR: the logging could emit an exception, violating noexcept?"); }
struct GB_result get_bit_file(void) { int oldinch, inch; bool valid = false; static bool read_acc_minlen; char co[6]; set_new_state(); /* * bit.realfreq and bit.t are set to fake value for compatibility with * old log files not storing acc_minlen values or to increase time * when mainloop() splits too long minutes */ bit.realfreq = 1000000000; while (!valid) { inch = getc(logfile); switch (inch) { case EOF: gb_res.done = true; return gb_res; case '0': case '1': buffer[bitpos] = inch - (int)'0'; gb_res.bitval = (inch == (int)'0') ? ebv_0 : ebv_1; valid = true; bit.t = 1000; break; case '\r': case '\n': /* * Skip multiple consecutive EOM markers, * these are made impossible by the reset_minlen() * invocation in get_bit_live() */ break; case 'x': gb_res.hwstat = ehw_transmit; valid = true; bit.t = 2500; break; case 'r': gb_res.hwstat = ehw_receive; valid = true; bit.t = 2500; break; case '#': gb_res.hwstat = ehw_random; valid = true; bit.t = 2500; break; case '*': gb_res.bad_io = true; valid = true; bit.t = 0; break; case '_': /* retain old value in buffer[bitpos] */ gb_res.bitval = ebv_none; valid = true; bit.t = 1000; break; case 'a': /* acc_minlen */ gb_res.skip = eskip_this; valid = true; bit.t = 0; if (fscanf(logfile, "%10u", &acc_minlen) != 1) gb_res.done = true; read_acc_minlen = !gb_res.done; break; case 'c': /* cutoff for newminute */ gb_res.skip = eskip_this; valid = true; bit.t = 0; if (fscanf(logfile, "%6c", co) != 1) gb_res.done = true; if (!gb_res.done && (co[1] == '.')) cutoff = (co[0] - '0') * 10000 + (int)strtol(co + 2, (char **)NULL, 10); break; default: break; } } /* Only allow \r , \n , \r\n , and \n\r as single EOM markers */ oldinch = inch; inch = getc(logfile); if (inch == EOF) gb_res.done = true; if (inch == (int)'a' || inch == (int)'c') gb_res.skip = eskip_next; if ((inch != (int)'\r' && inch != (int)'\n') || inch == oldinch) { if (ungetc(inch, logfile) == EOF) /* EOF remains, IO error */ gb_res.done = true; } else { if (gb_res.marker == emark_none) gb_res.marker = emark_minute; else if (gb_res.marker == emark_toolong) gb_res.marker = emark_late; if (!read_acc_minlen) bit.t += 1000; else read_acc_minlen = false; /* Check for \r\n or \n\r */ oldinch = inch; inch = getc(logfile); if (inch == EOF) gb_res.done = true; if (inch == (int)'a' || inch == (int)'c') gb_res.skip = eskip_next; if ((inch != (int)'\r' && inch != (int)'\n') || inch == oldinch) { if (ungetc(inch, logfile) == EOF) /* EOF remains, IO error */ gb_res.done = true; } } if (!read_acc_minlen) acc_minlen += 1000000 * bit.t / (bit.realfreq / 1000); return gb_res; }
/* * The bits are decoded from the signal using an exponential low-pass filter in * conjunction with a Schmitt trigger. The idea and the initial implementation * for this come from Udo Klein, with permission. * http://blog.blinkenlight.net/experiments/dcf77/binary-clock/#comment-5916 */ struct GB_result get_bit_live(void) { char outch; bool newminute = false; unsigned stv = 1; int p; struct timespec slp; #if !defined(MACOS) struct timespec tp0, tp1; #endif unsigned sec2; long long a, y = 1000000000; long long twait; static int init_bit = 2; bool is_eom = gb_res.marker == emark_minute || gb_res.marker == emark_late; bit.freq_reset = false; bit.bitlen_reset = false; set_new_state(); /* * One period is either 1000 ms or 2000 ms long (normal or padding for * last). The active part is either 100 ms ('0') or 200 ms ('1') long. * The maximum allowed values as percentage of the second length are * specified as half the value and the whole value of the lengths of * bit 0 and bit 20 respectively. * * ~A > 3/2 * realfreq: end-of-minute * ~A > 5/2 * realfreq: timeout */ if (init_bit == 2) { bit.realfreq = hw.freq * 1000000; bit.bit0 = bit.realfreq / 10; bit.bit20 = bit.realfreq / 5; } sec2 = 1000000000 / (hw.freq * hw.freq); /* * Set up filter, reach 50% after realfreq/20 samples (i.e. 50 ms) */ a = 1000000000 - (long long)(1000000000 * exp2(-2e7 / bit.realfreq)); bit.tlow = -1; bit.tlast0 = -1; for (bit.t = 0; bit.t != 0xFFFFFFFF; bit.t++) { #if !defined(MACOS) (void)clock_gettime(CLOCK_MONOTONIC, &tp0); #endif p = get_pulse(); if (p == 2) { gb_res.bad_io = true; outch = '*'; goto report; } if (bit.signal != NULL) { if ((bit.t & 7) == 0) bit.signal[bit.t / 8] = 0; /* clear data from previous second */ bit.signal[bit.t / 8] |= p << (unsigned char)(bit.t & 7); } if (y >= 0 && y < a / 2) bit.tlast0 = (int)bit.t; y += a * (p * 1000000000 - y) / 1000000000; /* * Prevent algorithm collapse during thunderstorms * or scheduler abuse */ if (bit.realfreq <= hw.freq * 500000 || bit.realfreq >= hw.freq * 1500000) reset_frequency(); if (bit.t > bit.realfreq * 2500000) { bit.realfreq += ((long long) (bit.t * 2500000 - bit.realfreq) / 20); a = 1000000000 - (long long)(1000000000 * exp2(-2e7 / bit.realfreq)); if (bit.tlow * 100 / bit.t < 1) { gb_res.hwstat = ehw_receive; outch = 'r'; } else if (bit.tlow * 100 / bit.t >= 99) { gb_res.hwstat = ehw_transmit; outch = 'x'; } else { gb_res.hwstat = ehw_random; outch = '#'; } goto report; /* timeout */ } /* * Schmitt trigger, maximize value to introduce * hysteresis and to avoid infinite memory. */ if (y < 500000000 && stv == 1) { /* end of high part of second */ y = 0; stv = 0; bit.tlow = (int)bit.t; } if (y > 500000000 && stv == 0) { /* end of low part of second */ y = 1000000000; stv = 1; newminute = bit.t * 2000000 > bit.realfreq * 3; if (init_bit == 2) init_bit--; else { if (newminute) bit.realfreq += ((long long)(bit.t * 500000 - bit.realfreq) / 20); else bit.realfreq += ((long long)(bit.t * 1000000 - bit.realfreq) / 20); a = 1000000000 - (long long)(1000000000 * exp2(-2e7 / bit.realfreq)); } if (newminute) { /* * Reset the frequency and the EOM flag if two * consecutive EOM markers come in, which means * something is wrong. */ if (is_eom) { if (gb_res.marker == emark_minute) gb_res.marker = emark_none; else if (gb_res.marker == emark_late) gb_res.marker = emark_toolong; reset_frequency(); } else { if (gb_res.marker == emark_none) gb_res.marker = emark_minute; else if (gb_res.marker == emark_toolong) gb_res.marker = emark_late; } } break; /* start of new second */ } twait = (long long)(sec2 * bit.realfreq / 1000000); #if !defined(MACOS) (void)clock_gettime(CLOCK_MONOTONIC, &tp1); twait = twait - (tp1.tv_sec - tp0.tv_sec) * 1000000000 - (tp1.tv_nsec - tp0.tv_nsec); #endif slp.tv_sec = twait / 1000000000; slp.tv_nsec = twait % 1000000000; while (twait > 0 && nanosleep(&slp, &slp)) ; } if (2 * bit.realfreq * bit.tlow * (1 + (newminute ? 1 : 0)) < (bit.bit0 + bit.bit20) * bit.t) { /* zero bit, ~100 ms active signal */ gb_res.bitval = ebv_0; outch = '0'; buffer[bitpos] = 0; } else if (bit.realfreq * bit.tlow * (1 + (newminute ? 1 : 0)) < (bit.bit0 + bit.bit20) * bit.t) { /* one bit, ~200 ms active signal */ gb_res.bitval = ebv_1; outch = '1'; buffer[bitpos] = 1; } else { /* bad radio signal, retain old value */ gb_res.bitval = ebv_none; outch = '_'; /* force bit 20 to be 1 to recover from too low b20 value */ if (bitpos == 20) { gb_res.bitval = ebv_1; outch = '1'; buffer[20] = 1; } } if (init_bit == 1) init_bit--; else if (gb_res.hwstat == ehw_ok && gb_res.marker == emark_none) { if (bitpos == 0 && gb_res.bitval == ebv_0) bit.bit0 += ((long long) (bit.tlow * 1000000 - bit.bit0) / 2); if (bitpos == 20 && gb_res.bitval == ebv_1) bit.bit20 += ((long long) (bit.tlow * 1000000 - bit.bit20) / 2); /* During a thunderstorm the value of bit20 might underflow */ if (bit.bit20 < bit.bit0) reset_bitlen(); } report: acc_minlen += 1000000 * bit.t / (bit.realfreq / 1000); if (logfile != NULL) { fprintf(logfile, "%c", outch); if (gb_res.marker == emark_minute || gb_res.marker == emark_late) fprintf(logfile, "a%uc%6.4f\n", acc_minlen, (double)((bit.t * 1e6) / bit.realfreq)); } if (gb_res.marker == emark_minute || gb_res.marker == emark_late) cutoff = bit.t * 1000000 / (bit.realfreq / 10000); return gb_res; }