diff --git a/src/base/xserver_interface.h b/src/base/xserver_interface.h index 8fb3e8456e4..7c85405b62a 100644 --- a/src/base/xserver_interface.h +++ b/src/base/xserver_interface.h @@ -262,7 +262,7 @@ extern int xlocator_upgrade_instances_domain (THREAD_ENTRY * thread_p, OID * cla extern int xsession_create_new (THREAD_ENTRY * thread_p, SESSION_ID * id); extern int xsession_check_session (THREAD_ENTRY * thread_p, const SESSION_ID id); -extern int xsession_end_session (THREAD_ENTRY * thread, const SESSION_ID id); +extern int xsession_end_session (THREAD_ENTRY * thread, const SESSION_ID id, bool is_keep_session); extern int xsession_set_row_count (THREAD_ENTRY * thread_p, int row_count); extern int xsession_get_row_count (THREAD_ENTRY * thread_p, int *row_count); diff --git a/src/broker/cas.c b/src/broker/cas.c index 0baf8e44bcf..6922ffb9078 100644 --- a/src/broker/cas.c +++ b/src/broker/cas.c @@ -1974,11 +1974,13 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) cas_log_msg = "RESET"; cas_log_write_and_end (0, true, cas_log_msg); fn_ret = FN_KEEP_SESS; + db_set_keep_session (true); } if (as_info->con_status == CON_STATUS_CLOSE_AND_CONNECT) { cas_log_msg = "CHANGE CLIENT"; fn_ret = FN_KEEP_SESS; + db_set_keep_session (true); } if (cas_log_msg == NULL) @@ -2170,6 +2172,10 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) net_buf->client_version = req_info->client_version; set_hang_check_time (); fn_ret = (*server_fn) (sock_fd, argc, argv, net_buf, req_info); + if (fn_ret == FN_KEEP_SESS) + { + db_set_keep_session (true); + } set_hang_check_time (); #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL) @@ -2242,6 +2248,7 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) else if (restart_is_needed ()) { fn_ret = FN_KEEP_SESS; + db_set_keep_session (true); } if (shm_appl->sql_log2 != as_info->cur_sql_log2) { @@ -2352,6 +2359,7 @@ process_request (SOCKET sock_fd, T_NET_BUF * net_buf, T_REQ_INFO * req_info) { cas_log_debug (ARG_FILE_LINE, "process_request: reset_flag && !CON_STATUS_IN_TRAN"); fn_ret = FN_KEEP_SESS; + db_set_keep_session (true); goto exit_on_end; } diff --git a/src/communication/network_interface_cl.c b/src/communication/network_interface_cl.c index 8e4c74779a1..ffad5f499f0 100644 --- a/src/communication/network_interface_cl.c +++ b/src/communication/network_interface_cl.c @@ -4736,13 +4736,13 @@ csession_find_or_create_session (SESSION_ID * session_id, int *row_count, char * * session_id (in) : the id of the session to end */ int -csession_end_session (SESSION_ID session_id) +csession_end_session (SESSION_ID session_id, bool is_keep_session) { #if defined (CS_MODE) int req_error; OR_ALIGNED_BUF (OR_INT_SIZE) a_reply; char *reply; - OR_ALIGNED_BUF (OR_INT_SIZE) a_request; + OR_ALIGNED_BUF (OR_INT_SIZE * 2) a_request; char *request; char *ptr; @@ -4750,6 +4750,7 @@ csession_end_session (SESSION_ID session_id) request = OR_ALIGNED_BUF_START (a_request); ptr = or_pack_int (request, session_id); + ptr = or_pack_int (ptr, is_keep_session); req_error = net_client_request (NET_SERVER_SES_END_SESSION, request, OR_ALIGNED_BUF_SIZE (a_request), reply, @@ -4765,7 +4766,7 @@ csession_end_session (SESSION_ID session_id) THREAD_ENTRY *thread_p = enter_server (); - result = xsession_end_session (thread_p, session_id); + result = xsession_end_session (thread_p, session_id, is_keep_session); exit_server (*thread_p); diff --git a/src/communication/network_interface_cl.h b/src/communication/network_interface_cl.h index 5b268d1872e..d9279786588 100644 --- a/src/communication/network_interface_cl.h +++ b/src/communication/network_interface_cl.h @@ -406,7 +406,7 @@ extern int boot_get_server_timezone_checksum (char *timezone_checksum); /* session state API */ extern int csession_find_or_create_session (SESSION_ID * session_id, int *row_count, char *server_session_key, const char *db_user, const char *host, const char *program_name); -extern int csession_end_session (SESSION_ID session_id); +extern int csession_end_session (SESSION_ID session_id, bool is_keep_session); extern int csession_set_row_count (int rows); extern int csession_get_row_count (int *rows); extern int csession_get_last_insert_id (DB_VALUE * value, bool update_last_insert_id); diff --git a/src/communication/network_interface_sr.c b/src/communication/network_interface_sr.c index 1f0ca0742d0..a74478f28e7 100644 --- a/src/communication/network_interface_sr.c +++ b/src/communication/network_interface_sr.c @@ -8986,14 +8986,16 @@ void ssession_end_session (THREAD_ENTRY * thread_p, unsigned int rid, char *request, int reqlen) { int err = NO_ERROR; + int is_keep_session; SESSION_ID id; OR_ALIGNED_BUF (OR_INT_SIZE) a_reply; char *reply = OR_ALIGNED_BUF_START (a_reply); char *ptr = NULL; - (void) or_unpack_int (request, (int *) &id); + ptr = or_unpack_int (request, (int *) &id); + ptr = or_unpack_int (ptr, (int *) &is_keep_session); - err = xsession_end_session (thread_p, id); + err = xsession_end_session (thread_p, id, (bool) is_keep_session); ptr = or_pack_int (reply, err); css_send_data_to_client (thread_p->conn_entry, rid, reply, OR_ALIGNED_BUF_SIZE (a_reply)); diff --git a/src/compat/db.h b/src/compat/db.h index 03549922633..9fb108480bf 100644 --- a/src/compat/db.h +++ b/src/compat/db.h @@ -49,6 +49,7 @@ extern int db_Connect_status; extern SESSION_ID db_Session_id; +extern bool db_Keep_session; extern int db_Row_count; diff --git a/src/compat/db_admin.c b/src/compat/db_admin.c index 823c495fcb1..90c5a0048a3 100644 --- a/src/compat/db_admin.c +++ b/src/compat/db_admin.c @@ -1062,7 +1062,7 @@ db_end_session (void) CHECK_CONNECT_ERROR (); - retval = csession_end_session (db_get_session_id ()); + retval = csession_end_session (db_get_session_id (), db_get_keep_session ()); cubmethod::get_callback_handler ()->free_query_handle_all (true); @@ -3073,6 +3073,26 @@ db_set_session_id (const SESSION_ID session_id) db_Session_id = session_id; } +/* + * db_get_keep_session () - get keep session flag + */ +bool +db_get_keep_session (void) +{ + return db_Keep_session; +} + +/* + * db_set_keep_session () - set keep session flag + * return : void + * keep_session (in): keep session flag + */ +void +db_set_keep_session (const bool keep_session) +{ + db_Keep_session = keep_session; +} + /* * db_find_or_create_session - check if current session is still active * if not, create a new session diff --git a/src/compat/db_macro.c b/src/compat/db_macro.c index 2fd7addab9c..7126ff1fa6e 100644 --- a/src/compat/db_macro.c +++ b/src/compat/db_macro.c @@ -79,6 +79,7 @@ struct valcnv_buffer }; SESSION_ID db_Session_id = DB_EMPTY_SESSION; +bool db_Keep_session = false; int db_Row_count = DB_ROW_COUNT_NOT_SET; diff --git a/src/compat/dbi.h b/src/compat/dbi.h index 74f2b077c5b..bb45d0844bc 100644 --- a/src/compat/dbi.h +++ b/src/compat/dbi.h @@ -77,6 +77,8 @@ extern "C" extern char *db_get_server_session_key (void); extern SESSION_ID db_get_session_id (void); extern void db_set_session_id (const SESSION_ID session_id); + extern bool db_get_keep_session (void); + extern void db_set_keep_session (const bool keep_session); extern int db_end_session (void); extern int db_find_or_create_session (const char *db_user, const char *program_name); extern int db_get_row_count_cache (void); diff --git a/src/compat/dbi_compat.h b/src/compat/dbi_compat.h index ce13ff58e96..e159026d82d 100644 --- a/src/compat/dbi_compat.h +++ b/src/compat/dbi_compat.h @@ -150,6 +150,8 @@ extern "C" const char *preferred_hosts, int client_type); extern SESSION_ID db_get_session_id (void); extern void db_set_session_id (const SESSION_ID session_id); + extern bool db_get_keep_session (void); + extern void db_set_keep_session (const bool keep_session); extern int db_find_or_create_session (const char *db_user, const char *program_name); extern int db_get_row_count_cache (void); extern void db_update_row_count_cache (const int row_count); diff --git a/src/session/session.c b/src/session/session.c index fab62a4997f..9e43a535157 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -118,6 +118,7 @@ struct session_state pthread_mutex_t mutex; /* state mutex */ UINT64 del_id; /* delete transaction ID (for lock free) */ + bool is_keep_session; bool is_trigger_involved; bool is_last_insert_id_generated; bool auto_commit; @@ -302,6 +303,7 @@ session_state_init (void *st) /* initialize fields */ db_make_null (&session_p->cur_insert_id); db_make_null (&session_p->last_insert_id); + session_p->is_keep_session = false; session_p->is_trigger_involved = false; session_p->is_last_insert_id_generated = false; session_p->row_count = -1; @@ -743,9 +745,10 @@ session_state_create (THREAD_ENTRY * thread_p, SESSION_ID * id) * session_state_destroy () - close a session state * return : NO_ERROR or error code * id(in) : the identifier for the session + * is_keep_session(in) : whether to keep the session */ int -session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id) +session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id, bool is_keep_session) { SESSION_STATE *session_p; int error = NO_ERROR, success = 0; @@ -762,6 +765,13 @@ session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id) return ER_SES_SESSION_EXPIRED; } + if (is_keep_session == true) + { + session_p->is_keep_session = true; + pthread_mutex_unlock (&session_p->mutex); + return NO_ERROR; + } + #if defined (SERVER_MODE) assert (session_p->ref_count > 0); @@ -934,10 +944,19 @@ session_remove_expired_sessions (THREAD_ENTRY * thread_p) /* Now we can destroy this session */ assert (state->ref_count == 0); - expired_sid_buffer[n_expired_sids++] = state->id; + if (state->is_keep_session == true) + { + /* keep session */ + pthread_mutex_unlock (&state->mutex); + continue; + } + else + { + expired_sid_buffer[n_expired_sids++] = state->id; - /* Destroy the session related resources like session parameters */ - (void) session_state_uninit (state); + /* Destroy the session related resources like session parameters */ + (void) session_state_uninit (state); + } if (n_expired_sids == EXPIRED_SESSION_BUFFER_SIZE) { diff --git a/src/session/session.h b/src/session/session.h index 6b55c12afea..eafa0191539 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -41,7 +41,7 @@ struct xasl_cache_ent; extern void session_states_init (THREAD_ENTRY * thread_p); extern void session_states_finalize (THREAD_ENTRY * thread_p); extern int session_state_create (THREAD_ENTRY * thread_p, SESSION_ID * id); -extern int session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id); +extern int session_state_destroy (THREAD_ENTRY * thread_p, const SESSION_ID id, bool is_keep_session); extern int session_check_session (THREAD_ENTRY * thread_p, const SESSION_ID id); extern int session_get_session_id (THREAD_ENTRY * thread_p, SESSION_ID * id); extern int session_get_last_insert_id (THREAD_ENTRY * thread_p, DB_VALUE * value, bool update_last_insert_id); diff --git a/src/session/session_sr.c b/src/session/session_sr.c index 107666218f3..6b4a37d9a6d 100644 --- a/src/session/session_sr.c +++ b/src/session/session_sr.c @@ -62,11 +62,12 @@ xsession_check_session (THREAD_ENTRY * thread_p, const SESSION_ID id) * return : error code * id (in) : session id * thread_p (in) + * is_keep_session (in) : whether to keep the session */ int -xsession_end_session (THREAD_ENTRY * thread_p, const SESSION_ID id) +xsession_end_session (THREAD_ENTRY * thread_p, const SESSION_ID id, bool is_keep_session) { - return session_state_destroy (thread_p, id); + return session_state_destroy (thread_p, id, is_keep_session); } /* diff --git a/win/cubridcs/cubridcs.def b/win/cubridcs/cubridcs.def index ac18a59f9dc..2f65bc0c68d 100644 --- a/win/cubridcs/cubridcs.def +++ b/win/cubridcs/cubridcs.def @@ -299,6 +299,8 @@ EXPORTS db_restart_ex db_set_session_id db_get_session_id + db_set_keep_session + db_get_keep_session db_find_or_create_session db_end_session db_set_connect_status diff --git a/win/cubridsa/cubridsa.def b/win/cubridsa/cubridsa.def index c1d922ba23e..1034e05dbf3 100644 --- a/win/cubridsa/cubridsa.def +++ b/win/cubridsa/cubridsa.def @@ -43,6 +43,8 @@ EXPORTS db_restart_ex db_set_session_id db_get_session_id + db_set_keep_session + db_get_keep_session db_find_or_create_session db_end_session db_set_server_session_key