Statistics
| Branch: | Revision:

streamers / transaction.c @ f1bad954

History | View | Annotate | Download (6.22 KB)

1
/*
2
 *  Copyright (c) 2010 Stefano Traverso
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7

    
8
#include <stdint.h>
9
#include <stdio.h>
10
#include <stdbool.h>
11
#include <stdlib.h>
12
#include <sys/time.h>
13

    
14
#include "dbg.h"
15
#include "transaction.h"
16
#include "hrc.h"
17

    
18
static struct service_times_element *stl = NULL;
19

    
20
// Add the moment I received a positive select in a list
21
// return true if a valid trans_id is found
22
uint16_t transaction_create(struct nodeID *id) {
23
        struct service_times_element *stl2, *stl_iterator;
24
        struct timeval current_time;
25
        gettimeofday(&current_time, NULL);
26
        stl_iterator = stl;
27
        static uint16_t trans_id = 0;
28
        
29
        ++trans_id;
30
        if (trans_id == 0) 
31
                ++trans_id; // skip transid 0 which is reserved for the source (for when trans_id reaches his maximum)
32
                
33
        dprintf("LIST: adding trans_id %d to the list, offer_sent_time %f\n", trans_id, (current_time.tv_sec + current_time.tv_usec*1e-6));
34
        //List is not empty
35
        if (stl != NULL) {
36
                dprintf("LIST: adding trans_id %d to the list, offer_sent_time %f -- LIST IS NOT EMPTY\n", trans_id, (current_time.tv_sec + current_time.tv_usec*1e-6));
37
                stl2 = (struct service_times_element*) malloc(sizeof(struct service_times_element));
38
                stl2->st.trans_id = trans_id;
39
                stl2->st.offer_sent_time = current_time.tv_sec + current_time.tv_usec*1e-6;
40
                stl2->st.accept_received_time = -1.0;
41
                stl2->st.id = id;
42
                stl2->forward = stl;
43
                stl2->backward = NULL;
44
                stl->backward = stl2;
45
                stl = stl2; 
46
                }
47
        else { // This is the first element to insert
48
                dprintf("LIST: adding trans_id %d to the list, offer_sent_time %f -- LIST IS EMPTY\n", trans_id, current_time.tv_sec + current_time.tv_usec*1e-6);
49
                stl = (struct service_times_element*) malloc(sizeof(struct service_times_element));
50
                stl->st.trans_id = trans_id;
51
                stl->st.offer_sent_time = current_time.tv_sec + current_time.tv_usec*1e-6;
52
                stl->st.accept_received_time = -1.0;
53
                stl->st.id = id;
54
                stl->forward = NULL;
55
                stl->backward = NULL;
56
                }
57
        return trans_id;
58
        }
59

    
60
// Change transaction status when an accept has been received
61
bool transaction_change(uint16_t trans_id, struct nodeID *id) {
62
        struct service_times_element *stl_iterator;
63
        struct timeval current_time;
64
        gettimeofday(&current_time, NULL);
65
        stl_iterator = stl;
66
                
67
        // if an accept was received, look for the trans_id and add current_time to accept_received_time field
68
        dprintf("LIST: changing trans_id %d to the list -- ACCEPT\n", trans_id);
69
        // Iterate the list until you get the right element
70
        while (stl_iterator != NULL) {
71
                if (stl_iterator->st.trans_id == trans_id) {
72
                        stl_iterator->st.accept_received_time = current_time.tv_sec + current_time.tv_usec*1e-6;
73
                        return true;
74
                        }
75
                stl_iterator = stl_iterator->forward;
76
                }
77
        return false;
78
}
79

    
80

    
81
// Used to get the time elapsed from the moment I get a positive select to the moment i get the ACK
82
// related to the same chunk
83
// it return -1.0 in case no trans_id is found
84
double transaction_remove(uint16_t trans_id) {
85
        struct service_times_element *stl_iterator;
86
        double to_return;
87

    
88
            dprintf("LIST: deleting trans_id %d\n", trans_id);
89
                
90
        // Start from the beginning of the list
91
        stl_iterator = stl;
92
        // Iterate the list until you get the right element
93
        while (stl_iterator != NULL) {
94
                if (stl_iterator->st.trans_id == trans_id)
95
                        break;
96
                stl_iterator = stl_iterator->forward;
97
                }
98
        if (stl_iterator == NULL){
99
                // not found
100
                dprintf(stderr, "LIST: deleting trans_id %d -- STL is already NULL \n", trans_id);
101
                return -2.0;
102
        }
103
        
104
        to_return = stl_iterator->st.accept_received_time;
105
               
106
        // I have to remove the element from the list
107
        // If it is the first element
108
        if (stl_iterator->backward == NULL) {
109
                stl = stl_iterator->forward;
110
                // Check if I have more than one element in the list
111
                if (stl_iterator->forward != NULL)
112
                        stl_iterator->forward->backward = NULL;
113
                stl_iterator->forward = NULL;
114
                }
115
        // I have to remove the last element of the list
116
        else {
117
                if (stl_iterator->forward == NULL) {
118
                        stl_iterator->backward->forward = NULL;
119
                        }
120
                // I have to remove an element in the middle
121
                else {
122
                        stl_iterator->backward->forward = stl_iterator->forward;
123
                        stl_iterator->forward->backward = stl_iterator->backward;
124
                        }
125
                }
126
        free(stl_iterator);
127
        return to_return;
128
        }
129
        
130
// Check the service times list to find elements over the timeout
131
void transactions_check() {
132
        struct service_times_element *stl_iterator, *stl_aux;
133
        struct timeval current_time;
134
        bool something_got_removed;
135

    
136
        gettimeofday(&current_time, NULL);
137
        something_got_removed = false;
138
        
139
        // Check if list is empty
140
        if (stl == NULL) {
141
                return;
142
                }
143
        
144
        // Start from the beginning of the list
145
        stl_iterator = stl;
146
        stl_aux = stl;
147
        // Iterate the list until you get the right element
148
        while (stl_iterator != NULL) {
149
                // If the element has been in the list for a period greater than the timeout, remove it
150
                if ( ( (current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.offer_sent_time) > TRANS_ID_MAX_LIFETIME) {
151
                        dprintf("LIST TIMEOUT: trans_id %d, offer_sent_time %f, accept_received_time %f\n", stl_iterator->st.trans_id, (double) ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.offer_sent_time  ), (double) ((current_time.tv_sec + current_time.tv_usec*1e-6) - stl_iterator->st.accept_received_time));
152
                        if (stl_iterator->backward == NULL) {
153
                                stl = stl_iterator->forward;
154
                                // Check if I have more than one element in the list
155
                                if (stl_iterator->forward != NULL)
156
                                        stl_iterator->forward->backward = NULL;
157
                                stl_iterator->forward = NULL;
158
                                }
159
                        else {         // I have to remove the last element of the list
160
                                if (stl_iterator->forward == NULL) {
161
                                        stl_iterator->backward->forward = NULL;
162
                                        free(stl_iterator);
163
                                        return;
164
                                        }
165
                                // I have to remove an element in the middle
166
                                else {
167
                                        stl_iterator->backward->forward = stl_iterator->forward;
168
                                        stl_iterator->forward->backward = stl_iterator->backward;
169
                                        }
170
                                }
171
                        
172
                        something_got_removed = true;
173
                        stl_aux = stl_iterator->forward;
174
                        // Free the memory
175
                        free(stl_iterator);
176
                        // A thread was interrupted, so free it
177
                        adjust_offer_threads(THREAD_TIMEOUT, -1);
178
                        }
179
                if (something_got_removed) {
180
                        stl_iterator = stl_aux;
181
                        something_got_removed = false;
182
                        }
183
                else
184
                        stl_iterator = stl_iterator->forward;
185
                }
186
        // reincarnate eventual deleted offers
187
        return;
188
        }