xref: /aosp_15_r20/hardware/ril/libril/rilSocketQueue.h (revision 062a843b36e31144e02d312b6b2de34642e6750e)
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 Worker Ril_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 Worker T* 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 Worker void 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 Worker int 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 Worker int 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