packetTimeoutTable.c 2.84 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "../clock.h"
#include "packetTimeoutTable.h"

PrrtPacketTimeoutTable *PrrtPacketTimeoutTable_create(void)
{
    PrrtPacketTimeoutTable *table = (PrrtPacketTimeoutTable *) calloc(1, sizeof(PrrtPacketTimeoutTable));
    check_mem(table);

    table->packetList = NULL;

13
    check(pthread_mutex_init(&table->lock, NULL) == EXIT_SUCCESS, "Init mutex failed.");
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

    return table;
    error:
    PERROR("Out of memory%s.","");
    return NULL;
}

bool PrrtPacketTimeoutTable_destroy(PrrtPacketTimeoutTable *table)
{
    List* list = List_create();

    BPTree_get_range(table->packetList, list, 0, SEQNO_SPACE - 1);
    while (List_count(list) > 0) {
        PrrtPacket *packet = List_shift(list);
        PrrtPacket_destroy(packet);
    }
    List_destroy(list);

    if(table->packetList != NULL) {
        table->packetList = BPTree_destroy(table->packetList);
    }

    pthread_mutex_destroy(&table->lock);
    free(table);
    return true;
}

bool PrrtPacketTimeoutTable_insert(PrrtPacketTimeoutTable *table, PrrtPacket *packet)
{
    check(pthread_mutex_lock(&table->lock) == EXIT_SUCCESS, "Lock failed.");
    PrrtPacketDataPayload* payload = packet->payload;
    table->packetList = BPTree_insert(table->packetList, payload->packetTimeout_us, packet);
    check(pthread_mutex_unlock(&table->lock) == EXIT_SUCCESS, "Unlock failed.");
    return true;
    error:
        PERROR("Insert failed%s.","");
        return false;
}

List *PrrtPacketTimeoutTable_expire_packets(PrrtPacketTimeoutTable *table, prrtTimestamp_t now)
{
    check(pthread_mutex_lock(&table->lock) == EXIT_SUCCESS, "Lock failed.");
    List* list = List_create();

    if(table->packetList != NULL) {
        if(now > HALF_TIMESTAMP) {
            BPTree_get_range(table->packetList, list, now - HALF_TIMESTAMP, now);
        } else {
            BPTree_get_range(table->packetList, list, 0, now);
            BPTree_get_range(table->packetList, list, now - HALF_TIMESTAMP, MAX_TIMESTAMP);
        }
    }

    LIST_FOREACH(list, first, next, current) {
        PrrtPacket *packet = current->value;
        PrrtPacketDataPayload* payload = packet->payload;
        table->packetList = BPTree_delete(table->packetList, payload->packetTimeout_us);
    }

    check(pthread_mutex_unlock(&table->lock) == EXIT_SUCCESS, "Unlock failed.");
    return list;
    error:
    PERROR("Get expired timestamps failed%s.","");
    return NULL;
}

PrrtPacket *PrrtPacketTimeoutTable_remove(PrrtPacketTimeoutTable *table, prrtTimestamp_t stamp)
{
    check(pthread_mutex_lock(&table->lock) == EXIT_SUCCESS, "Lock failed.");
    PrrtPacket *packet = (PrrtPacket *) BPTree_delete(table->packetList, stamp);
    check(pthread_mutex_unlock(&table->lock) == EXIT_SUCCESS, "Unlock failed.");
    return packet;
    error:
    PERROR("Get expired timestamps failed%s.","");
    return NULL;
}