static da_result_t __cancel_download_with_slot_id(int slot_id) { da_result_t ret = DA_RESULT_OK; download_state_t download_state; stage_info *stage = DA_NULL; DA_LOG_FUNC_START(Default); _da_thread_mutex_lock (&mutex_download_state[slot_id]); download_state = GET_DL_STATE_ON_ID(slot_id); DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id)); if (download_state == DOWNLOAD_STATE_FINISH || download_state == DOWNLOAD_STATE_CANCELED) { DA_LOG_CRITICAL(Default, "Already download is finished. Do not send cancel request"); _da_thread_mutex_unlock (&mutex_download_state[slot_id]); return ret; } _da_thread_mutex_unlock (&mutex_download_state[slot_id]); stage = GET_DL_CURRENT_STAGE(slot_id); if (!stage) return DA_RESULT_OK; ret = request_to_cancel_http_download(stage); if (ret != DA_RESULT_OK) goto ERR; DA_LOG(Default, "Download cancel Successful for download id - %d", slot_id); ERR: return ret; }
da_result_t dereg_client_app(void) { client_noti_t *client_noti = DA_NULL; DA_LOG_FUNC_START(ClientNoti); client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t)); if (!client_noti) { DA_LOG_ERR(ClientNoti, "calloc fail"); return DA_ERR_FAIL_TO_MEMALLOC; } client_noti->download_id = DA_INVALID_ID; client_noti->noti_type = Q_CLIENT_NOTI_TYPE_TERMINATE; client_noti->next = DA_NULL; _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr)); if (client_app_mgr.is_thread_init != DA_TRUE) { DA_LOG_CRITICAL(ClientNoti, "try to cancel client mgr thread id[%lu]", client_app_mgr.thread_id); if (pthread_cancel(client_app_mgr.thread_id) < 0) { DA_LOG_ERR(ClientNoti, "cancel thread is failed!!!"); } } else { void *t_return = NULL; DA_LOG_VERBOSE(ClientNoti, "pushing Q_CLIENT_NOTI_TYPE_TERMINATE"); push_client_noti(client_noti); DA_LOG_CRITICAL(Thread, "===try to join client mgr thread id[%lu]===", client_app_mgr.thread_id); if (pthread_join(client_app_mgr.thread_id, &t_return) < 0) { DA_LOG_ERR(Thread, "join client thread is failed!!!"); } DA_LOG_CRITICAL(Thread, "===thread join return[%d]===", (char*)t_return); } _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr)); /* ToDo: This clean up should be done at the end of client_thread. */ client_app_mgr.client_app_info.is_using= DA_FALSE; client_app_mgr.client_app_info.is_manual_download = DA_FALSE; if(client_app_mgr.client_app_info.client_user_agent) { free(client_app_mgr.client_app_info.client_user_agent); client_app_mgr.client_app_info.client_user_agent = DA_NULL; } _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr)); client_app_mgr.is_thread_init = DA_FALSE; _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr)); _da_thread_mutex_destroy(&(client_app_mgr.mutex_client_mgr)); return DA_RESULT_OK; }
void push_client_noti(client_noti_t *client_noti) { client_queue_t *queue = DA_NULL; client_noti_t *head = DA_NULL; client_noti_t *pre = DA_NULL; client_noti_t *cur = DA_NULL; /* DA_LOG_FUNC_START(ClientNoti); */ if(!is_this_client_available()) { DA_LOG_ERR(ClientNoti, "invalid client"); return; } queue = &(client_app_mgr.client_queue); _da_thread_mutex_lock (&(queue->mutex_client_queue)); head = queue->client_q_head; if (!head) { queue->client_q_head = client_noti; } else { cur = head; while (cur->next) { pre = cur; cur = pre->next; } if (DA_TRUE == is_this_client_manual_download_type()) { cur->next = client_noti; } else if (client_noti->noti_type == Q_CLIENT_NOTI_TYPE_SEND_STATE) { cur->next = client_noti; } else { if (cur->noti_type == Q_CLIENT_NOTI_TYPE_SEND_STATE) { cur->next = client_noti; } else if (cur->noti_type == Q_CLIENT_NOTI_TYPE_UPDATE_DOWNLOADING_INFO) { /* For UI performance. If the update noti info is existed at queue, replace it with new update noti info */ if (cur->download_id == client_noti->download_id) { /* DA_LOG(ClientNoti, "exchange queue's tail and pushing item"); */ if (pre == DA_NULL) queue->client_q_head = client_noti; else pre->next = client_noti; destroy_client_noti(cur); } else { cur->next = client_noti; } } } } queue->having_data = DA_TRUE; __client_q_wake_up_without_lock(); _da_thread_mutex_unlock (&(queue->mutex_client_queue)); }
da_result_t send_user_noti_and_finish_download_flow( int slot_id, char *installed_path, char *etag) { da_result_t ret = DA_RESULT_OK; download_state_t download_state = DA_NULL; da_bool_t need_destroy_download_info = DA_FALSE; DA_LOG_FUNC_START(Default); _da_thread_mutex_lock (&mutex_download_state[slot_id]); download_state = GET_DL_STATE_ON_ID(slot_id); DA_LOG(Default, "state = %d", download_state); _da_thread_mutex_unlock (&mutex_download_state[slot_id]); switch (download_state) { case DOWNLOAD_STATE_FINISH: send_client_finished_info(slot_id, GET_DL_ID(slot_id), installed_path, DA_NULL, DA_RESULT_OK, get_http_status(slot_id)); need_destroy_download_info = DA_TRUE; break; case DOWNLOAD_STATE_CANCELED: send_client_finished_info(slot_id, GET_DL_ID(slot_id), installed_path, etag, DA_RESULT_USER_CANCELED, get_http_status(slot_id)); need_destroy_download_info = DA_TRUE; break; #ifdef PAUSE_EXIT case DOWNLOAD_STATE_PAUSED: need_destroy_download_info = DA_TRUE; break; #endif default: DA_LOG(Default, "download state = %d", download_state); break; } if (need_destroy_download_info == DA_TRUE) { destroy_download_info(slot_id); } else { DA_LOG_CRITICAL(Default, "download info is not destroyed"); } return ret; }
static da_result_t __resume_download_with_slot_id(int slot_id) { da_result_t ret = DA_RESULT_OK; download_state_t download_state; stage_info *stage = DA_NULL; DA_LOG_FUNC_START(Default); _da_thread_mutex_lock (&mutex_download_state[slot_id]); download_state = GET_DL_STATE_ON_ID(slot_id); DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id)); _da_thread_mutex_unlock (&mutex_download_state[slot_id]); stage = GET_DL_CURRENT_STAGE(slot_id); ret = request_to_resume_http_download(stage); if (ret != DA_RESULT_OK) goto ERR; DA_LOG(Default, "Download Resume Successful for download id-%d", slot_id); ERR: return ret; }
void __pop_client_noti(client_noti_t **out_client_noti) { client_queue_t *queue = DA_NULL; /* DA_LOG_FUNC_START(ClientNoti); */ queue = &(client_app_mgr.client_queue); _da_thread_mutex_lock (&(queue->mutex_client_queue)); if (queue->client_q_head) { *out_client_noti = queue->client_q_head; queue->client_q_head = queue->client_q_head->next; } else { *out_client_noti = DA_NULL; } if (queue->client_q_head == DA_NULL) { queue->having_data = DA_FALSE; } _da_thread_mutex_unlock (&(queue->mutex_client_queue)); }
static void *__thread_for_client_noti(void *data) { da_result_t ret = DA_RESULT_OK; da_bool_t need_wait = DA_TRUE; client_queue_t *queue = DA_NULL; client_noti_t *client_noti = DA_NULL; DA_LOG_FUNC_START(Thread); _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr)); client_app_mgr.is_thread_init = DA_TRUE; _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr)); queue = &(client_app_mgr.client_queue); DA_LOG(ClientNoti, "client queue = %p", queue); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL); pthread_cleanup_push(__thread_clean_up_handler_for_client_thread, (void *)DA_NULL); do { _da_thread_mutex_lock(&(queue->mutex_client_queue)); if (DA_FALSE == IS_CLIENT_Q_HAVING_DATA(queue)) { DA_LOG(Thread, "Sleep @ thread_for_client_noti!"); __client_q_goto_sleep_without_lock(); DA_LOG(Thread, "Woke up @ thread_for_client_noti"); } _da_thread_mutex_unlock(&(queue->mutex_client_queue)); do { __pop_client_noti(&client_noti); if (client_noti == DA_NULL) { DA_LOG_ERR(ClientNoti, "There is no data on client queue!"); ret = DA_ERR_INVALID_STATE; need_wait = DA_FALSE; } else { switch (client_noti->noti_type) { case Q_CLIENT_NOTI_TYPE_UPDATE_DL_INFO: { user_download_info_t *update_dl_info = DA_NULL;; update_dl_info = (user_download_info_t*)(&(client_noti->type.update_dl_info)); if (client_app_mgr.client_app_info.client_callback.update_dl_info_cb) { client_app_mgr.client_app_info.client_callback.update_dl_info_cb(update_dl_info, client_noti->user_data); DA_LOG(ClientNoti, "Update download info for download_id=%d, dl_req_id=%d, received size=%lu- DONE", client_noti->download_id, update_dl_info->da_dl_req_id, update_dl_info->file_size ); } } break; case Q_CLIENT_NOTI_TYPE_UPDATE_DOWNLOADING_INFO: { user_downloading_info_t *downloading_info = DA_NULL;; downloading_info = (user_downloading_info_t*)(&(client_noti->type.update_downloading_info)); if (client_app_mgr.client_app_info.client_callback.update_progress_info_cb) { client_app_mgr.client_app_info.client_callback.update_progress_info_cb(downloading_info, client_noti->user_data); DA_LOG(ClientNoti, "Update downloading info for download_id=%d, dl_req_id=%d, received size=%lu - DONE", client_noti->download_id, downloading_info->da_dl_req_id, downloading_info->total_received_size); } } break; case Q_CLIENT_NOTI_TYPE_SEND_STATE: { user_notify_info_t *da_state_info = DA_NULL; da_state_info = (user_notify_info_t *)(&(client_noti->type.da_state_info)); if (client_app_mgr.client_app_info.client_callback.user_noti_cb) { DA_LOG(ClientNoti, "User Noti info for download_id=%d, dl_req_id=%d, da_state=%d, err=%d", client_noti->download_id, da_state_info->da_dl_req_id, da_state_info->state, da_state_info->err); client_app_mgr.client_app_info.client_callback.user_noti_cb(da_state_info, client_noti->user_data); DA_LOG(ClientNoti, "User Noti info for download_id=%d, dl_req_id=%d, da_state=%d, err=%d - DONE", client_noti->download_id, da_state_info->da_dl_req_id, da_state_info->state, da_state_info->err); } } break; case Q_CLIENT_NOTI_TYPE_TERMINATE: DA_LOG_CRITICAL(ClientNoti, "Q_CLIENT_NOTI_TYPE_TERMINATE"); need_wait = DA_FALSE; break; } destroy_client_noti(client_noti); } if(DA_TRUE == need_wait) { _da_thread_mutex_lock(&(queue->mutex_client_queue)); if (DA_FALSE == IS_CLIENT_Q_HAVING_DATA(queue)) { _da_thread_mutex_unlock (&(queue->mutex_client_queue)); break; } else { _da_thread_mutex_unlock (&(queue->mutex_client_queue)); } } else { break; } } while (1); } while (DA_TRUE == need_wait); _da_thread_mutex_destroy(&(queue->mutex_client_queue)); _da_thread_cond_destroy(&(queue->cond_client_queue)); pthread_cleanup_pop(0); DA_LOG_CRITICAL(Thread, "=====thread_for_client_noti- EXIT====="); pthread_exit((void *)NULL); return DA_NULL; }