2 * Copyright (c) 2013 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.
19 #include <download-provider-queue.h>
20 #include <download-provider-log.h>
21 #include <download-provider-pthread.h>
22 #include <download-provider-client.h>
23 #include <download-provider-client-manager.h>
26 * 1. push : at the tail of linked list
27 * 2. pop : at the head of linked list
28 * 3. priority push : at the head of linked list
29 * 4. in pop, check client of slot, search request by download_id
32 //dp_queue_fmt *g_dp_queue = NULL; // head of linked list
33 static pthread_mutex_t g_dp_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
35 // normal . push at the tail of queue.
36 int dp_queue_push(dp_queue_fmt **queue, void *slot, void *request)
39 TRACE_ERROR("check memory address of queue");
42 dp_client_slots_fmt *baseslot = slot;
43 dp_request_fmt *new_request = request;
44 if (slot == NULL || request == NULL || new_request->id <= 0) {
45 TRACE_ERROR("check client and request memory address");
47 } else if (new_request->id <= 0) {
48 TRACE_ERROR("check slot or download id:%d", new_request->id);
50 } else if (new_request->state != DP_STATE_QUEUED) {
51 TRACE_ERROR("check id:%d state:%s", new_request->id, dp_print_state(new_request->state));
55 CLIENT_MUTEX_LOCK(&g_dp_queue_mutex);
56 // search the tail of queue
58 dp_queue_fmt *tailp = *queue;
59 dp_queue_fmt *prevp = NULL;
60 TRACE_DEBUG("queue req slot:%p request:%p id:%d", slot, request, (request == NULL ? 0 : new_request->id));
61 for (; tailp != NULL; i++) {
62 dp_request_fmt *qrequestp = tailp->request;
63 if (tailp->slot == NULL || tailp->request == NULL ||
64 qrequestp->state != DP_STATE_QUEUED) {
65 TRACE_DEBUG("queue error %d slot:%p request:%p id:%d", i, tailp->slot, tailp->request, (tailp->request == NULL ? 0 : ((dp_request_fmt *)tailp->request)->id));
66 } else if (tailp->slot == slot && tailp->request == request && qrequestp->id == new_request->id) {
67 TRACE_INFO("queue duplicte %d slot:%p request:%p id:%d", i, slot, request, new_request->id);
68 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
71 TRACE_INFO("queue info %d slot:%p request:%p id:%d %s", i, tailp->slot, tailp->request, ((dp_request_fmt *)tailp->request)->id, ((dp_client_slots_fmt *)tailp->slot)->pkgname);
76 dp_queue_fmt *new_queue = (dp_queue_fmt *)malloc(sizeof(dp_queue_fmt));
77 if (new_queue != NULL) {
78 new_queue->slot = slot;
79 new_queue->request = request;
80 new_queue->next = NULL;
84 prevp->next = new_queue;
86 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
89 TRACE_DEBUG("queue push %d info:%s id:%d", i, baseslot->pkgname, new_request->id);
90 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
94 int dp_queue_pop(dp_queue_fmt **queue, void **slot, void **request)
97 TRACE_ERROR("check memory address of queue");
100 if (slot == NULL || request == NULL) {
101 TRACE_ERROR("check client and request memory address");
105 int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_queue_mutex);
107 TRACE_DEBUG("skip queue is used by other thread");
110 if (*queue == NULL) {
111 //TRACE_DEBUG("queue empty");
112 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
115 // get a head of queue
121 dp_client_slots_fmt *slotp = popp->slot;
122 dp_request_fmt *requestp = popp->request;
123 if (slotp == NULL || requestp == NULL ||
124 requestp->state != DP_STATE_QUEUED) {
125 TRACE_DEBUG("queue error slot:%p request:%p id:%d", popp->slot, popp->request, (requestp == NULL ? 0 : requestp->id));
128 TRACE_INFO("queue pop slot:%p request:%p id:%d %s", popp->slot, popp->request, requestp->id, slotp->pkgname);
130 *request = popp->request;
135 } while (*queue != NULL); // if meet the tail of queue
136 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
140 void dp_queue_clear(dp_queue_fmt **queue, void *request)
143 TRACE_ERROR("check memory address of queue");
146 if (request == NULL) {
147 TRACE_ERROR("check client and request memory address");
150 CLIENT_MUTEX_LOCK(&g_dp_queue_mutex);
152 dp_queue_fmt *tailp = *queue;
153 dp_queue_fmt *prevp = NULL;
154 TRACE_DEBUG("queue clear req request:%p id:%d", request, (request == NULL ? 0 : ((dp_request_fmt *)request)->id));
155 for (; tailp != NULL; i++) {
156 dp_request_fmt *requestp = tailp->request;
157 TRACE_DEBUG("queue info %d request:%p id:%d", i, requestp, (requestp == NULL ? 0 : requestp->id));
158 if (requestp == request) {
161 *queue = tailp->next;
163 prevp->next = tailp->next;
164 TRACE_DEBUG("queue clear this %d request:%p id:%d", i, requestp, (requestp == NULL ? 0 : requestp->id));
171 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
174 void dp_queue_clear_all(dp_queue_fmt **queue)
177 TRACE_ERROR("check memory address of queue");
180 CLIENT_MUTEX_LOCK(&g_dp_queue_mutex);
181 if (queue == NULL || *queue == NULL) {
182 TRACE_DEBUG("queue empty");
183 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
186 // get a head of queue
188 dp_queue_fmt *popp = *queue;
190 TRACE_DEBUG("queue clear slot:%p request:%p id:%d", popp->slot, popp->request, (popp->request == NULL ? 0 : ((dp_request_fmt *)popp->request)->id));
192 } while (*queue != NULL); // if meet the tail of queue
193 CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);