/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "pb_decode.h" #include #include #include using namespace std; /** * Template queue class to handling requests for a rild socket. *

* This class performs the following functions : *

    *
  • Enqueue. *
  • Dequeue. *
  • Check and dequeue. *
*/ template class Ril_queue { /** * Mutex attribute used in queue mutex initialization. */ pthread_mutexattr_t attr; /** * Queue mutex variable for synchronized queue access. */ pthread_mutex_t mutex_instance; /** * Condition to be waited on for dequeuing. */ pthread_cond_t cond; /** * Front of the queue. */ T *front; public: /** * Remove the first element of the queue. * * @return first element of the queue. */ T* dequeue(void); /** * Add a request to the front of the queue. * * @param Request to be added. */ void enqueue(T* request); /** * Check if the queue is empty. */ int empty(void); /** * Check and remove an element with a particular message id and token. * * @param Request message id. * @param Request token. */ int checkAndDequeue( MsgId id, int token); /** * Queue constructor. */ Ril_queue(void); }; template Ril_queue::Ril_queue(void) { pthread_mutexattr_init(&attr); pthread_mutex_init(&mutex_instance, &attr); cond = PTHREAD_COND_INITIALIZER; front = NULL; } template T* Ril_queue::dequeue(void) { T* temp = NULL; pthread_mutex_lock(&mutex_instance); while(empty()) { pthread_cond_wait(&cond, &mutex_instance); } temp = this->front; if(NULL != this->front->p_next) { this->front = this->front->p_next; } else { this->front = NULL; } pthread_mutex_unlock(&mutex_instance); return temp; } template void Ril_queue::enqueue(T* request) { pthread_mutex_lock(&mutex_instance); if(NULL == this->front) { this->front = request; request->p_next = NULL; } else { request->p_next = this->front; this->front = request; } pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex_instance); } template int Ril_queue::checkAndDequeue(MsgId id, int token) { int ret = 0; T* temp; pthread_mutex_lock(&mutex_instance); for(T **ppCur = &(this->front); *ppCur != NULL; ppCur = &((*ppCur)->p_next)) { if (token == (*ppCur)->token && id == (*ppCur)->curr->id) { ret = 1; temp = *ppCur; *ppCur = (*ppCur)->p_next; free(temp); break; } } pthread_mutex_unlock(&mutex_instance); return ret; } template int Ril_queue::empty(void) { if(this->front == NULL) { return 1; } else { return 0; } }