b81f9d8e07e499fa4741c131b4042807beba8ad2
[platform/framework/web/download-provider.git] / src / agent / download-agent-http-queue.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 "download-agent-http-queue.h"
18 #include "download-agent-http-mgr.h"
19 #include "download-agent-debug.h"
20 #include "download-agent-pthread.h"
21
22 void init_q_event_data_http(q_event_t *q_event);
23 void init_q_event_control(q_event_t *q_event);
24
25 void Q_init_queue(queue_t *queue)
26 {
27         queue->having_data = DA_FALSE;
28         queue->control_head = DA_NULL;
29         queue->data_head = DA_NULL;
30         queue->queue_size = 0;
31
32         _da_thread_mutex_init(&(queue->mutex_queue), DA_NULL);
33         _da_thread_cond_init(&(queue->cond_queue), DA_NULL);
34 }
35
36 void Q_destroy_queue(queue_t *queue)
37 {
38         q_event_t *event = DA_NULL;
39
40         DA_LOG_FUNC_START(HTTPManager);
41
42         do {
43                 Q_pop_event(queue, &event);
44                 Q_destroy_q_event(&event);
45         } while(event);
46
47         queue->having_data = DA_FALSE;
48         queue->control_head = DA_NULL;
49         queue->data_head = DA_NULL;
50         queue->queue_size = 0;
51
52         _da_thread_mutex_destroy(&(queue->mutex_queue));
53         _da_thread_cond_destroy(&(queue->cond_queue));
54 }
55
56 void Q_init_q_event(q_event_t *q_event)
57 {
58         switch(q_event->event_type) {
59                 case Q_EVENT_TYPE_DATA_HTTP:
60                         init_q_event_data_http(q_event);
61                         break;
62
63                 case Q_EVENT_TYPE_DATA_DRM:
64                         break;
65
66                 case Q_EVENT_TYPE_CONTROL:
67                         init_q_event_control(q_event);
68                         break;
69         }
70
71         q_event->size = 0;
72         q_event->next = DA_NULL;
73 }
74
75 void Q_destroy_q_event(q_event_t **in_q_event)
76 {
77         q_event_t *q_event = DA_NULL;
78         q_event = *in_q_event;
79
80         if(q_event == DA_NULL)
81                 return;
82
83 //      DA_LOG(HTTPManager, "destroying size = %d", q_event->size);
84
85         switch(q_event->event_type)     {
86                 case Q_EVENT_TYPE_DATA_HTTP:
87                         init_q_event_data_http(q_event);
88                         q_event->size = 0;
89                         q_event->next = DA_NULL;
90                         free(q_event);
91                         break;
92
93                 case Q_EVENT_TYPE_DATA_DRM:
94                         q_event->size = 0;
95                         q_event->next = DA_NULL;
96                         free(q_event);
97                         break;
98
99                 case Q_EVENT_TYPE_CONTROL:
100                         init_q_event_control(q_event);
101                         q_event->size = 0;
102                         q_event->next = DA_NULL;
103                         free(q_event);
104                         break;
105         }
106 }
107
108 da_result_t  Q_make_control_event(q_event_type_control control_type, q_event_t **out_event)
109 {
110         da_result_t  ret = DA_RESULT_OK;
111         q_event_t *q_event = DA_NULL;
112
113         DA_LOG_FUNC_START(HTTPManager);
114
115         q_event = (q_event_t *)calloc(1, sizeof(q_event_t));
116         if(q_event == DA_NULL) {
117                 DA_LOG_ERR(HTTPManager, "calloc fail for q_event");
118                 ret = DA_ERR_FAIL_TO_MEMALLOC;
119
120                 *out_event = DA_NULL;
121         } else {
122                 q_event->event_type = Q_EVENT_TYPE_CONTROL;
123                 q_event->type.q_event_control.control_type = control_type;
124                 q_event->next = DA_NULL;
125
126                 *out_event = q_event;
127         }
128
129         return ret;
130 }
131
132 da_result_t  Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event)
133 {
134         da_result_t  ret = DA_RESULT_OK;
135         q_event_t *q_event = DA_NULL;
136
137 //      DA_LOG_FUNC_START(HTTPManager);
138
139         q_event = (q_event_t *)calloc(1, sizeof(q_event_t));
140         if(q_event == DA_NULL) {
141                 DA_LOG_ERR(HTTPManager, "calloc fail for q_event");
142                 ret = DA_ERR_FAIL_TO_MEMALLOC;
143                 *out_event = DA_NULL;
144         } else {
145                 q_event->event_type = Q_EVENT_TYPE_DATA_HTTP;
146                 q_event->type.q_event_data_http.data_type = data_type;
147                 q_event->next = DA_NULL;
148
149                 *out_event = q_event;
150
151 //              DA_LOG(HTTPManager, "made event = %x", *out_event);
152         }
153
154         return ret;
155
156 }
157
158 da_result_t  Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code)
159 {
160         da_result_t  ret = DA_RESULT_OK;
161
162 //      DA_LOG_FUNC_START(HTTPManager);
163
164         if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
165                 DA_LOG_ERR(HTTPManager, "status_code can be set only for Q_EVENT_TYPE_DATA_HTTP.");
166                 ret = DA_ERR_INVALID_ARGUMENT;
167                 goto ERR;
168         }
169
170         q_event->type.q_event_data_http.status_code = status_code;
171
172 //      DA_LOG(HTTPManager, "status_code = %d, q_event = %x", q_event->type.q_event_data_http.status_code, q_event);
173
174 ERR:
175         return ret;
176
177 }
178
179 da_result_t  Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data)
180 {
181         da_result_t  ret = DA_RESULT_OK;
182
183 //      DA_LOG_FUNC_START(HTTPManager);
184
185         if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
186                 DA_LOG_ERR(HTTPManager, "http body can be set only for Q_EVENT_TYPE_DATA_HTTP.");
187                 ret = DA_ERR_INVALID_ARGUMENT;
188                 goto ERR;
189         }
190
191         q_event->type.q_event_data_http.body_len = body_len;
192         q_event->type.q_event_data_http.body_data = body_data;
193         q_event->size = body_len;
194
195 //      DA_LOG(HTTPManager, "body_len = %d, body_data = %x, q_event = %x", q_event->type.q_event_data_http.body_len, q_event->type.q_event_data_http.body_data, q_event);
196
197 ERR:
198         return ret;
199
200 }
201
202 da_result_t  Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type)
203 {
204         da_result_t  ret = DA_RESULT_OK;
205
206 //      DA_LOG_FUNC_START(HTTPManager);
207
208         if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
209                 DA_LOG_ERR(HTTPManager, "error_type can be set only for Q_EVENT_TYPE_DATA_HTTP.");
210                 ret = DA_ERR_INVALID_ARGUMENT;
211                 goto ERR;
212         }
213
214         q_event->type.q_event_data_http.error_type = error_type;
215
216         DA_LOG(HTTPManager, "error_type = %d, q_event = %p", q_event->type.q_event_data_http.error_type, q_event);
217
218 ERR:
219         return ret;
220
221 }
222
223 da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event)
224 {
225         da_bool_t b_ret = DA_FALSE;
226         queue_t *queue = (queue_t *)in_queue;
227
228         _da_thread_mutex_lock (&(queue->mutex_queue));
229         b_ret = Q_push_event_without_lock(in_queue, in_event);
230         _da_thread_mutex_unlock (&(queue->mutex_queue));
231
232         return b_ret;
233 }
234
235 da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event)
236 {
237         da_bool_t b_ret = DA_FALSE;
238         queue_t *queue = (queue_t *)in_queue;
239         q_event_t *event = (q_event_t *)in_event;
240         q_event_type event_type;
241         q_event_t *head = DA_NULL;
242         q_event_t *cur = DA_NULL;
243
244 //      DA_LOG_FUNC_START(HTTPManager);
245 //      DA_LOG(HTTPManager, "queue = %x", in_queue);
246
247         event_type = event->event_type;
248
249 //      _da_thread_mutex_lock (&(queue->mutex_queue));
250
251         if(event_type == Q_EVENT_TYPE_CONTROL) {
252                 head = queue->control_head;
253                 if(head == DA_NULL) {
254                         queue->control_head = event;
255                 } else {
256                         cur = head;
257
258                         while(cur->next != DA_NULL) {
259                                 cur = cur->next;
260                         }
261                         cur->next= event;
262                 }
263                 b_ret = DA_TRUE;
264         } else {
265                 if((event->size == 0) || (queue->queue_size < MAX_QUEUE_SIZE)) {
266                         head = queue->data_head;
267                         if(head == DA_NULL)     {
268                                 queue->data_head = event;
269                         } else {
270                                 cur = head;
271                                 while(cur->next != DA_NULL) {
272                                         cur = cur->next;
273                                 }
274                                 cur->next= event ;
275                         }
276
277                         queue->queue_size += event->size;
278 //                      DA_LOG(HTTPManager, "queue size is %d", queue->queue_size);
279
280                         b_ret = DA_TRUE;
281                 } else {
282                         DA_LOG_CRITICAL(HTTPManager, "rejected event's size is %d queue_size %d", event->size, queue->queue_size);
283                         b_ret = DA_FALSE;
284                 }
285         }
286
287         queue->having_data = DA_TRUE;
288         Q_wake_up(queue);
289 //      _da_thread_mutex_unlock (&(queue->mutex_queue));
290         return b_ret;
291 }
292
293 void Q_pop_event(const queue_t *in_queue, q_event_t **out_event)
294 {
295         queue_t *queue = (queue_t*)in_queue;
296
297 //      DA_LOG_FUNC_START(HTTPManager);
298 //      DA_LOG(HTTPManager, "queue = %x", in_queue);
299
300         /** Pop Priority
301           * 1. If there are control event, control event should pop first
302           * 2. If there is no control event, data event should pop
303           * 3. If there is no control and data event on queue, pop NULL
304          */
305
306         _da_thread_mutex_lock (&(queue->mutex_queue));
307
308         if(queue->control_head != DA_NULL) {/* Priority 1 */
309                 *out_event = queue->control_head;
310                 queue->control_head = queue->control_head->next;
311         } else {
312                 if(queue->data_head != DA_NULL) {/* Priority 2 */
313                         *out_event = queue->data_head;
314                         queue->data_head = queue->data_head->next;
315                         queue->queue_size -= (*out_event)->size;
316 //                      DA_LOG(HTTPManager, "queue size is %d", queue->queue_size);
317                 } else {/* Priority 3 */
318                         *out_event = DA_NULL;
319                 }
320         }
321
322         if((queue->control_head == DA_NULL) && (queue->data_head == DA_NULL)) {
323                 queue->having_data = DA_FALSE;
324         } else {
325                 queue->having_data = DA_TRUE;
326         }
327
328         _da_thread_mutex_unlock (&(queue->mutex_queue));
329
330 }
331
332 void Q_goto_sleep(const queue_t *in_queue)
333 {
334 //      DA_LOG_FUNC_START(HTTPManager);
335         DA_LOG_VERBOSE(HTTPManager, "sleep for %p", in_queue);
336
337 //** SHOULD NOT use mutex **//
338
339 //      _da_thread_mutex_lock (&(in_queue->mutex_queue));
340         _da_thread_cond_wait((pthread_cond_t*)(&(in_queue->cond_queue)),(pthread_mutex_t*) (&(in_queue->mutex_queue)));
341 //      _da_thread_mutex_unlock (&(in_queue->mutex_queue));
342 }
343
344 void Q_wake_up(const queue_t *in_queue)
345 {
346 //      DA_LOG_FUNC_START(HTTPManager);
347         DA_LOG_VERBOSE(HTTPManager, "wake up for %p", in_queue);
348
349 //** SHOULD NOT use mutex **//
350
351 //      _da_thread_mutex_lock (&(in_queue->mutex_queue));
352         _da_thread_cond_signal((pthread_cond_t*)(&(in_queue->cond_queue)));
353 //      _da_thread_mutex_unlock (&(in_queue->mutex_queue));
354 }
355
356 void init_q_event_data_http(q_event_t *q_event)
357 {
358         q_event_data_http_t *q_event_data_http;
359
360 //      DA_LOG_FUNC_START(HTTPManager);
361
362         if(q_event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
363                 q_event_data_http = &(q_event->type.q_event_data_http);
364
365                 if(q_event_data_http) {
366                         q_event_data_http->status_code = DA_NULL;
367                         if(q_event_data_http->http_response_msg) {
368                                 http_msg_response_destroy(&(q_event_data_http->http_response_msg));
369                         }
370
371                         if(q_event_data_http->body_len > 0 ) {
372                                 if (q_event_data_http->body_data) {
373                                         free(q_event_data_http->body_data);
374                                         q_event_data_http->body_data = DA_NULL;
375                                 }
376                         }
377                         q_event_data_http->error_type = DA_NULL;
378                 }
379         }
380 }
381
382 void init_q_event_control(q_event_t *q_event)
383 {
384         q_event_control_t *q_event_control;
385
386 //      DA_LOG_FUNC_START(HTTPManager);
387
388         if(q_event->event_type == Q_EVENT_TYPE_CONTROL) {
389                 q_event_control = &(q_event->type.q_event_control);
390                 if(q_event_control) {
391                         q_event_control->control_type = DA_NULL;
392                 }
393         }
394
395 }