1*062a843bSAndroid Build Coastguard Worker /* 2*062a843bSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*062a843bSAndroid Build Coastguard Worker * 4*062a843bSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*062a843bSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*062a843bSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*062a843bSAndroid Build Coastguard Worker * 8*062a843bSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*062a843bSAndroid Build Coastguard Worker * 10*062a843bSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*062a843bSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*062a843bSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*062a843bSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*062a843bSAndroid Build Coastguard Worker * limitations under the License. 15*062a843bSAndroid Build Coastguard Worker */ 16*062a843bSAndroid Build Coastguard Worker 17*062a843bSAndroid Build Coastguard Worker #include "pb_decode.h" 18*062a843bSAndroid Build Coastguard Worker #include <pthread.h> 19*062a843bSAndroid Build Coastguard Worker #include <hardware/ril/librilutils/proto/sap-api.pb.h> 20*062a843bSAndroid Build Coastguard Worker #include <utils/Log.h> 21*062a843bSAndroid Build Coastguard Worker 22*062a843bSAndroid Build Coastguard Worker /** 23*062a843bSAndroid Build Coastguard Worker * Template queue class to handling requests for a rild socket. 24*062a843bSAndroid Build Coastguard Worker * <p> 25*062a843bSAndroid Build Coastguard Worker * This class performs the following functions : 26*062a843bSAndroid Build Coastguard Worker * <ul> 27*062a843bSAndroid Build Coastguard Worker * <li>Enqueue. 28*062a843bSAndroid Build Coastguard Worker * <li>Dequeue. 29*062a843bSAndroid Build Coastguard Worker * <li>Check and dequeue. 30*062a843bSAndroid Build Coastguard Worker * </ul> 31*062a843bSAndroid Build Coastguard Worker */ 32*062a843bSAndroid Build Coastguard Worker 33*062a843bSAndroid Build Coastguard Worker template <typename T> 34*062a843bSAndroid Build Coastguard Worker class Ril_queue { 35*062a843bSAndroid Build Coastguard Worker 36*062a843bSAndroid Build Coastguard Worker /** 37*062a843bSAndroid Build Coastguard Worker * Mutex attribute used in queue mutex initialization. 38*062a843bSAndroid Build Coastguard Worker */ 39*062a843bSAndroid Build Coastguard Worker pthread_mutexattr_t attr; 40*062a843bSAndroid Build Coastguard Worker 41*062a843bSAndroid Build Coastguard Worker /** 42*062a843bSAndroid Build Coastguard Worker * Queue mutex variable for synchronized queue access. 43*062a843bSAndroid Build Coastguard Worker */ 44*062a843bSAndroid Build Coastguard Worker pthread_mutex_t mutex_instance; 45*062a843bSAndroid Build Coastguard Worker 46*062a843bSAndroid Build Coastguard Worker /** 47*062a843bSAndroid Build Coastguard Worker * Condition to be waited on for dequeuing. 48*062a843bSAndroid Build Coastguard Worker */ 49*062a843bSAndroid Build Coastguard Worker pthread_cond_t cond; 50*062a843bSAndroid Build Coastguard Worker 51*062a843bSAndroid Build Coastguard Worker /** 52*062a843bSAndroid Build Coastguard Worker * Front of the queue. 53*062a843bSAndroid Build Coastguard Worker */ 54*062a843bSAndroid Build Coastguard Worker T *front; 55*062a843bSAndroid Build Coastguard Worker 56*062a843bSAndroid Build Coastguard Worker public: 57*062a843bSAndroid Build Coastguard Worker 58*062a843bSAndroid Build Coastguard Worker /** 59*062a843bSAndroid Build Coastguard Worker * Remove the first element of the queue. 60*062a843bSAndroid Build Coastguard Worker * 61*062a843bSAndroid Build Coastguard Worker * @return first element of the queue. 62*062a843bSAndroid Build Coastguard Worker */ 63*062a843bSAndroid Build Coastguard Worker T* dequeue(void); 64*062a843bSAndroid Build Coastguard Worker 65*062a843bSAndroid Build Coastguard Worker /** 66*062a843bSAndroid Build Coastguard Worker * Add a request to the front of the queue. 67*062a843bSAndroid Build Coastguard Worker * 68*062a843bSAndroid Build Coastguard Worker * @param Request to be added. 69*062a843bSAndroid Build Coastguard Worker */ 70*062a843bSAndroid Build Coastguard Worker void enqueue(T* request); 71*062a843bSAndroid Build Coastguard Worker 72*062a843bSAndroid Build Coastguard Worker /** 73*062a843bSAndroid Build Coastguard Worker * Check if the queue is empty. 74*062a843bSAndroid Build Coastguard Worker */ 75*062a843bSAndroid Build Coastguard Worker int empty(void); 76*062a843bSAndroid Build Coastguard Worker 77*062a843bSAndroid Build Coastguard Worker /** 78*062a843bSAndroid Build Coastguard Worker * Check and remove an element with a particular message id and token. 79*062a843bSAndroid Build Coastguard Worker * 80*062a843bSAndroid Build Coastguard Worker * @param Request message id. 81*062a843bSAndroid Build Coastguard Worker * @param Request token. 82*062a843bSAndroid Build Coastguard Worker */ 83*062a843bSAndroid Build Coastguard Worker int checkAndDequeue( MsgId id, int token); 84*062a843bSAndroid Build Coastguard Worker 85*062a843bSAndroid Build Coastguard Worker /** 86*062a843bSAndroid Build Coastguard Worker * Queue constructor. 87*062a843bSAndroid Build Coastguard Worker */ 88*062a843bSAndroid Build Coastguard Worker Ril_queue(void); 89*062a843bSAndroid Build Coastguard Worker }; 90*062a843bSAndroid Build Coastguard Worker 91*062a843bSAndroid Build Coastguard Worker template <typename T> Ril_queue(void)92*062a843bSAndroid Build Coastguard WorkerRil_queue<T>::Ril_queue(void) { 93*062a843bSAndroid Build Coastguard Worker pthread_mutexattr_init(&attr); 94*062a843bSAndroid Build Coastguard Worker pthread_mutex_init(&mutex_instance, &attr); 95*062a843bSAndroid Build Coastguard Worker cond = PTHREAD_COND_INITIALIZER; 96*062a843bSAndroid Build Coastguard Worker front = NULL; 97*062a843bSAndroid Build Coastguard Worker } 98*062a843bSAndroid Build Coastguard Worker 99*062a843bSAndroid Build Coastguard Worker template <typename T> dequeue(void)100*062a843bSAndroid Build Coastguard WorkerT* Ril_queue<T>::dequeue(void) { 101*062a843bSAndroid Build Coastguard Worker T* temp = NULL; 102*062a843bSAndroid Build Coastguard Worker 103*062a843bSAndroid Build Coastguard Worker pthread_mutex_lock(&mutex_instance); 104*062a843bSAndroid Build Coastguard Worker while(empty()) { 105*062a843bSAndroid Build Coastguard Worker pthread_cond_wait(&cond, &mutex_instance); 106*062a843bSAndroid Build Coastguard Worker } 107*062a843bSAndroid Build Coastguard Worker temp = this->front; 108*062a843bSAndroid Build Coastguard Worker if(NULL != this->front->p_next) { 109*062a843bSAndroid Build Coastguard Worker this->front = this->front->p_next; 110*062a843bSAndroid Build Coastguard Worker } else { 111*062a843bSAndroid Build Coastguard Worker this->front = NULL; 112*062a843bSAndroid Build Coastguard Worker } 113*062a843bSAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex_instance); 114*062a843bSAndroid Build Coastguard Worker 115*062a843bSAndroid Build Coastguard Worker return temp; 116*062a843bSAndroid Build Coastguard Worker } 117*062a843bSAndroid Build Coastguard Worker 118*062a843bSAndroid Build Coastguard Worker template <typename T> enqueue(T * request)119*062a843bSAndroid Build Coastguard Workervoid Ril_queue<T>::enqueue(T* request) { 120*062a843bSAndroid Build Coastguard Worker 121*062a843bSAndroid Build Coastguard Worker pthread_mutex_lock(&mutex_instance); 122*062a843bSAndroid Build Coastguard Worker 123*062a843bSAndroid Build Coastguard Worker if(NULL == this->front) { 124*062a843bSAndroid Build Coastguard Worker this->front = request; 125*062a843bSAndroid Build Coastguard Worker request->p_next = NULL; 126*062a843bSAndroid Build Coastguard Worker } else { 127*062a843bSAndroid Build Coastguard Worker request->p_next = this->front; 128*062a843bSAndroid Build Coastguard Worker this->front = request; 129*062a843bSAndroid Build Coastguard Worker } 130*062a843bSAndroid Build Coastguard Worker pthread_cond_broadcast(&cond); 131*062a843bSAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex_instance); 132*062a843bSAndroid Build Coastguard Worker } 133*062a843bSAndroid Build Coastguard Worker 134*062a843bSAndroid Build Coastguard Worker template <typename T> checkAndDequeue(MsgId id,int token)135*062a843bSAndroid Build Coastguard Workerint Ril_queue<T>::checkAndDequeue(MsgId id, int token) { 136*062a843bSAndroid Build Coastguard Worker int ret = 0; 137*062a843bSAndroid Build Coastguard Worker T* temp; 138*062a843bSAndroid Build Coastguard Worker 139*062a843bSAndroid Build Coastguard Worker pthread_mutex_lock(&mutex_instance); 140*062a843bSAndroid Build Coastguard Worker 141*062a843bSAndroid Build Coastguard Worker for(T **ppCur = &(this->front); *ppCur != NULL; ppCur = &((*ppCur)->p_next)) { 142*062a843bSAndroid Build Coastguard Worker if (token == (*ppCur)->token && id == (*ppCur)->curr->id) { 143*062a843bSAndroid Build Coastguard Worker ret = 1; 144*062a843bSAndroid Build Coastguard Worker temp = *ppCur; 145*062a843bSAndroid Build Coastguard Worker *ppCur = (*ppCur)->p_next; 146*062a843bSAndroid Build Coastguard Worker free(temp); 147*062a843bSAndroid Build Coastguard Worker break; 148*062a843bSAndroid Build Coastguard Worker } 149*062a843bSAndroid Build Coastguard Worker } 150*062a843bSAndroid Build Coastguard Worker 151*062a843bSAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex_instance); 152*062a843bSAndroid Build Coastguard Worker 153*062a843bSAndroid Build Coastguard Worker return ret; 154*062a843bSAndroid Build Coastguard Worker } 155*062a843bSAndroid Build Coastguard Worker 156*062a843bSAndroid Build Coastguard Worker 157*062a843bSAndroid Build Coastguard Worker template <typename T> empty(void)158*062a843bSAndroid Build Coastguard Workerint Ril_queue<T>::empty(void) { 159*062a843bSAndroid Build Coastguard Worker 160*062a843bSAndroid Build Coastguard Worker if(this->front == NULL) { 161*062a843bSAndroid Build Coastguard Worker return 1; 162*062a843bSAndroid Build Coastguard Worker } else { 163*062a843bSAndroid Build Coastguard Worker return 0; 164*062a843bSAndroid Build Coastguard Worker } 165*062a843bSAndroid Build Coastguard Worker } 166