1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*
2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Copyright (C) Texas Instruments - http://www.ti.com/
3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * you may not use this file except in compliance with the License.
6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * You may obtain a copy of the License at
7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *
10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Unless required by applicable law or agreed to in writing, software
11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * See the License for the specific language governing permissions and
14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * limitations under the License.
15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <errno.h>
19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <string.h>
20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <sys/types.h>
21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <sys/poll.h>
22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <unistd.h>
231d0e99f00b2089482e5f7c91ce0b0866f465a4d6Mathias Agopian#include <utils/Errors.h>
24c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define LOG_TAG "MessageQueue"
28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <utils/Log.h>
29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "MessageQueue.h"
31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
32f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Ti {
33f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Utils {
34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
36c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Constructor for the message queue class
37c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
38c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param none
39c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return none
40c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevMessageQueue::MessageQueue()
42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
45c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int fds[2] = {-1,-1};
46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    android::status_t stat;
47c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    stat = pipe(fds);
49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
50c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( 0 > stat )
51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEB("Error while openning pipe: %s", strerror(stat) );
53c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        this->fd_read = 0;
54c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        this->fd_write = 0;
55c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mHasMsg = false;
56c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
57c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
58c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
59c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        this->fd_read = fds[0];
60c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        this->fd_write = fds[1];
61c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
62c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mHasMsg = false;
63c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
64c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
65c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
66c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
67c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
68c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
69c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Destructor for the semaphore class
70c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
71c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param none
72c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return none
73c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
74c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevMessageQueue::~MessageQueue()
75c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
76c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
77c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
7818d4cb78c873c0ac1ab145f9b70d8f3d0e715185Iliyan Malchev    if(this->fd_read >= 0)
79c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
80c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        close(this->fd_read);
81c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
82c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
8318d4cb78c873c0ac1ab145f9b70d8f3d0e715185Iliyan Malchev    if(this->fd_write >= 0)
84c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        close(this->fd_write);
86c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
87c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
88c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
89c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
90c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
91c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
92c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Get a message from the queue
93c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
94c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param msg Message structure to hold the message to be retrieved
95c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::NO_ERROR On success
96c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::BAD_VALUE if the message pointer is NULL
97c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::NO_INIT If the file read descriptor is not set
98c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::UNKNOWN_ERROR if the read operation fromthe file read descriptor fails
99c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevandroid::status_t MessageQueue::get(Message* msg)
101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!msg)
105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("msg is NULL");
107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::BAD_VALUE;
109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
110c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!this->fd_read)
112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("read descriptor not initialized for message queue");
114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::NO_INIT;
116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    char* p = (char*) msg;
119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    size_t read_bytes = 0;
120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
121c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    while( read_bytes  < sizeof(*msg) )
122c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
123c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        int err = read(this->fd_read, p, sizeof(*msg) - read_bytes);
124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if( err < 0 )
126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            MSGQ_LOGEB("read() error: %s", strerror(errno));
128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return android::UNKNOWN_ERROR;
129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            read_bytes += err;
133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    MSGQ_LOGDB("MQ.get(%d,%p,%p,%p,%p)", msg->command, msg->arg1,msg->arg2,msg->arg3,msg->arg4);
137c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
138c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mHasMsg = false;
139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
140c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return 0;
143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Get the input file descriptor of the message queue
147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param none
149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return file read descriptor
150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint MessageQueue::getInFd()
153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return this->fd_read;
155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Constructor for the message queue class
159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param fd file read descriptor
161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return none
162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid MessageQueue::setInFd(int fd)
165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if ( -1 != this->fd_read )
169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        close(this->fd_read);
171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    this->fd_read = fd;
174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Queue a message
180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param msg Message structure to hold the message to be retrieved
182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::NO_ERROR On success
183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::BAD_VALUE if the message pointer is NULL
184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::NO_INIT If the file write descriptor is not set
185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::UNKNOWN_ERROR if the write operation fromthe file write descriptor fails
186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevandroid::status_t MessageQueue::put(Message* msg)
189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    char* p = (char*) msg;
193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    size_t bytes = 0;
194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
195c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!msg)
196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("msg is NULL");
198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::BAD_VALUE;
200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!this->fd_write)
203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("write descriptor not initialized for message queue");
205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::NO_INIT;
207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    MSGQ_LOGDB("MQ.put(%d,%p,%p,%p,%p)", msg->command, msg->arg1,msg->arg2,msg->arg3,msg->arg4);
211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    while( bytes  < sizeof(msg) )
213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        int err = write(this->fd_write, p, sizeof(*msg) - bytes);
215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if( err < 0 )
217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            MSGQ_LOGEB("write() error: %s", strerror(errno));
219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            LOG_FUNCTION_NAME_EXIT;
220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return android::UNKNOWN_ERROR;
221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        else
223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            bytes += err;
225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    MSGQ_LOGDA("MessageQueue::put EXIT");
229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return 0;
232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Returns if the message queue is empty or not
237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param none
239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return true If the queue is empty
240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return false If the queue has at least one message
241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevbool MessageQueue::isEmpty()
243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{
244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    struct pollfd pfd;
247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    pfd.fd = this->fd_read;
249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    pfd.events = POLLIN;
250c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    pfd.revents = 0;
251c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!this->fd_read)
253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("read descriptor not initialized for message queue");
255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::NO_INIT;
257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if( -1 == poll(&pfd,1,0) )
261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEB("poll() error: %s", strerror(errno));
263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return false;
265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(pfd.revents & POLLIN)
268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mHasMsg = true;
270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    else
272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
273c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        mHasMsg = false;
274c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
275c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return !mHasMsg;
278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}
279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
280f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Ramanvoid MessageQueue::clear()
281f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman{
282f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
283f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
284f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman    if(!this->fd_read)
285f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        {
286f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        MSGQ_LOGEA("read descriptor not initialized for message queue");
287f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        LOG_FUNCTION_NAME_EXIT;
288f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        return;
289f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        }
290f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman
291f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman    Message msg;
292f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman    while(!isEmpty())
293f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        {
294f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        get(&msg);
295f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman        }
296f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman
297f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman}
298f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman
299f9df3ee5cfb3c3177bcc630abf6d756e8a60254cSundar Raman
300c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
301c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @brief Force whether the message queue has message or not
302c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param hasMsg Whether the queue has a message or not
304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return none
305c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid MessageQueue::setMsg(bool hasMsg)
307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    mHasMsg = hasMsg;
309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/**
313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @briefWait for message in maximum three different queues with a timeout
314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param queue1 First queue. At least this should be set to a valid queue pointer
316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param queue2 Second queue. Optional.
317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param queue3 Third queue. Optional.
318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @param timeout The timeout value (in micro secs) to wait for a message in any of the queues
319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::NO_ERROR On success
320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::BAD_VALUE If queue1 is NULL
321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev   @return android::NO_INIT If the file read descriptor of any of the provided queues is not set
322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */
323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevandroid::status_t MessageQueue::waitForMsg(MessageQueue *queue1, MessageQueue *queue2, MessageQueue *queue3, int timeout)
324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    {
325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME;
326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int n =1;
328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    struct pollfd pfd[3];
329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!queue1)
331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("queue1 pointer is NULL");
333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::BAD_VALUE;
335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
337c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    pfd[0].fd = queue1->getInFd();
338c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(!pfd[0].fd)
339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
340c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEA("read descriptor not initialized for message queue1");
341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
342c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return android::NO_INIT;
343c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
344c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    pfd[0].events = POLLIN;
345c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    pfd[0].revents = 0;
346c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(queue2)
347c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
348c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGDA("queue2 not-null");
349c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pfd[1].fd = queue2->getInFd();
350c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if(!pfd[1].fd)
351c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
352c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            MSGQ_LOGEA("read descriptor not initialized for message queue2");
353c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            LOG_FUNCTION_NAME_EXIT;
354c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return android::NO_INIT;
355c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
356c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pfd[1].events = POLLIN;
358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pfd[1].revents = 0;
359c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        n++;
360c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
361c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
362c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(queue3)
363c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
364c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGDA("queue3 not-null");
365c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pfd[2].fd = queue3->getInFd();
366c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if(!pfd[2].fd)
367c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            MSGQ_LOGEA("read descriptor not initialized for message queue3");
369c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            LOG_FUNCTION_NAME_EXIT;
370c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            return android::NO_INIT;
371c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
372c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
373c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pfd[2].events = POLLIN;
374c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        pfd[2].revents = 0;
375c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        n++;
376c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
377c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
378c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
379c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    int ret = poll(pfd, n, timeout);
380c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(ret==0)
381c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
382c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
383c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ret;
384c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
385c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
386c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(ret<android::NO_ERROR)
387c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        MSGQ_LOGEB("Message queue returned error %d", ret);
389c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        LOG_FUNCTION_NAME_EXIT;
390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        return ret;
391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if (pfd[0].revents & POLLIN)
394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        queue1->setMsg(true);
396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(queue2)
399c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (pfd[1].revents & POLLIN)
401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            queue2->setMsg(true);
403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
404c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    if(queue3)
407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        {
408c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        if (pfd[2].revents & POLLIN)
409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            {
410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            queue3->setMsg(true);
411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev            }
412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev        }
413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    LOG_FUNCTION_NAME_EXIT;
415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    return ret;
416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev    }
417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev
418f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Utils
419f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Ti
420