168 lines
3.7 KiB
C
168 lines
3.7 KiB
C
|
/*
|
||
|
* 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;
|
||
|
}
|
||
|
}
|