Retry read() when getting EAGAIN
[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 da_ret_t __download_content(da_info_t *da_info)
26 {
27         da_ret_t ret = DA_RESULT_OK;
28
29         DA_LOGV("");
30         if (!da_info) {
31                 DA_LOGE("NULL CHECK!: da_info");
32                 ret = DA_ERR_INVALID_ARGUMENT;
33                 return ret;
34         }
35
36         ret = request_http_download(da_info);
37         return ret;
38 }
39
40 static void *__thread_start_download(void *data)
41 {
42         da_info_t *da_info = DA_NULL;
43         req_info_t *req_info = DA_NULL;
44         int da_id = DA_INVALID_ID;
45
46 //      DA_LOGV("");
47
48         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL);
49
50         da_info = (da_info_t *)data;
51         NULL_CHECK_RET_OPT(da_info, DA_NULL);
52         req_info = da_info->req_info;
53         NULL_CHECK_RET_OPT(req_info, DA_NULL);
54
55         da_id = da_info->da_id;
56         __download_content(da_info);
57         destroy_da_info(da_id);
58         DA_LOGI("=====EXIT thread : da_id[%d]=====", da_id);
59         pthread_exit((void *)DA_NULL);
60         return DA_NULL;
61 }
62
63 da_ret_t start_download(da_info_t *da_info)
64 {
65         da_ret_t ret = DA_RESULT_OK;
66         pthread_attr_t thread_attr;
67         pthread_t tid;
68         if (pthread_attr_init(&thread_attr) != 0) {
69                 ret = DA_ERR_FAIL_TO_CREATE_THREAD;
70                 goto ERR;
71         }
72
73         if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) {
74                 ret = DA_ERR_FAIL_TO_CREATE_THREAD;
75                 goto ERR;
76         }
77
78         if (pthread_create(&(tid), &thread_attr,
79                         __thread_start_download, da_info) < 0) {
80                 DA_LOGE("Fail to make thread:id[%d]", da_info->da_id);
81                 ret = DA_ERR_FAIL_TO_CREATE_THREAD;
82         } else {
83                 if (tid < 1) {
84                         DA_LOGE("The thread start is failed before calling this");
85 // When http resource is leaked, the thread ID is initialized at error handling section of thread_start_download()
86 // Because the thread ID is initialized, the ptrhead_detach should not be called. This is something like timing issue between threads.
87 // thread info and basic_dl_input is freed at thread_start_download(). And it should not returns error code in this case.
88                         ret = DA_ERR_FAIL_TO_CREATE_THREAD;
89                         goto ERR;
90                 }
91         }
92         da_info->thread_id = tid;
93         DA_LOGI("Thread create:thread id[%lu]", da_info->thread_id);
94 ERR:
95         if (DA_RESULT_OK != ret)
96                 destroy_da_info(da_info->da_id);
97         return ret;
98 }
99
100 da_ret_t cancel_download(int dl_id, da_bool_t is_enable_cb)
101 {
102         da_ret_t ret = DA_RESULT_OK;
103         da_info_t *da_info = DA_NULL;
104
105         DA_LOGV("");
106
107         ret = get_da_info_with_da_id(dl_id, &da_info);
108         if (ret != DA_RESULT_OK || !da_info)
109                 return DA_ERR_INVALID_ARGUMENT;
110         da_info->is_cb_update = is_enable_cb;
111         ret = request_to_cancel_http_download(da_info);
112         if (ret != DA_RESULT_OK)
113                 goto ERR;
114         DA_LOGI("Download cancel Successful for download id[%d]", dl_id);
115
116 ERR:
117         return ret;
118 }
119
120 da_ret_t suspend_download(int dl_id, da_bool_t is_enable_cb)
121 {
122         da_ret_t ret = DA_RESULT_OK;
123         da_info_t *da_info = DA_NULL;
124
125         DA_LOGV("");
126
127         ret = get_da_info_with_da_id(dl_id, &da_info);
128         if (ret != DA_RESULT_OK || !da_info)
129                 return DA_ERR_INVALID_ARGUMENT;
130         da_info->is_cb_update = is_enable_cb;
131         ret = request_to_suspend_http_download(da_info);
132         if (ret != DA_RESULT_OK)
133                 goto ERR;
134         DA_LOGV("Download Suspend Successful for download id[%d]", da_info->da_id);
135 ERR:
136         return ret;
137
138 }
139
140 da_ret_t resume_download(int dl_id)
141 {
142         da_ret_t ret = DA_RESULT_OK;
143         da_info_t *da_info = DA_NULL;
144
145         DA_LOGV("");
146
147         ret = get_da_info_with_da_id(dl_id, &da_info);
148         if (ret != DA_RESULT_OK || !da_info)
149                 return DA_ERR_INVALID_ARGUMENT;
150         da_info->is_cb_update = DA_TRUE;
151         ret = request_to_resume_http_download(da_info);
152         if (ret != DA_RESULT_OK)
153                 goto ERR;
154         DA_LOGV("Download Resume Successful for download id[%d]", da_info->da_id);
155 ERR:
156         return ret;
157 }
158