RDK Documentation (Open Sourced RDK Components)
RtUtils.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2018 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 #include <pthread.h>
21 #include <rtLog.h>
22 #include <rtRemote.h>
23 #include <rtError.h>
24 #include <assert.h>
25 
26 #include <sys/types.h>
27 #include <sys/syscall.h>
28 
29 #include "RtUtils.h"
30 
31 /*
32 static void rtRemoteLogHandler(rtLogLevel level, const char* file, int line, int threadId, char* message) {
33  switch (level) {
34  case RT_LOG_DEBUG: Log::debug(TRACE_SYSTEM, "RT LOG line:%d, threadId:%d : %s", message); break;
35  case RT_LOG_INFO: Log::info(TRACE_SYSTEM, "RT LOG line:%d, threadId:%d : %s", message); break;
36  case RT_LOG_WARN: Log::warn(TRACE_SYSTEM, "RT LOG line:%d, threadId:%d : %s", message); break;
37  case RT_LOG_ERROR: Log::error(TRACE_SYSTEM, "RT LOG line:%d, threadId:%d : %s", message); break;
38  case RT_LOG_FATAL: Log::fatal(TRACE_SYSTEM, "RT LOG line:%d, threadId:%d : %s", message); break;
39  default: Log::info(TRACE_SYSTEM, "RT LOG line:%d, threadId:%d : %s", message); break;
40  }
41 }
42 */
43 
44 RtUtils::RtUtils() : mStarted(false), mEventEmitter(), mRemoteReady(true)
45 {
46 }
47 
48 rtError RtUtils::initRt()
49 {
50  rtError rc;
51 
52  memset(&mThreadData,0,sizeof(RtProcessThreadData));
53  pthread_cond_init(&mThreadData.mCond,NULL);
54  pthread_mutex_init(&mThreadData.mMutex,NULL);
55  mThreadData.mRunning = true;
56  pthread_create(&mThreadData.mThread, NULL, RtUtils::RtMessageThread, this);
57 
58  //TODO: Use and test log handler
59  //rtLogSetLogHandler(rtRemoteLogHandler);
60  rtRemoteRegisterQueueReadyHandler( rtEnvironmentGetGlobal(), rtRemoteCallback, this);
61 
62  rc = rtRemoteInit();
63  if(rc != RT_OK)
64  {
65  printf("Failed to init rt!\n");
66  return rc;
67  }
68 }
69 
70 RtUtils::~RtUtils()
71 {
72  setDedicatedThreadRunning(false);
73  void *returnValue;
74 
75  pthread_mutex_lock(&mThreadData.mMutex);
76  pthread_cond_signal(&mThreadData.mCond);
77  pthread_mutex_unlock(&mThreadData.mMutex);
78 
79  pthread_join(mThreadData.mThread, &returnValue);
80  pthread_cond_destroy(&mThreadData.mCond);
81  pthread_mutex_destroy(&mThreadData.mMutex);
82  printf("Dedicated RT message thread exited!\n");
83 
84  rtError rc = RT_OK;
85  printf("before rt remote shutdown\n"); fflush(stdout);
86  // TODO: Revisit the mRemoteReady check, if px doesn't connect or isn't destroyed
87  // the shutdown will hang unless a signal is sent again. mRemoteReady is only set
88  // if the remote object actually communicated with us.
89  if(mRemoteReady)
90  {
91  ProcessRtItem();
92  rc = rtRemoteShutdown();
93  }
94  if(rc != RT_OK)
95  printf("Failed to shutdown rt!\n");
96  printf("after rt remote shutdown\n"); fflush(stdout);
97 }
98 
99 void RtUtils::ProcessRtItem()
100 {
101  rtError err = RT_OK;
102  while(err == RT_OK) { // empty the queue
103  err = rtRemoteProcessSingleItem();
104  if (err == RT_ERROR_QUEUE_EMPTY)
105  printf("queue was empty upon processing event\n");
106  else if (err != RT_OK)
107  printf("rtRemoteProcessSingleItem() returned %d\n", err);
108  }
109 }
110 
111 void * RtUtils::RtMessageThread(void * ctx)
112 {
113  RtUtils* rtUtils = static_cast<RtUtils*>(ctx);
114 
115  pthread_mutex_lock(&rtUtils->mThreadData.mMutex);
116  while(rtUtils->mThreadData.mRunning)
117  {
118  pthread_cond_wait(&rtUtils->mThreadData.mCond, &rtUtils->mThreadData.mMutex);
119 
120  printf("rtRemoteProcessSingleItem()\n");
121  rtUtils->ProcessRtItem();
122  }
123  pthread_mutex_unlock(&rtUtils->mThreadData.mMutex);
124 
125  pthread_exit(NULL);
126 }
127 
128 void RtUtils::setDedicatedThreadRunning(bool running)
129 {
130  pthread_mutex_lock(&mThreadData.mMutex);
131  mThreadData.mRunning = running;
132  pthread_mutex_unlock(&mThreadData.mMutex);
133 }
134 
135 bool RtUtils::isDedicatedThreadRunning()
136 {
137  bool isRunning = false;
138 
139  pthread_mutex_lock(&mThreadData.mMutex);
140  isRunning = mThreadData.mRunning;
141  pthread_mutex_unlock(&mThreadData.mMutex);
142 
143  return isRunning;
144 }
145 
146 void RtUtils::rtRemoteCallback(void* ctx)
147 {
148  RtUtils* rtUtils = static_cast<RtUtils*>(ctx);
149 
150  pthread_mutex_lock(&rtUtils->mThreadData.mMutex);
151  pthread_cond_signal(&rtUtils->mThreadData.mCond);
152  pthread_mutex_unlock(&rtUtils->mThreadData.mMutex);
153 }
154 
155 void RtUtils::setStarted(bool started)
156 {
157  mStarted = started;
158 }
159 
160 void RtUtils::send(Event* event)
161 {
162  mEventEmitter.send(event);
163 }
164 
165 void RtUtils::EventEmitter::processEvents()
166 {
167  pthread_mutex_lock(&mMutex);
168  while (!mEventQueue.empty())
169  {
170  rtObjectRef obj = mEventQueue.front();
171  mEventQueue.pop();
172 
173  rtError rc = m_emit.send(obj.get<rtString>("name"), obj);
174  if(rc == RT_OK)
175  printf("SENDING EVENT SUCCEDED!\n");
176  else
177  printf("SENDING EVENT FAILED!\n");
178 
179  assert(RT_OK == rc);
180  }
181  pthread_mutex_unlock(&mMutex);
182 }
183 
184 rtError RtUtils::EventEmitter::send(Event* event) {
185  pthread_mutex_lock(&mMutex);
186  mEventQueue.push(event->object());
187  pthread_mutex_unlock(&mMutex);
188 
189  if(mRemoteReady)
190  {
191  processEvents();
192  }
193 
194  return RT_OK;
195 }
196 
197 rtError RtUtils::setListener(rtString eventName, const rtFunctionRef& f)
198 {
199  return mEventEmitter.setListener(eventName, f);
200 }
201 
202 rtError RtUtils::delListener(rtString eventName, const rtFunctionRef& f)
203 {
204  return mEventEmitter.delListener(eventName, f);
205 }
206 
207 void RtUtils::remoteObjectReady()
208 {
209  mRemoteReady=true;
210  mEventEmitter.remoteObjectReady();
211 }
RtUtils
Definition: RtUtils.h:27
Event
class to DRM Event handle
Definition: opencdmsessionadapter.h:24