06e4b5f773ae131123ecf4e79c98c3af4bf07cf3
[platform/framework/web/download-provider.git] / agent / download-agent-dl-mgr.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <sys/syscall.h>
19 #include <signal.h>
20
21 #include "download-agent-dl-mgr.h"
22 #include "download-agent-dl-info.h"
23 #include "download-agent-http-mgr.h"
24
25 void __thread_clean_up_handler_for_start_download(void *arg)
26 {
27         DA_LOGI("cleanup for thread id[%lu]", pthread_self());
28 }
29
30 da_ret_t __download_content(da_info_t *da_info)
31 {
32         da_ret_t ret = DA_RESULT_OK;
33
34         DA_LOGV("");
35         if (!da_info) {
36                 DA_LOGE("NULL CHECK!: da_info");
37                 ret = DA_ERR_INVALID_ARGUMENT;
38                 return ret;
39         }
40
41         ret = request_http_download(da_info);
42         return ret;
43 }
44
45
46 static void *__thread_start_download(void *data)
47 {
48         da_info_t *da_info = DA_NULL;
49         req_info_t *req_info = DA_NULL;
50         int da_id = DA_INVALID_ID;
51
52 //      DA_LOGV("");
53
54         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL);
55
56         da_info = (da_info_t *)data;
57         NULL_CHECK_RET_OPT(da_info, DA_NULL);
58         req_info = da_info->req_info;
59         NULL_CHECK_RET_OPT(req_info, DA_NULL);
60
61         da_id = da_info->da_id;
62         pthread_cleanup_push(__thread_clean_up_handler_for_start_download, DA_NULL);
63         __download_content(da_info);
64         destroy_da_info(da_id);
65         pthread_cleanup_pop(0);
66         DA_LOGI("=====EXIT thread : da_id[%d]=====", da_id);
67         pthread_exit((void *)DA_NULL);
68         return DA_NULL;
69 }
70
71 da_ret_t start_download(da_info_t *da_info)
72 {
73         da_ret_t ret = DA_RESULT_OK;
74         pthread_attr_t thread_attr;
75         pthread_t tid;
76         if (pthread_attr_init(&thread_attr) != 0) {
77                 ret = DA_ERR_FAIL_TO_CREATE_THREAD;
78                 goto ERR;
79         }
80
81         if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) {
82                 ret = DA_ERR_FAIL_TO_CREATE_THREAD;
83                 goto ERR;
84         }
85
86         if (pthread_create(&(tid), &thread_attr,
87                         __thread_start_download, da_info) < 0) {
88                 DA_LOGE("Fail to make thread:id[%d]", da_info->da_id);
89                 ret = DA_ERR_FAIL_TO_CREATE_THREAD;
90         } else {
91                 if (tid < 1) {
92                         DA_LOGE("The thread start is failed before calling this");
93 // When http resource is leaked, the thread ID is initialized at error handling section of thread_start_download()
94 // Because the thread ID is initialized, the ptrhead_detach should not be called. This is something like timing issue between threads.
95 // thread info and basic_dl_input is freed at thread_start_download(). And it should not returns error code in this case.
96                         ret = DA_ERR_FAIL_TO_CREATE_THREAD;
97                         goto ERR;
98                 }
99         }
100         da_info->thread_id = tid;
101         DA_LOGI("Thread create:thread id[%lu]", da_info->thread_id);
102 ERR:
103         if (DA_RESULT_OK != ret) {
104                 destroy_da_info(da_info->da_id);
105         }
106         return ret;
107 }
108
109 da_ret_t cancel_download(int dl_id, da_bool_t is_enable_cb)
110 {
111         da_ret_t ret = DA_RESULT_OK;
112         da_info_t *da_info = DA_NULL;
113
114         DA_LOGV("");
115
116         ret = get_da_info_with_da_id(dl_id, &da_info);
117         if (ret != DA_RESULT_OK || !da_info) {
118                 return DA_ERR_INVALID_ARGUMENT;
119         }
120         da_info->is_cb_update = is_enable_cb;
121         ret = request_to_cancel_http_download(da_info);
122         if (ret != DA_RESULT_OK)
123                 goto ERR;
124         DA_LOGI("Download cancel Successful for download id[%d]", da_info->da_id);
125
126 ERR:
127         return ret;
128 }
129
130 da_ret_t suspend_download(int dl_id, da_bool_t is_enable_cb)
131 {
132         da_ret_t ret = DA_RESULT_OK;
133         da_info_t *da_info = DA_NULL;
134
135         DA_LOGV("");
136
137         ret = get_da_info_with_da_id(dl_id, &da_info);
138         if (ret != DA_RESULT_OK || !da_info) {
139                 return DA_ERR_INVALID_ARGUMENT;
140         }
141         da_info->is_cb_update = is_enable_cb;
142         ret = request_to_suspend_http_download(da_info);
143         if (ret != DA_RESULT_OK)
144                 goto ERR;
145         DA_LOGV("Download Suspend Successful for download id[%d]", da_info->da_id);
146 ERR:
147         return ret;
148
149 }
150
151 da_ret_t resume_download(int dl_id)
152 {
153         da_ret_t ret = DA_RESULT_OK;
154         da_info_t *da_info = DA_NULL;
155
156         DA_LOGV("");
157
158         ret = get_da_info_with_da_id(dl_id, &da_info);
159         if (ret != DA_RESULT_OK || !da_info) {
160                 return DA_ERR_INVALID_ARGUMENT;
161         }
162         da_info->is_cb_update = DA_TRUE;
163         ret = request_to_resume_http_download(da_info);
164         if (ret != DA_RESULT_OK)
165                 goto ERR;
166         DA_LOGV("Download Resume Successful for download id[%d]", da_info->da_id);
167 ERR:
168         return ret;
169 }
170