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