lsquic_alarmset.c revision 293df8d6
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_alarmset.c -- A set of alarms
4 */
5
6#include <assert.h>
7#include <string.h>
8
9#include "lsquic_types.h"
10#include "lsquic_packet_common.h"
11#include "lsquic_alarmset.h"
12
13#define LSQUIC_LOGGER_MODULE LSQLM_ALARMSET
14#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(alset->as_conn)
15#include "lsquic_logger.h"
16
17
18void
19lsquic_alarmset_init (lsquic_alarmset_t *alset, const struct lsquic_conn *conn)
20{
21    alset->as_conn      = conn;
22    alset->as_armed_set = 0;
23}
24
25
26void
27lsquic_alarmset_init_alarm (lsquic_alarmset_t *alset, enum alarm_id al_id,
28                            lsquic_alarm_cb_f callback, void *cb_ctx)
29{
30    alset->as_alarms[ al_id ].callback = callback;
31    alset->as_alarms[ al_id ].cb_ctx   = cb_ctx;
32}
33
34
35const char *const lsquic_alid2str[] =
36{
37    [AL_HANDSHAKE]  =  "HANDSHAKE",
38    [AL_RETX_INIT]  =  "RETX_INIT",
39    [AL_RETX_HSK]   =  "RETX_HSK",
40    [AL_RETX_APP]   =  "RETX_APP",
41    [AL_PING]       =  "PING",
42    [AL_IDLE]       =  "IDLE",
43    [AL_ACK_APP]    =  "ACK_APP",
44    [AL_RET_CIDS]   =  "RET_CIDS",
45    [AL_CID_THROT]  =  "CID_THROT",
46    [AL_PATH_CHAL_0] = "PATH_CHAL_0",
47    [AL_PATH_CHAL_1] = "PATH_CHAL_1",
48    [AL_PATH_CHAL_2] = "PATH_CHAL_2",
49    [AL_PATH_CHAL_3] = "PATH_CHAL_3",
50    [AL_SESS_TICKET] = "SESS_TICKET",
51    [AL_BLOCKED_KA] = "BLOCKED_KA",
52    [AL_MTU_PROBE]  = "MTU_PROBE",
53    [AL_PACK_TOL]   = "PACK_TOL",
54};
55
56
57void
58lsquic_alarmset_ring_expired (lsquic_alarmset_t *alset, lsquic_time_t now)
59{
60    enum alarm_id_bit armed_set;
61    enum alarm_id al_id;
62
63    for (al_id = 0, armed_set = alset->as_armed_set;
64            al_id < MAX_LSQUIC_ALARMS && armed_set;
65                armed_set &= ~(1 << al_id), ++al_id)
66        if (armed_set & (1 << al_id))
67        {
68            if (alset->as_expiry[al_id] < now)
69            {
70                alset->as_armed_set &= ~(1 << al_id);
71                LSQ_INFO("ring expired %s alarm", lsquic_alid2str[al_id]);
72                alset->as_alarms[al_id].callback(al_id,
73                                alset->as_alarms[al_id].cb_ctx,
74                                alset->as_expiry[al_id], now);
75            }
76        }
77}
78
79
80lsquic_time_t
81lsquic_alarmset_mintime (const lsquic_alarmset_t *alset, enum alarm_id *idp)
82{
83    lsquic_time_t expiry;
84    enum alarm_id al_id, ret_id;
85
86    if (alset->as_armed_set)
87    {
88        expiry = UINT64_MAX;
89        for (al_id = 0, ret_id = 0; al_id < MAX_LSQUIC_ALARMS; ++al_id)
90            if ((alset->as_armed_set & (1 << al_id))
91                                && alset->as_expiry[al_id] < expiry)
92            {
93                expiry = alset->as_expiry[al_id];
94                ret_id = al_id;
95            }
96        *idp = ret_id;
97        return expiry;
98    }
99    else
100        return 0;
101}
102