@@ -1190,7 +1190,7 @@ static byte_t rx_transfer_id_forward_difference(const byte_t a, const byte_t b)
11901190// Maintaining separate state per priority level allows preemption of higher-priority transfers without loss.
11911191typedef struct
11921192{
1193- canard_us_t timestamp ; // Timestamp of the last received start-of-transfer; initially BIG_BANG .
1193+ canard_us_t timestamp ; // Timestamp of the start-of-transfer.
11941194 size_t total_payload_size ; // The raw payload size before the implicit truncation and CRC removal.
11951195 canard_bytes_mut_t payload ; // Dynamically allocated and handed off to the application when done.
11961196 uint16_t crc ;
@@ -1215,7 +1215,8 @@ static_assert((sizeof(void*) > 4) || (sizeof(rx_slot_t) <= 24), "too large");
12151215typedef struct
12161216{
12171217 canard_tree_t index ;
1218- canard_listed_t list_animation ; // On update, session moved to the tail; oldest pushed to the head.
1218+ canard_listed_t list_animation ; // On update, session moved to the tail; oldest pushed to the head.
1219+ canard_us_t timestamp ;
12191220 rx_slot_t * slots [CANARD_PRIO_COUNT ]; // Indexed by priority level to allow preemption.
12201221 canard_subscription_t * owner ;
12211222 byte_t transfer_id ; // Used for deduplication.
@@ -1289,18 +1290,11 @@ static void rx_session_destroy(rx_session_t* const ses)
12891290 mem_free (sub -> owner -> mem .rx_session , sizeof (rx_session_t ), ses );
12901291}
12911292
1292- typedef struct
1293- {
1294- canard_us_t latest_sof_at ;
1295- byte_t in_progress_slots ;
1296- } rx_session_state_t ;
1297-
1298- // Checks the state and purges stale slots to reclaim memory early.
1299- // A slot is stale if it's been idle for a very long time that is usually much larger than the transfer-ID timeout.
1300- static rx_session_state_t rx_session_scan (rx_session_t * const ses , const canard_us_t now )
1293+ // Checks the state and purges stale slots to reclaim memory early. Returns the number of in-progress slots remaining.
1294+ static size_t rx_session_scan (rx_session_t * const ses , const canard_us_t now )
13011295{
1302- const canard_us_t deadline = now - later (RX_SESSION_TIMEOUT , ses -> owner -> transfer_id_timeout );
1303- rx_session_state_t out = { . latest_sof_at = BIG_BANG , . in_progress_slots = 0 } ;
1296+ const canard_us_t deadline = now - later (RX_SESSION_TIMEOUT , ses -> owner -> transfer_id_timeout );
1297+ size_t in_progress_slots = 0 ;
13041298 FOREACH_SLOT (i ) {
13051299 const rx_slot_t * const slot = ses -> slots [i ];
13061300 if (slot == NULL ) {
@@ -1311,13 +1305,13 @@ static rx_session_state_t rx_session_scan(rx_session_t* const ses, const canard_
13111305 rx_slot_destroy (ses -> owner , ses -> slots [i ]);
13121306 ses -> slots [i ] = NULL ;
13131307 } else {
1314- out . latest_sof_at = later (out . latest_sof_at , slot -> timestamp );
1308+ ses -> timestamp = later (ses -> timestamp , slot -> timestamp );
13151309 if (slot -> total_payload_size > 0 ) {
1316- out . in_progress_slots ++ ;
1310+ in_progress_slots ++ ;
13171311 }
13181312 }
13191313 }
1320- return out ;
1314+ return in_progress_slots ;
13211315}
13221316
13231317// Returns false on OOM, no other failure modes. Stores at most extent bytes.
@@ -1450,8 +1444,8 @@ void canard_poll(canard_t* const self, const uint_least8_t tx_ready_iface_bitmap
14501444 // transfer-ID timeout among all subscriptions, but this is a reasonable tradeoff for the reduced complexity.
14511445 rx_session_t * const ses = LIST_HEAD (self -> rx .list_session_by_animation , rx_session_t , list_animation );
14521446 if (ses != NULL ) {
1453- const rx_session_state_t state = rx_session_scan (ses , now );
1454- if ((state . in_progress_slots == 0 ) && (state . latest_sof_at < (now - ses -> owner -> transfer_id_timeout ))) {
1447+ const size_t in_progress_slots = rx_session_scan (ses , now );
1448+ if ((in_progress_slots == 0 ) && (ses -> timestamp < (now - ses -> owner -> transfer_id_timeout ))) {
14551449 rx_session_destroy (ses );
14561450 }
14571451 }
0 commit comments