1/*
2**
3** Copyright 2008, The Android Open Source Project
4** Copyright 2012, Samsung Electronics Co. LTD
5**
6** Licensed under the Apache License, Version 2.0 (the "License");
7** you may not use this file except in compliance with the License.
8** You may obtain a copy of the License at
9**
10**     http://www.apache.org/licenses/LICENSE-2.0
11**
12** Unless required by applicable law or agreed to in writing, software
13** distributed under the License is distributed on an "AS IS" BASIS,
14** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15** See the License for the specific language governing permissions and
16** limitations under the License.
17*/
18
19/*!
20 * \file      SignalDrivenThread.cpp
21 * \brief     source file for general thread ( for camera hal2 implementation )
22 * \author    Sungjoong Kang(sj3.kang@samsung.com)
23 * \date      2012/05/31
24 *
25 * <b>Revision History: </b>
26 * - 2012/05/31 : Sungjoong Kang(sj3.kang@samsung.com) \n
27 *   Initial Release
28 *
29 * - 2012/07/10 : Sungjoong Kang(sj3.kang@samsung.com) \n
30 *   2nd Release
31 *
32 */
33
34//#define LOG_NDEBUG 1
35#define LOG_TAG "SignalDrivenThread"
36#include <utils/Log.h>
37
38#include "SignalDrivenThread.h"
39
40namespace android {
41
42
43SignalDrivenThread::SignalDrivenThread()
44    :Thread(false)
45{
46    ALOGV("(SignalDrivenThread() ):");
47    m_processingSignal = 0;
48    m_receivedSignal = 0;
49    m_pendingSignal = 0;
50    m_isTerminated = false;
51}
52
53void SignalDrivenThread::Start(const char* name,
54                            int32_t priority, size_t stack)
55{
56    ALOGV("DEBUG(SignalDrivenThread::Start() ):");
57    run(name, priority, stack);
58}
59SignalDrivenThread::SignalDrivenThread(const char* name,
60                            int32_t priority, size_t stack)
61    :Thread(false)
62{
63    ALOGV("DEBUG(SignalDrivenThread( , , )):");
64    m_processingSignal = 0;
65    m_receivedSignal = 0;
66    m_pendingSignal = 0;
67    m_isTerminated = false;
68    run(name, priority, stack);
69    return;
70}
71
72SignalDrivenThread::~SignalDrivenThread()
73{
74    ALOGD("DEBUG(%s):", __func__);
75    return;
76}
77
78status_t SignalDrivenThread::SetSignal(uint32_t signal)
79{
80    ALOGV("DEBUG(%s):Setting Signal (%x)", __FUNCTION__, signal);
81
82    Mutex::Autolock lock(m_signalMutex);
83    ALOGV("DEBUG(%s):Signal Set     (%x) - prev(%x)", __FUNCTION__, signal, m_receivedSignal);
84    if (m_receivedSignal & signal) {
85        m_pendingSignal |= signal;
86    } else {
87        m_receivedSignal |= signal;
88    }
89    m_threadCondition.signal();
90    return NO_ERROR;
91}
92
93uint32_t SignalDrivenThread::GetProcessingSignal()
94{
95    ALOGV("DEBUG(%s): Signal (%x)", __FUNCTION__, m_processingSignal);
96
97    Mutex::Autolock lock(m_signalMutex);
98    return m_processingSignal;
99}
100
101bool SignalDrivenThread::IsTerminated()
102{
103    Mutex::Autolock lock(m_signalMutex);
104    return m_isTerminated;
105}
106
107status_t SignalDrivenThread::readyToRun()
108{
109    ALOGV("DEBUG(%s):", __func__);
110    return readyToRunInternal();
111}
112
113status_t SignalDrivenThread::readyToRunInternal()
114{
115    ALOGV("DEBUG(%s):", __func__);
116    return NO_ERROR;
117}
118
119bool SignalDrivenThread::threadLoop()
120{
121    {
122        Mutex::Autolock lock(m_signalMutex);
123        ALOGV("DEBUG(%s):Waiting Signal", __FUNCTION__);
124        while (!m_receivedSignal)
125        {
126            m_threadCondition.wait(m_signalMutex);
127        }
128        m_processingSignal = m_receivedSignal;
129        m_receivedSignal = m_pendingSignal;
130        m_pendingSignal = 0;
131    }
132    ALOGV("DEBUG(%s):Got Signal (%x)", __FUNCTION__, m_processingSignal);
133
134    if (m_processingSignal & SIGNAL_THREAD_TERMINATE)
135    {
136        ALOGD("(%s): Thread Terminating by SIGNAL", __func__);
137        Mutex::Autolock lock(m_signalMutex);
138        m_isTerminated = true;
139        return (false);
140    }
141    else if (m_processingSignal & SIGNAL_THREAD_PAUSE)
142    {
143        ALOGV("DEBUG(%s):Thread Paused", __func__);
144        return (true);
145    }
146
147    if (m_isTerminated)
148        m_isTerminated = false;
149
150    threadFunctionInternal();
151    return true;
152}
153
154
155}; // namespace android
156