2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
22 void init_q_event_data_http(q_event_t *q_event);
23 void init_q_event_control(q_event_t *q_event);
25 void Q_init_queue(queue_t *queue)
27 queue->having_data = DA_FALSE;
28 queue->control_head = DA_NULL;
29 queue->data_head = DA_NULL;
30 queue->queue_size = 0;
32 _da_thread_mutex_init(&(queue->mutex_queue), DA_NULL);
33 _da_thread_cond_init(&(queue->cond_queue), DA_NULL);
36 void Q_destroy_queue(queue_t *queue)
38 q_event_t *event = DA_NULL;
40 DA_LOG_FUNC_START(HTTPManager);
43 Q_pop_event(queue, &event);
44 Q_destroy_q_event(&event);
47 queue->having_data = DA_FALSE;
48 queue->control_head = DA_NULL;
49 queue->data_head = DA_NULL;
50 queue->queue_size = 0;
52 _da_thread_mutex_destroy(&(queue->mutex_queue));
53 _da_thread_cond_destroy(&(queue->cond_queue));
56 void Q_init_q_event(q_event_t *q_event)
58 switch(q_event->event_type) {
59 case Q_EVENT_TYPE_DATA_HTTP:
60 init_q_event_data_http(q_event);
63 case Q_EVENT_TYPE_DATA_DRM:
66 case Q_EVENT_TYPE_CONTROL:
67 init_q_event_control(q_event);
72 q_event->next = DA_NULL;
75 void Q_destroy_q_event(q_event_t **in_q_event)
77 q_event_t *q_event = DA_NULL;
78 q_event = *in_q_event;
80 if(q_event == DA_NULL)
83 // DA_LOG(HTTPManager, "destroying size = %d", q_event->size);
85 switch(q_event->event_type) {
86 case Q_EVENT_TYPE_DATA_HTTP:
87 init_q_event_data_http(q_event);
89 q_event->next = DA_NULL;
93 case Q_EVENT_TYPE_DATA_DRM:
95 q_event->next = DA_NULL;
99 case Q_EVENT_TYPE_CONTROL:
100 init_q_event_control(q_event);
102 q_event->next = DA_NULL;
108 da_result_t Q_make_control_event(q_event_type_control control_type, q_event_t **out_event)
110 da_result_t ret = DA_RESULT_OK;
111 q_event_t *q_event = DA_NULL;
113 DA_LOG_FUNC_START(HTTPManager);
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;
120 *out_event = DA_NULL;
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;
126 *out_event = q_event;
132 da_result_t Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event)
134 da_result_t ret = DA_RESULT_OK;
135 q_event_t *q_event = DA_NULL;
137 // DA_LOG_FUNC_START(HTTPManager);
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;
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;
149 *out_event = q_event;
151 // DA_LOG(HTTPManager, "made event = %x", *out_event);
158 da_result_t Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code)
160 da_result_t ret = DA_RESULT_OK;
162 // DA_LOG_FUNC_START(HTTPManager);
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;
170 q_event->type.q_event_data_http.status_code = status_code;
172 // DA_LOG(HTTPManager, "status_code = %d, q_event = %x", q_event->type.q_event_data_http.status_code, q_event);
179 da_result_t Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data)
181 da_result_t ret = DA_RESULT_OK;
183 // DA_LOG_FUNC_START(HTTPManager);
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;
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;
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);
202 da_result_t Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type)
204 da_result_t ret = DA_RESULT_OK;
206 // DA_LOG_FUNC_START(HTTPManager);
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;
214 q_event->type.q_event_data_http.error_type = error_type;
216 DA_LOG(HTTPManager, "error_type = %d, q_event = %p", q_event->type.q_event_data_http.error_type, q_event);
223 da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event)
225 da_bool_t b_ret = DA_FALSE;
226 queue_t *queue = (queue_t *)in_queue;
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));
235 da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event)
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;
244 // DA_LOG_FUNC_START(HTTPManager);
245 // DA_LOG(HTTPManager, "queue = %x", in_queue);
247 event_type = event->event_type;
249 // _da_thread_mutex_lock (&(queue->mutex_queue));
251 if(event_type == Q_EVENT_TYPE_CONTROL) {
252 head = queue->control_head;
253 if(head == DA_NULL) {
254 queue->control_head = event;
258 while(cur->next != DA_NULL) {
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;
271 while(cur->next != DA_NULL) {
277 queue->queue_size += event->size;
278 // DA_LOG(HTTPManager, "queue size is %d", queue->queue_size);
282 DA_LOG_CRITICAL(HTTPManager, "rejected event's size is %d queue_size %d", event->size, queue->queue_size);
287 queue->having_data = DA_TRUE;
289 // _da_thread_mutex_unlock (&(queue->mutex_queue));
293 void Q_pop_event(const queue_t *in_queue, q_event_t **out_event)
295 queue_t *queue = (queue_t*)in_queue;
297 // DA_LOG_FUNC_START(HTTPManager);
298 // DA_LOG(HTTPManager, "queue = %x", in_queue);
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
306 _da_thread_mutex_lock (&(queue->mutex_queue));
308 if(queue->control_head != DA_NULL) {/* Priority 1 */
309 *out_event = queue->control_head;
310 queue->control_head = queue->control_head->next;
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;
322 if((queue->control_head == DA_NULL) && (queue->data_head == DA_NULL)) {
323 queue->having_data = DA_FALSE;
325 queue->having_data = DA_TRUE;
328 _da_thread_mutex_unlock (&(queue->mutex_queue));
332 void Q_goto_sleep(const queue_t *in_queue)
334 // DA_LOG_FUNC_START(HTTPManager);
335 DA_LOG_VERBOSE(HTTPManager, "sleep for %p", in_queue);
337 //** SHOULD NOT use mutex **//
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));
344 void Q_wake_up(const queue_t *in_queue)
346 // DA_LOG_FUNC_START(HTTPManager);
347 DA_LOG_VERBOSE(HTTPManager, "wake up for %p", in_queue);
349 //** SHOULD NOT use mutex **//
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));
356 void init_q_event_data_http(q_event_t *q_event)
358 q_event_data_http_t *q_event_data_http;
360 // DA_LOG_FUNC_START(HTTPManager);
362 if(q_event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
363 q_event_data_http = &(q_event->type.q_event_data_http);
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));
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;
377 q_event_data_http->error_type = DA_NULL;
382 void init_q_event_control(q_event_t *q_event)
384 q_event_control_t *q_event_control;
386 // DA_LOG_FUNC_START(HTTPManager);
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;