diff --git a/src/session/session.cpp b/src/session/session.cpp index 1b582fd..11a1b8d 100644 --- a/src/session/session.cpp +++ b/src/session/session.cpp @@ -421,6 +421,8 @@ const char *session_state_to_str(enum session_state state) return "active"; case SESSION_STATE_CLOSING: return "closing"; + case SESSION_STATE_DISCARD: + return "discard"; case SESSION_STATE_CLOSED: return "closed"; default: diff --git a/src/session/session.h b/src/session/session.h index 9e1674b..dbeaecb 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -17,8 +17,9 @@ enum session_state SESSION_STATE_OPENING = 1, SESSION_STATE_ACTIVE = 2, SESSION_STATE_CLOSING = 3, - SESSION_STATE_CLOSED = 4, - MAX_STATE = 5, + SESSION_STATE_DISCARD = 4, + SESSION_STATE_CLOSED = 5, + MAX_STATE = 6, }; enum session_type diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp index f942d15..762a2ad 100644 --- a/src/session/session_manager.cpp +++ b/src/session/session_manager.cpp @@ -174,6 +174,9 @@ static void session_stat_inc(struct session_stat *stat, enum session_state state case SESSION_STATE_CLOSING: stat->nr_sess_closing++; break; + case SESSION_STATE_DISCARD: + stat->nr_sess_discard++; + break; case SESSION_STATE_CLOSED: stat->nr_sess_closed++; break; @@ -198,6 +201,9 @@ static void session_stat_dec(struct session_stat *stat, enum session_state state case SESSION_STATE_CLOSING: stat->nr_sess_closing--; break; + case SESSION_STATE_DISCARD: + stat->nr_sess_discard--; + break; case SESSION_STATE_CLOSED: stat->nr_sess_closed--; break; diff --git a/src/session/session_manager.h b/src/session/session_manager.h index 75e4b5c..487d7c5 100644 --- a/src/session/session_manager.h +++ b/src/session/session_manager.h @@ -53,6 +53,7 @@ struct session_stat uint64_t nr_sess_opening; uint64_t nr_sess_active; uint64_t nr_sess_closing; + uint64_t nr_sess_discard; uint64_t nr_sess_closed; uint64_t nr_new_sess_evicted; diff --git a/src/session/session_transition.cpp b/src/session/session_transition.cpp index d64bb0a..bbf0d4c 100644 --- a/src/session/session_transition.cpp +++ b/src/session/session_transition.cpp @@ -3,7 +3,7 @@ #include "session_transition.h" -#define MAX_TRANSITION_PER_STATE 4 +#define MAX_TRANSITION_PER_STATE 8 struct session_transition { @@ -20,14 +20,20 @@ struct session_transition * SESSION_STATE_OPENING -> SESSION_STATE_OPENING ( NONE ) * SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA ) * SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT ) + * SESSION_STATE_OPENING -> SESSION_STATE_DISCARD ( USER_CLOSE ) * SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT ) * * SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE ) * SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT ) + * SESSION_STATE_ACTIVE -> SESSION_STATE_DISCARD ( USER_CLOSE ) * SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT ) * * SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE ) - * SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( TIMEOUT | LRU_EVICT ) + * SESSION_STATE_CLOSING -> SESSION_STATE_DISCARD ( USER_CLOSE ) + * SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( LRU_EVICT | TIMEOUT ) + * + * SESSION_STATE_DISCARD -> SESSION_STATE_DISCARD ( NONE ) + * SESSION_STATE_DISCARD -> SESSION_STATE_CLOSED ( LRU_EVICT | TIMEOUT ) */ static void session_inputs_to_str(int inputs, char *buff, int len) @@ -65,57 +71,61 @@ static void session_inputs_to_str(int inputs, char *buff, int len) { nused += snprintf(buff + nused, len - nused, "LRU_EVICT "); } + if (inputs & USER_CLOSE) + { + nused += snprintf(buff + nused, len - nused, "USER_CLOSE "); + } } void session_transition_init() { - // SESSION_STATE_INIT -> SESSION_STATE_OPENING ( TCP_SYN | TCP_SYN_ACK | UDP_DATA ) - // SESSION_STATE_INIT -> SESSION_STATE_INIT ( NONE ) - fsm[SESSION_STATE_INIT][0].inputs_mask = TCP_SYN | TCP_SYN_ACK | UDP_DATA; fsm[SESSION_STATE_INIT][0].next_state = SESSION_STATE_OPENING; fsm[SESSION_STATE_INIT][1].inputs_mask = NONE; fsm[SESSION_STATE_INIT][1].next_state = SESSION_STATE_INIT; - // SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA ) - // SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT ) - // SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT ) - // SESSION_STATE_OPENING -> SESSION_STATE_OPENING ( NONE ) - fsm[SESSION_STATE_OPENING][0].inputs_mask = TCP_DATA | UDP_DATA; fsm[SESSION_STATE_OPENING][0].next_state = SESSION_STATE_ACTIVE; fsm[SESSION_STATE_OPENING][1].inputs_mask = TCP_FIN | TCP_RST | TIMEOUT; fsm[SESSION_STATE_OPENING][1].next_state = SESSION_STATE_CLOSING; - fsm[SESSION_STATE_OPENING][2].inputs_mask = LRU_EVICT; - fsm[SESSION_STATE_OPENING][2].next_state = SESSION_STATE_CLOSED; + fsm[SESSION_STATE_OPENING][2].inputs_mask = USER_CLOSE; + fsm[SESSION_STATE_OPENING][2].next_state = SESSION_STATE_DISCARD; - fsm[SESSION_STATE_OPENING][3].inputs_mask = NONE; - fsm[SESSION_STATE_OPENING][3].next_state = SESSION_STATE_OPENING; + fsm[SESSION_STATE_OPENING][3].inputs_mask = LRU_EVICT; + fsm[SESSION_STATE_OPENING][3].next_state = SESSION_STATE_CLOSED; - // SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT ) - // SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT ) - // SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE ) + fsm[SESSION_STATE_OPENING][4].inputs_mask = NONE; + fsm[SESSION_STATE_OPENING][4].next_state = SESSION_STATE_OPENING; fsm[SESSION_STATE_ACTIVE][0].inputs_mask = TCP_FIN | TCP_RST | TIMEOUT; fsm[SESSION_STATE_ACTIVE][0].next_state = SESSION_STATE_CLOSING; - fsm[SESSION_STATE_ACTIVE][1].inputs_mask = LRU_EVICT; - fsm[SESSION_STATE_ACTIVE][1].next_state = SESSION_STATE_CLOSED; + fsm[SESSION_STATE_ACTIVE][1].inputs_mask = USER_CLOSE; + fsm[SESSION_STATE_ACTIVE][1].next_state = SESSION_STATE_DISCARD; - fsm[SESSION_STATE_ACTIVE][2].inputs_mask = NONE; - fsm[SESSION_STATE_ACTIVE][2].next_state = SESSION_STATE_ACTIVE; + fsm[SESSION_STATE_ACTIVE][2].inputs_mask = LRU_EVICT; + fsm[SESSION_STATE_ACTIVE][2].next_state = SESSION_STATE_CLOSED; - // SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( TIMEOUT | LRU_EVICT ) - // SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE ) + fsm[SESSION_STATE_ACTIVE][3].inputs_mask = NONE; + fsm[SESSION_STATE_ACTIVE][3].next_state = SESSION_STATE_ACTIVE; - fsm[SESSION_STATE_CLOSING][0].inputs_mask = TIMEOUT | LRU_EVICT; - fsm[SESSION_STATE_CLOSING][0].next_state = SESSION_STATE_CLOSED; + fsm[SESSION_STATE_CLOSING][0].inputs_mask = USER_CLOSE; + fsm[SESSION_STATE_CLOSING][0].next_state = SESSION_STATE_DISCARD; - fsm[SESSION_STATE_CLOSING][1].inputs_mask = NONE; - fsm[SESSION_STATE_CLOSING][1].next_state = SESSION_STATE_CLOSING; + fsm[SESSION_STATE_CLOSING][1].inputs_mask = LRU_EVICT | TIMEOUT; + fsm[SESSION_STATE_CLOSING][1].next_state = SESSION_STATE_CLOSED; + + fsm[SESSION_STATE_CLOSING][2].inputs_mask = NONE; + fsm[SESSION_STATE_CLOSING][2].next_state = SESSION_STATE_CLOSING; + + fsm[SESSION_STATE_DISCARD][0].inputs_mask = LRU_EVICT | TIMEOUT; + fsm[SESSION_STATE_DISCARD][0].next_state = SESSION_STATE_CLOSED; + + fsm[SESSION_STATE_DISCARD][1].inputs_mask = NONE; + fsm[SESSION_STATE_DISCARD][1].next_state = SESSION_STATE_DISCARD; } enum session_state session_transition_run(enum session_state curr_state, int inputs) diff --git a/src/session/session_transition.h b/src/session/session_transition.h index da36d99..dd69fd7 100644 --- a/src/session/session_transition.h +++ b/src/session/session_transition.h @@ -28,6 +28,9 @@ enum session_inputs // session table full evict LRU_EVICT = 1 << 7, + + // user close + USER_CLOSE = 1 << 8, }; void session_transition_init(); diff --git a/src/session/test/CMakeLists.txt b/src/session/test/CMakeLists.txt index edee948..695b0fb 100644 --- a/src/session/test/CMakeLists.txt +++ b/src/session/test/CMakeLists.txt @@ -83,6 +83,13 @@ target_link_libraries(gtest_overload_evict_tcp_sess session_manager gtest) add_executable(gtest_overload_evict_udp_sess gtest_overload_evict_udp_sess.cpp) target_link_libraries(gtest_overload_evict_udp_sess session_manager gtest) +############################################################################### +# gtest transistion +############################################################################### + +add_executable(gtest_session_transition gtest_session_transition.cpp) +target_link_libraries(gtest_session_transition session_manager gtest) + ############################################################################### # gtest ############################################################################### @@ -112,3 +119,5 @@ gtest_discover_tests(gtest_filter_tcp_dupkt) gtest_discover_tests(gtest_overload_evict_tcp_sess) gtest_discover_tests(gtest_overload_evict_udp_sess) + +gtest_discover_tests(gtest_session_transition) diff --git a/src/session/test/gtest_session_transition.cpp b/src/session/test/gtest_session_transition.cpp new file mode 100644 index 0000000..7007d5e --- /dev/null +++ b/src/session/test/gtest_session_transition.cpp @@ -0,0 +1,44 @@ +#include + +#include "session_transition.h" + +TEST(SESSION_TRANSITION, RUN) +{ + session_transition_init(); + + EXPECT_TRUE(session_transition_run(SESSION_STATE_INIT, NONE) == SESSION_STATE_INIT); + EXPECT_TRUE(session_transition_run(SESSION_STATE_INIT, TCP_SYN) == SESSION_STATE_OPENING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_INIT, TCP_SYN_ACK) == SESSION_STATE_OPENING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_INIT, UDP_DATA) == SESSION_STATE_OPENING); + + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, NONE) == SESSION_STATE_OPENING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, TCP_DATA) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, UDP_DATA) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, TCP_FIN) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, TCP_RST) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, TIMEOUT) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, USER_CLOSE) == SESSION_STATE_DISCARD); + EXPECT_TRUE(session_transition_run(SESSION_STATE_OPENING, LRU_EVICT) == SESSION_STATE_CLOSED); + + EXPECT_TRUE(session_transition_run(SESSION_STATE_ACTIVE, NONE) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_transition_run(SESSION_STATE_ACTIVE, TCP_FIN) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_ACTIVE, TCP_RST) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_ACTIVE, TIMEOUT) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_ACTIVE, USER_CLOSE) == SESSION_STATE_DISCARD); + EXPECT_TRUE(session_transition_run(SESSION_STATE_ACTIVE, LRU_EVICT) == SESSION_STATE_CLOSED); + + EXPECT_TRUE(session_transition_run(SESSION_STATE_CLOSING, NONE) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_transition_run(SESSION_STATE_CLOSING, USER_CLOSE) == SESSION_STATE_DISCARD); + EXPECT_TRUE(session_transition_run(SESSION_STATE_CLOSING, LRU_EVICT) == SESSION_STATE_CLOSED); + EXPECT_TRUE(session_transition_run(SESSION_STATE_CLOSING, TIMEOUT) == SESSION_STATE_CLOSED); + + EXPECT_TRUE(session_transition_run(SESSION_STATE_DISCARD, NONE) == SESSION_STATE_DISCARD); + EXPECT_TRUE(session_transition_run(SESSION_STATE_DISCARD, LRU_EVICT) == SESSION_STATE_CLOSED); + EXPECT_TRUE(session_transition_run(SESSION_STATE_DISCARD, TIMEOUT) == SESSION_STATE_CLOSED); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/timestamp/test/gtest_timestamp.cpp b/src/timestamp/test/gtest_timestamp.cpp index 04a1dec..32f608f 100644 --- a/src/timestamp/test/gtest_timestamp.cpp +++ b/src/timestamp/test/gtest_timestamp.cpp @@ -4,21 +4,36 @@ TEST(TIMESTAMP, GET) { - uint64_t sec = 0; - uint64_t msec = 0; + uint64_t last_sec = 0; + uint64_t last_msec = 0; + uint64_t curr_sec = 0; + uint64_t curr_msec = 0; - for (int i = 0; i < 4; i++) - { - timestamp_update(); - sec = timestamp_get_sec(); - msec = timestamp_get_msec(); + timestamp_update(); + last_sec = timestamp_get_sec(); + last_msec = timestamp_get_msec(); - printf("current ts in sec : %lu\n", sec); - printf("current ts in msec : %lu\n", msec); - EXPECT_TRUE(sec == msec / 1000); - sleep(i); - printf("sleep %ds\n", i); - } + usleep(1000); // 1ms + timestamp_update(); + curr_sec = timestamp_get_sec(); + curr_msec = timestamp_get_msec(); + printf("After usleep(1000)\n"); + printf("last_sec: %lu, last_msec: %lu\n", last_sec, last_msec); + printf("curr_sec: %lu, curr_msec: %lu\n", curr_sec, curr_msec); + EXPECT_TRUE(curr_sec == last_sec); + EXPECT_TRUE(curr_msec - last_msec >= 1 && curr_msec - last_msec <= 2); + + usleep(1000 * 1000); // 1s + timestamp_update(); + last_sec = curr_sec; + last_msec = curr_msec; + curr_sec = timestamp_get_sec(); + curr_msec = timestamp_get_msec(); + printf("After usleep(1000 * 1000)\n"); + printf("last_sec: %lu, last_msec: %lu\n", last_sec, last_msec); + printf("curr_sec: %lu, curr_msec: %lu\n", curr_sec, curr_msec); + EXPECT_TRUE(curr_sec - last_sec == 1); + EXPECT_TRUE(curr_msec - last_msec >= 1000 && curr_msec - last_msec <= 1001); } int main(int argc, char **argv) diff --git a/src/timestamp/timestamp.cpp b/src/timestamp/timestamp.cpp index 0748c05..4cac82a 100644 --- a/src/timestamp/timestamp.cpp +++ b/src/timestamp/timestamp.cpp @@ -32,6 +32,7 @@ uint64_t timestamp_get_sec() return ATOMIC_READ(&g_timestamp.ts_in_sec); } +// TODO uint64_t 溢出 uint64_t timestamp_get_msec() { return ATOMIC_READ(&g_timestamp.ts_in_msec);