| /* |
| * 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 <pthread.h> |
| #include <hardware/ril/librilutils/proto/sap-api.pb.h> |
| #include <utils/Log.h> |
| |
| using namespace std; |
| |
| /** |
| * Template queue class to handling requests for a rild socket. |
| * <p> |
| * This class performs the following functions : |
| * <ul> |
| * <li>Enqueue. |
| * <li>Dequeue. |
| * <li>Check and dequeue. |
| * </ul> |
| */ |
| |
| template <typename T> |
| 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 <typename T> |
| Ril_queue<T>::Ril_queue(void) { |
| pthread_mutexattr_init(&attr); |
| pthread_mutex_init(&mutex_instance, &attr); |
| cond = PTHREAD_COND_INITIALIZER; |
| front = NULL; |
| } |
| |
| template <typename T> |
| T* Ril_queue<T>::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 <typename T> |
| void Ril_queue<T>::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 <typename T> |
| int Ril_queue<T>::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 <typename T> |
| int Ril_queue<T>::empty(void) { |
| |
| if(this->front == NULL) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |