4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * @file download-agent-http-queue.c
21 * @brief Including functions regarding http queue
22 * @author Keunsoon Lee(keunsoon.lee@samsung.com)
25 #include "download-agent-http-queue.h"
26 #include "download-agent-http-mgr.h"
27 #include "download-agent-debug.h"
28 #include "download-agent-pthread.h"
30 void init_q_event_data_http(q_event_t *q_event);
31 void init_q_event_control(q_event_t *q_event);
33 void Q_init_queue(queue_t *queue)
35 queue->having_data = DA_FALSE;
36 queue->control_head = DA_NULL;
37 queue->data_head = DA_NULL;
38 queue->queue_size = 0;
40 _da_thread_mutex_init(&(queue->mutex_queue), DA_NULL);
41 _da_thread_cond_init(&(queue->cond_queue), DA_NULL);
44 void Q_destroy_queue(queue_t *queue)
46 q_event_t *event = DA_NULL;
48 DA_LOG_FUNC_START(HTTPManager);
51 Q_pop_event(queue, &event);
52 Q_destroy_q_event(&event);
55 queue->having_data = DA_FALSE;
56 queue->control_head = DA_NULL;
57 queue->data_head = DA_NULL;
58 queue->queue_size = 0;
60 _da_thread_mutex_destroy(&(queue->mutex_queue));
61 _da_thread_cond_destroy(&(queue->cond_queue));
64 void Q_init_q_event(q_event_t *q_event)
66 switch(q_event->event_type) {
67 case Q_EVENT_TYPE_DATA_HTTP:
68 init_q_event_data_http(q_event);
70 case Q_EVENT_TYPE_CONTROL:
71 init_q_event_control(q_event);
76 q_event->next = DA_NULL;
79 void Q_destroy_q_event(q_event_t **in_q_event)
81 q_event_t *q_event = DA_NULL;
82 q_event = *in_q_event;
84 if(q_event == DA_NULL)
87 // DA_LOG(HTTPManager, "destroying size = %d", q_event->size);
89 switch(q_event->event_type) {
90 case Q_EVENT_TYPE_DATA_HTTP:
91 init_q_event_data_http(q_event);
93 q_event->next = DA_NULL;
96 case Q_EVENT_TYPE_CONTROL:
97 init_q_event_control(q_event);
99 q_event->next = DA_NULL;
105 da_result_t Q_make_control_event(q_event_type_control control_type, q_event_t **out_event)
107 da_result_t ret = DA_RESULT_OK;
108 q_event_t *q_event = DA_NULL;
110 DA_LOG_FUNC_START(HTTPManager);
112 q_event = (q_event_t *)calloc(1, sizeof(q_event_t));
113 if(q_event == DA_NULL) {
114 DA_LOG_ERR(HTTPManager, "calloc fail for q_event");
115 ret = DA_ERR_FAIL_TO_MEMALLOC;
117 *out_event = DA_NULL;
119 q_event->event_type = Q_EVENT_TYPE_CONTROL;
120 q_event->type.q_event_control.control_type = control_type;
121 q_event->next = DA_NULL;
123 *out_event = q_event;
129 da_result_t Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event)
131 da_result_t ret = DA_RESULT_OK;
132 q_event_t *q_event = DA_NULL;
134 // DA_LOG_FUNC_START(HTTPManager);
136 q_event = (q_event_t *)calloc(1, sizeof(q_event_t));
137 if(q_event == DA_NULL) {
138 DA_LOG_ERR(HTTPManager, "calloc fail for q_event");
139 ret = DA_ERR_FAIL_TO_MEMALLOC;
140 *out_event = DA_NULL;
142 q_event->event_type = Q_EVENT_TYPE_DATA_HTTP;
143 q_event->type.q_event_data_http.data_type = data_type;
144 q_event->next = DA_NULL;
146 *out_event = q_event;
148 // DA_LOG(HTTPManager, "made event = %x", *out_event);
155 da_result_t Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code)
157 da_result_t ret = DA_RESULT_OK;
159 // DA_LOG_FUNC_START(HTTPManager);
161 if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
162 DA_LOG_ERR(HTTPManager, "status_code can be set only for Q_EVENT_TYPE_DATA_HTTP.");
163 ret = DA_ERR_INVALID_ARGUMENT;
167 q_event->type.q_event_data_http.status_code = status_code;
169 // DA_LOG(HTTPManager, "status_code = %d, q_event = %x", q_event->type.q_event_data_http.status_code, q_event);
176 da_result_t Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data)
178 da_result_t ret = DA_RESULT_OK;
180 // DA_LOG_FUNC_START(HTTPManager);
182 if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
183 DA_LOG_ERR(HTTPManager, "http body can be set only for Q_EVENT_TYPE_DATA_HTTP.");
184 ret = DA_ERR_INVALID_ARGUMENT;
188 q_event->type.q_event_data_http.body_len = body_len;
189 q_event->type.q_event_data_http.body_data = body_data;
190 q_event->size = body_len;
192 // 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);
199 da_result_t Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type)
201 da_result_t ret = DA_RESULT_OK;
203 // DA_LOG_FUNC_START(HTTPManager);
205 if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
206 DA_LOG_ERR(HTTPManager, "error_type can be set only for Q_EVENT_TYPE_DATA_HTTP.");
207 ret = DA_ERR_INVALID_ARGUMENT;
211 q_event->type.q_event_data_http.error_type = error_type;
213 DA_LOG(HTTPManager, "error_type = %d, q_event = %p", q_event->type.q_event_data_http.error_type, q_event);
220 da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event)
222 da_bool_t b_ret = DA_FALSE;
223 queue_t *queue = (queue_t *)in_queue;
225 _da_thread_mutex_lock (&(queue->mutex_queue));
226 b_ret = Q_push_event_without_lock(in_queue, in_event);
227 _da_thread_mutex_unlock (&(queue->mutex_queue));
232 da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event)
234 da_bool_t b_ret = DA_FALSE;
235 queue_t *queue = (queue_t *)in_queue;
236 q_event_t *event = (q_event_t *)in_event;
237 q_event_type event_type;
238 q_event_t *head = DA_NULL;
239 q_event_t *cur = DA_NULL;
241 // DA_LOG_FUNC_START(HTTPManager);
242 // DA_LOG(HTTPManager, "queue = %x", in_queue);
244 event_type = event->event_type;
246 // _da_thread_mutex_lock (&(queue->mutex_queue));
248 if(event_type == Q_EVENT_TYPE_CONTROL) {
249 head = queue->control_head;
250 if(head == DA_NULL) {
251 queue->control_head = event;
255 while(cur->next != DA_NULL) {
262 if((event->size == 0) || (queue->queue_size < MAX_QUEUE_SIZE)) {
263 head = queue->data_head;
264 if(head == DA_NULL) {
265 queue->data_head = event;
268 while(cur->next != DA_NULL) {
274 queue->queue_size += event->size;
275 // DA_LOG(HTTPManager, "queue size is %d", queue->queue_size);
279 DA_LOG_CRITICAL(HTTPManager, "rejected event's size is %d queue_size %d", event->size, queue->queue_size);
284 queue->having_data = DA_TRUE;
286 // _da_thread_mutex_unlock (&(queue->mutex_queue));
290 void Q_pop_event(const queue_t *in_queue, q_event_t **out_event)
292 queue_t *queue = (queue_t*)in_queue;
294 // DA_LOG_FUNC_START(HTTPManager);
295 // DA_LOG(HTTPManager, "queue = %x", in_queue);
298 * 1. If there are control event, control event should pop first
299 * 2. If there is no control event, data event should pop
300 * 3. If there is no control and data event on queue, pop NULL
303 _da_thread_mutex_lock (&(queue->mutex_queue));
305 if(queue->control_head != DA_NULL) {/* Priority 1 */
306 *out_event = queue->control_head;
307 queue->control_head = queue->control_head->next;
309 if(queue->data_head != DA_NULL) {/* Priority 2 */
310 *out_event = queue->data_head;
311 queue->data_head = queue->data_head->next;
312 queue->queue_size -= (*out_event)->size;
313 // DA_LOG(HTTPManager, "queue size is %d", queue->queue_size);
314 } else {/* Priority 3 */
315 *out_event = DA_NULL;
319 if((queue->control_head == DA_NULL) && (queue->data_head == DA_NULL)) {
320 queue->having_data = DA_FALSE;
322 queue->having_data = DA_TRUE;
325 _da_thread_mutex_unlock (&(queue->mutex_queue));
329 void Q_goto_sleep(const queue_t *in_queue)
331 // DA_LOG_FUNC_START(HTTPManager);
332 DA_LOG(HTTPManager, "sleep for %p", in_queue);
334 //** SHOULD NOT use mutex **//
336 // _da_thread_mutex_lock (&(in_queue->mutex_queue));
337 _da_thread_cond_wait((pthread_cond_t*)(&(in_queue->cond_queue)),(pthread_mutex_t*) (&(in_queue->mutex_queue)));
338 // _da_thread_mutex_unlock (&(in_queue->mutex_queue));
341 void Q_wake_up(const queue_t *in_queue)
343 // DA_LOG_FUNC_START(HTTPManager);
344 DA_LOG(HTTPManager, "wake up for %p", in_queue);
346 //** SHOULD NOT use mutex **//
348 // _da_thread_mutex_lock (&(in_queue->mutex_queue));
349 _da_thread_cond_signal((pthread_cond_t*)(&(in_queue->cond_queue)));
350 // _da_thread_mutex_unlock (&(in_queue->mutex_queue));
353 void init_q_event_data_http(q_event_t *q_event)
355 q_event_data_http_t *q_event_data_http;
357 // DA_LOG_FUNC_START(HTTPManager);
359 if(q_event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
360 q_event_data_http = &(q_event->type.q_event_data_http);
362 if(q_event_data_http) {
363 q_event_data_http->status_code = DA_NULL;
364 if(q_event_data_http->http_response_msg) {
365 http_msg_response_destroy(&(q_event_data_http->http_response_msg));
368 if(q_event_data_http->body_len > 0 ) {
369 if (q_event_data_http->body_data) {
370 free(q_event_data_http->body_data);
371 q_event_data_http->body_data = DA_NULL;
374 q_event_data_http->error_type = DA_NULL;
379 void init_q_event_control(q_event_t *q_event)
381 q_event_control_t *q_event_control;
383 // DA_LOG_FUNC_START(HTTPManager);
385 if(q_event->event_type == Q_EVENT_TYPE_CONTROL) {
386 q_event_control = &(q_event->type.q_event_control);
387 if(q_event_control) {
388 q_event_control->control_type = DA_NULL;