lsquic_alarmset.c revision b8fa6195
1/* Copyright (c) 2017 - 2020 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_SESS_TICKET] = "SESS_TICKET",
49    [AL_BLOCKED_KA] = "BLOCKED_KA",
50    [AL_MTU_PROBE]  = "MTU_PROBE",
51};
52
53
54void
55lsquic_alarmset_ring_expired (lsquic_alarmset_t *alset, lsquic_time_t now)
56{
57    enum alarm_id_bit armed_set;
58    enum alarm_id al_id;
59
60    for (al_id = 0, armed_set = alset->as_armed_set;
61            al_id < MAX_LSQUIC_ALARMS && armed_set;
62                armed_set &= ~(1 << al_id), ++al_id)
63        if (armed_set & (1 << al_id))
64        {
65            if (alset->as_expiry[al_id] < now)
66            {
67                alset->as_armed_set &= ~(1 << al_id);
68                LSQ_INFO("ring expired %s alarm", lsquic_alid2str[al_id]);
69                alset->as_alarms[al_id].callback(al_id,
70                                alset->as_alarms[al_id].cb_ctx,
71                                alset->as_expiry[al_id], now);
72            }
73        }
74}
75
76
77lsquic_time_t
78lsquic_alarmset_mintime (const lsquic_alarmset_t *alset, enum alarm_id *idp)
79{
80    lsquic_time_t expiry;
81    enum alarm_id al_id, ret_id;
82
83    if (alset->as_armed_set)
84    {
85        expiry = UINT64_MAX;
86        for (al_id = 0, ret_id = 0; al_id < MAX_LSQUIC_ALARMS; ++al_id)
87            if ((alset->as_armed_set & (1 << al_id))
88                                && alset->as_expiry[al_id] < expiry)
89            {
90                expiry = alset->as_expiry[al_id];
91                ret_id = al_id;
92            }
93        *idp = ret_id;
94        return expiry;
95    }
96    else
97        return 0;
98}
99