blob: eaa5155265c4eb10ddf006a46af927c2bd54b5f3 [file] [log] [blame]
Dheeraj Shetty27976c42014-07-02 21:27:57 +02001/*
2* Copyright (C) 2014 The Android Open Source Project
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 "pb_decode.h"
18#include <pthread.h>
19#include <hardware/ril/librilutils/proto/sap-api.pb.h>
20#include <utils/Log.h>
21
22using namespace std;
23
24/**
25 * Template queue class to handling requests for a rild socket.
26 * <p>
27 * This class performs the following functions :
28 * <ul>
29 * <li>Enqueue.
30 * <li>Dequeue.
31 * <li>Check and dequeue.
32 * </ul>
33 */
34
35template <typename T>
36class Ril_queue {
37
38 /**
39 * Mutex attribute used in queue mutex initialization.
40 */
41 pthread_mutexattr_t attr;
42
43 /**
44 * Queue mutex variable for synchronized queue access.
45 */
46 pthread_mutex_t mutex_instance;
47
48 /**
49 * Condition to be waited on for dequeuing.
50 */
51 pthread_cond_t cond;
52
53 /**
54 * Front of the queue.
55 */
56 T *front;
57
58 public:
59
60 /**
61 * Remove the first element of the queue.
62 *
63 * @return first element of the queue.
64 */
65 T* dequeue(void);
66
67 /**
68 * Add a request to the front of the queue.
69 *
70 * @param Request to be added.
71 */
72 void enqueue(T* request);
73
74 /**
75 * Check if the queue is empty.
76 */
77 int empty(void);
78
79 /**
80 * Check and remove an element with a particular message id and token.
81 *
82 * @param Request message id.
83 * @param Request token.
84 */
85 int checkAndDequeue( MsgId id, int token);
86
87 /**
88 * Queue constructor.
89 */
90 Ril_queue(void);
91};
92
93template <typename T>
94Ril_queue<T>::Ril_queue(void) {
95 pthread_mutexattr_init(&attr);
96 pthread_mutex_init(&mutex_instance, &attr);
97 cond = PTHREAD_COND_INITIALIZER;
98 front = NULL;
99}
100
101template <typename T>
102T* Ril_queue<T>::dequeue(void) {
103 T* temp = NULL;
104
105 pthread_mutex_lock(&mutex_instance);
106 while(empty()) {
107 pthread_cond_wait(&cond, &mutex_instance);
108 }
109 temp = this->front;
110 if(NULL != this->front->p_next) {
111 this->front = this->front->p_next;
112 } else {
113 this->front = NULL;
114 }
115 pthread_mutex_unlock(&mutex_instance);
116
117 return temp;
118}
119
120template <typename T>
121void Ril_queue<T>::enqueue(T* request) {
122
123 pthread_mutex_lock(&mutex_instance);
124
125 if(NULL == this->front) {
126 this->front = request;
127 request->p_next = NULL;
128 } else {
129 request->p_next = this->front;
130 this->front = request;
131 }
132 pthread_cond_broadcast(&cond);
133 pthread_mutex_unlock(&mutex_instance);
134}
135
136template <typename T>
137int Ril_queue<T>::checkAndDequeue(MsgId id, int token) {
138 int ret = 0;
139 T* temp;
140
141 pthread_mutex_lock(&mutex_instance);
142
143 for(T **ppCur = &(this->front); *ppCur != NULL; ppCur = &((*ppCur)->p_next)) {
144 if (token == (*ppCur)->token && id == (*ppCur)->curr->id) {
145 ret = 1;
146 temp = *ppCur;
147 *ppCur = (*ppCur)->p_next;
148 free(temp);
149 break;
150 }
151 }
152
153 pthread_mutex_unlock(&mutex_instance);
154
155 return ret;
156}
157
158
159template <typename T>
160int Ril_queue<T>::empty(void) {
161
162 if(this->front == NULL) {
163 return 1;
164 } else {
165 return 0;
166 }
167}