1e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
2e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *
3e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * Redistribution and use in source and binary forms, with or without
4e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * modification, are permitted provided that the following conditions are
5e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * met:
6e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *     * Redistributions of source code must retain the above copyright
7e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *       notice, this list of conditions and the following disclaimer.
8e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *     * Redistributions in binary form must reproduce the above
9e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *       copyright notice, this list of conditions and the following
10e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *       disclaimer in the documentation and/or other materials provided
11e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *       with the distribution.
12e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *     * Neither the name of The Linux Foundation, nor the names of its
13e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *       contributors may be used to endorse or promote products derived
14e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *       from this software without specific prior written permission.
15e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *
16e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo *
28e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo */
29e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#define LOG_NDDEBUG 0
30e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#define LOG_TAG "LocSvc_MsgTask"
31e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
32e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <cutils/sched_policy.h>
33e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <unistd.h>
34e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <MsgTask.h>
35e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <msg_q.h>
36e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <log_util.h>
37e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#include <loc_log.h>
38e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
39e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russonamespace loc_core {
40e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
41e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo#define MAX_TASK_COMM_LEN 15
42e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
43e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russostatic void LocMsgDestroy(void* msg) {
44e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    delete (LocMsg*)msg;
45e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
46e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
47e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoMsgTask::MsgTask(tCreate tCreator, const char* threadName) :
48e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mQ(msg_q_init2()), mAssociator(NULL){
49e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if (tCreator) {
50e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        tCreator(threadName, loopMain,
51e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                 (void*)new MsgTask(mQ, mAssociator));
52e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    } else {
53e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        createPThread(threadName);
54e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
55e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
56e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
57e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoMsgTask::MsgTask(tAssociate tAssociator, const char* threadName) :
58e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mQ(msg_q_init2()), mAssociator(tAssociator){
59e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    createPThread(threadName);
60e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
61e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
62e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russoinline
63e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoMsgTask::MsgTask(const void* q, tAssociate associator) :
64e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    mQ(q), mAssociator(associator){
65e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
66e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
67e14a6c846df2ce4bb1847e4250991f7c52fd793dDante RussoMsgTask::~MsgTask() {
68e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    msg_q_unblock((void*)mQ);
69e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
70e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
7147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russovoid MsgTask::associate(tAssociate tAssociator) const {
7247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    struct LocAssociateMsg : public LocMsg {
7347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        tAssociate mAssociator;
7447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        inline LocAssociateMsg(tAssociate associator) :
7547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            LocMsg(), mAssociator(associator) {}
7647ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        inline virtual void proc() const {
7747ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            if (mAssociator) {
7847ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                LOC_LOGD("MsgTask::associate");
7947ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo                mAssociator();
8047ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo            }
8147ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo        }
8247ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    };
8347ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo    sendMsg(new LocAssociateMsg(tAssociator));
8447ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo}
8547ad5e4cf2f6810db3c0e7ec79696496a94b6f0dDante Russo
86e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid MsgTask::createPThread(const char* threadName) {
87e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    pthread_attr_t attr;
88e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    pthread_attr_init(&attr);
89e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
90e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
91e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    pthread_t tid;
92e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    // create the thread here, then if successful
93e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    // and a name is given, we set the thread name
94e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if (!pthread_create(&tid, &attr, loopMain,
95e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                        (void*)new MsgTask(mQ, mAssociator)) &&
96e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        NULL != threadName) {
97e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        char lname[MAX_TASK_COMM_LEN+1];
98e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        memcpy(lname, threadName, MAX_TASK_COMM_LEN);
99e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        lname[MAX_TASK_COMM_LEN] = 0;
100e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        pthread_setname_np(tid, lname);
101e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
102e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
103e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
104e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid MsgTask::sendMsg(const LocMsg* msg) const {
105e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
106e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
107e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
108e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russovoid* MsgTask::loopMain(void* arg) {
109e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    MsgTask* copy = (MsgTask*)arg;
110e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
111e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    // make sure we do not run in background scheduling group
112e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    set_sched_policy(gettid(), SP_FOREGROUND);
113e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
114e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    if (NULL != copy->mAssociator) {
115e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        copy->mAssociator();
116e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
117e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
118e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    LocMsg* msg;
119e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    int cnt = 0;
120e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
121e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    while (1) {
122e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        LOC_LOGD("MsgTask::loop() %d listening ...\n", cnt++);
123e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
124e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        msq_q_err_type result = msg_q_rcv((void*)copy->mQ, (void **)&msg);
125e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
126e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        if (eMSG_Q_SUCCESS != result) {
127e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            LOC_LOGE("%s:%d] fail receiving msg: %s\n", __func__, __LINE__,
128e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo                     loc_get_msg_q_status(result));
129e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            // destroy the Q and exit
130e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            msg_q_destroy((void**)&(copy->mQ));
131e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            delete copy;
132e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo            return NULL;
133e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        }
134e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
135e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        msg->log();
136e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        // there is where each individual msg handling is invoked
137e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        msg->proc();
138e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
139e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo        delete msg;
140e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    }
141e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
142e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    delete copy;
143e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
144e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo    return NULL;
145e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
146e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo
147e14a6c846df2ce4bb1847e4250991f7c52fd793dDante Russo}
148