From: Seonah Moon Date: Wed, 16 Nov 2016 07:33:03 +0000 (+0900) Subject: Remove the transaction_thread X-Git-Tag: submit/tizen/20161202.120240~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F94%2F99794%2F1;p=platform%2Fcore%2Fapi%2Fhttp.git Remove the transaction_thread Change-Id: Ica09a27e7cd7169dd8ad5a10ac8b6e0c80eaced8 Signed-off-by: Seonah Moon --- diff --git a/include/http_private.h b/include/http_private.h index 078ebec..74572d9 100644 --- a/include/http_private.h +++ b/include/http_private.h @@ -138,7 +138,6 @@ typedef struct { typedef struct { CURLM *multi_handle; int session_id; - guint timer_event; int still_running; int active_transaction_count; gboolean auto_redirect; @@ -147,6 +146,7 @@ typedef struct { typedef struct { CURL *easy_handle; + guint timer_event; gchar *interface_name; int timeout; int write_event; @@ -161,6 +161,7 @@ typedef struct { bool proxy_auth_type; http_auth_scheme_e auth_scheme; gchar* realm; + /*Credential Info*/ gchar* user_name; gchar* password; @@ -186,8 +187,6 @@ typedef struct { __http_response_h *response; __http_header_h *header; - GThread *thread; - GMainLoop *thread_loop; } __http_transaction_h; typedef struct { @@ -226,6 +225,12 @@ FILE* _get_upload_file(http_transaction_h http_transaction); void _open_upload_file(http_transaction_h http_transaction); void _close_upload_file(__http_transaction_h *http_transaction); +void _http_transaction_start_timer(guint msecs, gboolean(*callback) (gpointer), void *user_data); +void _http_transaction_stop_timer(__http_transaction_h *transaction); + +gboolean curl_request_check(gpointer data); + + #ifdef __cplusplus } #endif diff --git a/packaging/capi-network-http.spec b/packaging/capi-network-http.spec index 9235e48..42e0bfd 100644 --- a/packaging/capi-network-http.spec +++ b/packaging/capi-network-http.spec @@ -1,6 +1,6 @@ Name: capi-network-http Summary: Http Framework -Version: 0.0.14 +Version: 0.0.15 Release: 0 Group: System/Network License: Apache-2.0 diff --git a/src/http_session.c b/src/http_session.c index 832b603..01c7d8d 100644 --- a/src/http_session.c +++ b/src/http_session.c @@ -19,10 +19,10 @@ static int generated_session_id = -1; -void _check_curl_multi_status(gpointer user_data) +static void _handle_completed_transaction(__http_session_h *user_data) { __http_transaction_h *transaction = NULL; - __http_session_h *session = (__http_session_h *)user_data; + __http_session_h *session = user_data; CURLMsg* message = NULL; int count = 0; @@ -102,173 +102,47 @@ void _check_curl_multi_status(gpointer user_data) } if (session->multi_handle != NULL && curl_easy != NULL) - curl_multi_remove_handle(session->multi_handle, curl_easy); + curl_multi_remove_handle(session->multi_handle, transaction->easy_handle); + } message = curl_multi_info_read(session->multi_handle, &count); } } -int _generate_session_id(void) +gboolean curl_request_check(gpointer data) { - if (generated_session_id >= INT_MAX) - generated_session_id = 0; - else - generated_session_id++; - - return generated_session_id; -} - -gboolean timer_expired_callback(gpointer user_data) -{ - __http_session_h* session = (__http_session_h *)user_data; - - CURLMcode ret; - - if (session == NULL || session->multi_handle == NULL) - return FALSE; - - ret = curl_multi_socket_action(session->multi_handle, CURL_SOCKET_TIMEOUT, 0, &(session->still_running)); - if (ret == CURLM_OK) - DBG("CURLM_OK - Called curl_multi_socket_action()\n"); - else - print_curl_multi_errorCode(ret); - - _check_curl_multi_status(session); - - return FALSE; -} - -gboolean _handle_event(int fd, int action, gpointer user_data) -{ - __http_session_h *session = (__http_session_h *)user_data; - - int running_handles = -1; - - CURLMcode ret = CURLM_OK; - - ret = curl_multi_socket_action(session->multi_handle, fd, action, &running_handles); - if (ret == CURLM_OK) - DBG("CURLM_OK: Called curl_multi_socket_action(%d)\n", action); - else - print_curl_multi_errorCode(ret); - - - if (running_handles > 0) { - _check_curl_multi_status(session); - return TRUE; - } else { - DBG("last transfer done, kill timeout\n"); - if (session->timer_event) { - g_source_remove(session->timer_event); - session->timer_event = 0; + __http_transaction_h *transaction = (__http_transaction_h *)data; + __http_session_h *session = transaction->session; + int rv = 0; + + if (0 != session->still_running) { + rv = curl_multi_perform(session->multi_handle, &session->still_running); + if (rv != CURLM_OK) { + DBG("curl multi perform failed %s\n", curl_easy_strerror(rv)); + _handle_completed_transaction(session); + _http_transaction_stop_timer(transaction); + return FALSE; } - _check_curl_multi_status(session); - return FALSE; + return TRUE; } -} - -gboolean __handle_socket_received_event_cb(GIOChannel *channel, GIOCondition condition, gpointer user_data) -{ - int fd, action, ret; - - if (condition & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) - return FALSE; - fd = g_io_channel_unix_get_fd(channel); + DBG("last transfer done"); - /* CURL_CSELECT_IN : 1, CURL_CSELECT_OUT: 2 */ - action = (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); - - ret = _handle_event(fd, action, user_data); - if (ret) - return TRUE; + _handle_completed_transaction(session); + _http_transaction_stop_timer(transaction); return FALSE; } -/* Clean up the __http_socket_info_h structure */ -static void _remove_socket_info(__http_socket_info_h *sock_info) -{ - if (!sock_info) - return; - - if (sock_info->event) { - g_source_remove(sock_info->event); - sock_info->event = 0; - } - if (sock_info->channel) { - g_io_channel_unref(sock_info->channel); - sock_info->channel = NULL; - } - g_free(sock_info); - sock_info = NULL; -} - -/* Assign socket information to a __http_socket_info_h structure */ -static void _set_socket_info(__http_socket_info_h *sock_info, curl_socket_t fd, CURL *curl_easy, int action, void *user_data) -{ - __http_session_h *session = (__http_session_h *)user_data; - GIOCondition condition = (action & CURL_POLL_IN ? G_IO_IN : 0) | (action & CURL_POLL_OUT ? G_IO_OUT : 0); - - sock_info->sockfd = fd; - sock_info->action = action; - sock_info->easy_handle = curl_easy; - if (sock_info->event) { - g_source_remove(sock_info->event); - sock_info->event = 0; - } - sock_info->event = g_io_add_watch(sock_info->channel, condition, __handle_socket_received_event_cb, session); -} - -/* Initialize a new Socket Info structure */ -static void _add_socket_info(curl_socket_t fd, CURL *curl_easy, int action, void *user_data) -{ - __http_session_h *session = (__http_session_h *)user_data; - __http_socket_info_h *sock_info = (__http_socket_info_h *)malloc(sizeof(__http_socket_info_h)); - - sock_info->session = session; - sock_info->channel = g_io_channel_unix_new(fd); - sock_info->event = 0; - _set_socket_info(sock_info, fd, curl_easy, action, session); - curl_multi_assign(session->multi_handle, fd, sock_info); -} - -int __handle_socket_cb(CURL *curl_easy, curl_socket_t fd, int action, void *user_data, void *socketp) -{ - __http_session_h *session = (__http_session_h *)user_data; - __http_socket_info_h *sock_info = (__http_socket_info_h*) socketp; - - static const char *actionstr[] = { "none", "IN", "OUT", "INOUT", "REMOVE"}; - - DBG("__handle_socket_cb: fd=%d easy_handle=%p action=%s", fd, curl_easy, actionstr[action]); - if (action == CURL_POLL_REMOVE) { - DBG("CURL_POLL_REMOVE\n"); - _remove_socket_info(sock_info); - } else { - if (!sock_info) { - DBG("Adding data: %s%s\n", action & CURL_POLL_IN ? "READ" : "", action & CURL_POLL_OUT ? "WRITE" : ""); - _add_socket_info(fd, curl_easy, action, session); - } else { - DBG("Changing action from %d to %d\n", sock_info->action, action); - _set_socket_info(sock_info, fd, curl_easy, action, session); - } - } - - return 0; -} -int __handle_timer_cb(CURLM *curl_multi, long timeout_ms, void *user_data) +int _generate_session_id(void) { - __http_session_h* session = (__http_session_h *)user_data; - - if (session->timer_event) { - g_source_remove(session->timer_event); - session->timer_event = 0; - } - - session->timer_event = g_timeout_add(timeout_ms , timer_expired_callback , session); + if (generated_session_id >= INT_MAX) + generated_session_id = 0; + else + generated_session_id++; - return 0; + return generated_session_id; } API int http_session_create(http_session_mode_e mode, http_session_h *http_session) @@ -291,12 +165,6 @@ API int http_session_create(http_session_mode_e mode, http_session_h *http_sessi session->active_transaction_count = 0; session->session_mode = mode; session->auto_redirect = FALSE; - session->timer_event = 0; - - curl_multi_setopt(session->multi_handle, CURLMOPT_SOCKETFUNCTION, __handle_socket_cb); - curl_multi_setopt(session->multi_handle, CURLMOPT_SOCKETDATA, session); - curl_multi_setopt(session->multi_handle, CURLMOPT_TIMERFUNCTION, __handle_timer_cb); - curl_multi_setopt(session->multi_handle, CURLMOPT_TIMERDATA, session); if (mode == HTTP_SESSION_MODE_PIPELINING) curl_multi_setopt(session->multi_handle, CURLMOPT_PIPELINING, 1L); @@ -325,11 +193,6 @@ API int http_session_destroy(http_session_h http_session) session->still_running = 0; session->auto_redirect = FALSE; - if (session->timer_event) { - g_source_remove(session->timer_event); - session->timer_event = 0; - } - free(session); session = NULL; } diff --git a/src/http_transaction.c b/src/http_transaction.c index ff61814..51d4ef7 100644 --- a/src/http_transaction.c +++ b/src/http_transaction.c @@ -212,6 +212,42 @@ int _set_authentication_info(http_transaction_h http_transaction) } //LCOV_EXCL_STOP +void _http_transaction_start_timer(guint msecs, gboolean(*callback) (gpointer), void *user_data) +{ + __http_transaction_h *transaction = (__http_transaction_h *)user_data; + guint t_id = 0; + + if (callback == NULL) + return; + + if (transaction->timer_event != 0) { + ERR("timer is already registered[%ld]", transaction->timer_event); + return; + } + + t_id = g_timeout_add(msecs, callback, user_data); + if (t_id == 0) { + ERR("Failed to add timer"); + return; + } + + DBG("g_timeout_add[%ld]", t_id); + + transaction->timer_event = t_id; +} + +void _http_transaction_stop_timer(__http_transaction_h *transaction) +{ + if (transaction->timer_event <= 0) + return; + + if (transaction->timer_event) { + DBG("g_source_remove[%ld]", transaction->timer_event); + g_source_remove(transaction->timer_event); + transaction->timer_event = 0; + } +} + int _transaction_submit(gpointer user_data) { __http_transaction_h *transaction = (__http_transaction_h *)user_data; @@ -351,7 +387,6 @@ int _transaction_submit(gpointer user_data) _get_request_body_size(transaction, &body_size); - /* Setup for POST method */ if (transaction->write_event) { if (content_len > 0 && content_len <= body_size) @@ -399,9 +434,6 @@ int _transaction_submit(gpointer user_data) curl_easy_setopt(transaction->easy_handle, CURLOPT_DEBUGFUNCTION, __http_debug_received); curl_easy_setopt(transaction->easy_handle, CURLOPT_ERRORBUFFER, transaction->error); - curl_easy_setopt(transaction->easy_handle, CURLOPT_OPENSOCKETDATA, &transaction->socket_fd); - curl_easy_setopt(transaction->easy_handle, CURLOPT_OPENSOCKETFUNCTION, __handle_opensocket_cb); - curl_easy_setopt(transaction->easy_handle, CURLOPT_PRIVATE, transaction); ret = curl_multi_add_handle(session->multi_handle, transaction->easy_handle); @@ -412,22 +444,13 @@ int _transaction_submit(gpointer user_data) ERR("Failed to add easy_handle to curl_multi_add_handle()"); } - return HTTP_ERROR_NONE; -} - -void* thread_callback(void *user_data) -{ - __http_transaction_h *transaction = (__http_transaction_h *)user_data; - - transaction->thread_loop = g_main_loop_new(NULL, FALSE); - - _transaction_submit(transaction); - - g_main_loop_run(transaction->thread_loop); - - DBG("thread exited.\n"); + ret = curl_multi_perform(session->multi_handle, &session->still_running); + if (ret == CURLM_OK) + _http_transaction_start_timer(5, curl_request_check, transaction); + else + print_curl_multi_errorCode(ret); - return NULL; + return ret; } API int http_session_open_transaction(http_session_h http_session, http_method_e method, http_transaction_h *http_transaction) @@ -444,11 +467,13 @@ API int http_session_open_transaction(http_session_h http_session, http_method_e } transaction->easy_handle = NULL; + transaction->timer_event = 0; transaction->interface_name = NULL; transaction->timeout = 0; transaction->verify_peer = 1; transaction->ca_path = g_strdup(HTTP_DEFAULT_CA_PATH); transaction->error[0] = '\0'; + transaction->cancel = 0; transaction->auth_required = FALSE; transaction->realm = NULL; @@ -513,9 +538,6 @@ API int http_session_open_transaction(http_session_h http_session, http_method_e transaction->header->header_list = NULL; transaction->header->hash_table = NULL; - transaction->thread = NULL; - transaction->thread_loop = NULL; - *http_transaction = (http_transaction_h)transaction; _add_transaction_to_list(transaction); @@ -537,9 +559,12 @@ API int http_transaction_submit(http_transaction_h http_transaction) _retvm_if(transaction->request->host_uri == NULL, HTTP_ERROR_INVALID_OPERATION, "URI isn't set!!"); - transaction->thread = g_thread_new("transaction_thread", thread_callback, transaction); + int ret = HTTP_ERROR_NONE; - return HTTP_ERROR_NONE; + if (_transaction_submit(transaction) != CURLM_OK) + ret = HTTP_ERROR_OPERATION_FAILED; + + return ret; } API int http_transaction_destroy(http_transaction_h http_transaction) @@ -565,18 +590,6 @@ API int http_transaction_destroy(http_transaction_h http_transaction) session->active_transaction_count--; if (transaction) { - if (transaction->thread_loop != NULL) { - g_main_loop_quit((GMainLoop*)transaction->thread_loop); - - g_main_loop_unref(transaction->thread_loop); - transaction->thread_loop = NULL; - } - - if (transaction->thread != NULL) { - g_thread_join(transaction->thread); - transaction->thread = NULL; - } - if (transaction->easy_handle != NULL) { curl_easy_cleanup(transaction->easy_handle); transaction->easy_handle = NULL; @@ -587,6 +600,11 @@ API int http_transaction_destroy(http_transaction_h http_transaction) transaction->interface_name = NULL; } + if (transaction->timer_event) { + g_source_remove(transaction->timer_event); + transaction->timer_event = 0; + } + transaction->timeout = 0; transaction->verify_peer = 0; @@ -660,14 +678,11 @@ API int http_transaction_destroy(http_transaction_h http_transaction) } if (response) { - if (response->status_text != NULL) { free(response->status_text); response->status_text = NULL; } - free(response); - } if (header) { @@ -677,9 +692,7 @@ API int http_transaction_destroy(http_transaction_h http_transaction) } if (header->hash_table != NULL) { - g_hash_table_remove_all(header->hash_table); - g_hash_table_destroy(header->hash_table); header->hash_table = NULL; } @@ -1096,6 +1109,7 @@ API int http_transaction_open_authentication(http_transaction_h http_transaction } auth_transaction->easy_handle = NULL; + auth_transaction->timer_event = 0; auth_transaction->interface_name = NULL; auth_transaction->ca_path = NULL; auth_transaction->error[0] = '\0'; @@ -1183,8 +1197,6 @@ API int http_transaction_open_authentication(http_transaction_h http_transaction auth_transaction->header->header_list = NULL; auth_transaction->header->hash_table = NULL; - auth_transaction->thread = NULL; - *http_auth_transaction = (http_transaction_h)auth_transaction; _add_transaction_to_list(auth_transaction); diff --git a/test/http_test.c b/test/http_test.c index 2130823..8df660b 100644 --- a/test/http_test.c +++ b/test/http_test.c @@ -94,13 +94,6 @@ void __transaction_completed_cb(http_transaction_h transaction, void *user_data) _register_callbacks(http_auth_transaction); http_transaction_submit(http_auth_transaction); } - - http_transaction_header_remove_field(transaction, "Content-Length"); - ret = http_transaction_destroy(transaction); - if (ret == HTTP_ERROR_NONE) DBG("Success to close transaction\n"); - else DBG("Fail to close transaction\n"); - - transaction = NULL; } void __transaction_aborted_cb(http_transaction_h transaction, int reason, void *user_data) @@ -108,20 +101,40 @@ void __transaction_aborted_cb(http_transaction_h transaction, int reason, void * PRG("transaction_aborted_cb", transaction); DBG("aborted reason: %d\n", reason); - int ret = http_transaction_destroy(transaction); - if (ret == HTTP_ERROR_NONE) DBG("Success to close transaction\n"); - else DBG("Fail to close transaction\n"); - - transaction = NULL; + switch (reason) { + case HTTP_ERROR_OPERATION_FAILED: + DBG("HTTP_ERROR_OPERATION_FAILED"); + break; + case HTTP_ERROR_COULDNT_RESOLVE_HOST: + DBG("HTTP_ERROR_COULDNT_RESOLVE_HOST"); + break; + case HTTP_ERROR_COULDNT_CONNECT: + DBG("HTTP_ERROR_COULDNT_CONNECT"); + break; + case HTTP_ERROR_OPERATION_TIMEDOUT: + DBG("HTTP_ERROR_OPERATION_TIMEDOUT"); + break; + case HTTP_ERROR_SSL_CONNECT_ERROR: + DBG("HTTP_ERROR_SSL_CONNECT_ERROR"); + break; + case HTTP_ERROR_CANCELED: + DBG("HTTP_ERROR_CANCELED"); + break; + default: + DBG("Unknown error"); + break; + } cancel = 0; + + return; } void __transaction_progress_cb(http_transaction_h transaction, double download_total, double download_now, double upload_total, double upload_now, void *user_data) { - PRG("__transaction_progress_cb", transaction); - - if (cancel) + if (cancel) { + DBG("Cancel"); http_transaction_cancel(transaction); + } } void _register_callbacks(http_transaction_h transaction) @@ -139,7 +152,7 @@ void _write_message_body(http_transaction_h transaction, const char *file_path) struct stat file_info; FILE *fp; size_t file_size; - size_t chunk_size = 1000; + size_t chunk_size = 50; char *buf = malloc(chunk_size); stat(file_path, &file_info); @@ -230,7 +243,6 @@ int test_simple_get(void) _register_callbacks(transaction); ret = http_transaction_submit(transaction); - if (ret != 0) { ERR("Fail to submit transaction", ret); return 0; @@ -275,7 +287,6 @@ int test_simple_post(void) int ret; http_transaction_h transaction; const char* post_msg = "name=tizen&project=capi-network-http"; - char field_value[15]; ret = http_session_open_transaction(session, HTTP_METHOD_POST, &transaction); if (ret != 0) { @@ -290,9 +301,6 @@ int test_simple_post(void) http_transaction_set_ready_to_write(transaction, TRUE); http_transaction_request_write_body(transaction, post_msg); - snprintf(field_value, sizeof(field_value), "%d", (int)strlen(post_msg)); - http_transaction_header_add_field(transaction, "Content-Length", field_value); - _register_callbacks(transaction); http_transaction_submit(transaction);