Add gitlab issue/merge request templates
[staging/basesystem.git] / service / system / logger_service / server / src / reader_writer.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup  tag_SS_LoggerService
19 /// \brief    TODO
20 ///
21 ///////////////////////////////////////////////////////////////////////////////
22 #include "readerWriter/reader_writer.h"
23 #include <errno.h>
24 #include <loggerservicedebug_loggerservicelog.h>
25 #include <system_service/ss_templates.h>
26 #include <native_service/frameworkunified_thread_priority.h>
27 #include <string>
28
29 namespace ReaderWriter {
30
31 CReaderWriter::CReaderWriter()
32     : m_pLoggerCfg(NULL),
33       m_reader(NULL),
34       m_writer(NULL),
35       m_running(FALSE),
36       m_thread(-1),
37       m_readerName(""),
38       m_paused(FALSE) {
39
40   pthread_cond_init(&m_condVariable, NULL);
41 }
42
43 CReaderWriter::~CReaderWriter() {  // LCOV_EXCL_START 14:global instance
44   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
45   if (NULL != this->m_reader) {
46     delete (this->m_reader);
47     this->m_reader = NULL;
48   }
49
50   if (NULL != this->m_writer) {
51     delete (this->m_writer);
52     this->m_writer = NULL;
53   }
54 }
55 // LCOV_EXCL_STOP
56
57 EFrameworkunifiedStatus CReaderWriter::Initialize(CLoggerCfg* f_pLoggerCfg,
58                                      EReaderType f_readerType,
59                                      std::string f_readerName,
60                                      UI_32 f_readerMaxSize,
61                                      EWriterType f_writerType,
62                                      std::string f_writer1Name,
63                                      UI_32 f_writer1MaxSize,
64                                      std::string f_writer2Name,
65                                      UI_32 f_writer2MaxSize) {
66   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
67   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
68   if (NULL == (this->m_pLoggerCfg = f_pLoggerCfg)) {  // LCOV_EXCL_BR_LINE 6:Because the applicable variable cannot be changed from the external API
69     // FRAMEWORKUNIFIEDLOG not needed... If this starts we won't be able to print loggerservicelogs anyways.
70     l_eStatus = eFrameworkunifiedStatusNullPointer;
71   } else {
72     this->m_reader = CReader::OpenReader(f_pLoggerCfg, f_readerType,  // LCOV_EXCL_BR_LINE 11:except,C++ STL
73                                          f_readerName, f_readerMaxSize);
74     this->m_writer = CWriter::OpenWriter(f_pLoggerCfg, f_writerType,  // LCOV_EXCL_BR_LINE 11:except,C++ STL
75                                          f_writer1Name, f_writer1MaxSize,
76                                          f_writer2Name, f_writer2MaxSize);
77
78     if ((NULL == this->m_reader) || (NULL == this->m_writer)) {
79       l_eStatus = eFrameworkunifiedStatusFail;
80
81       this->Cleanup(this);
82     }
83   }
84   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-: %d", l_eStatus);
85   return (l_eStatus);
86 }
87
88 EFrameworkunifiedStatus CReaderWriter::Start(std::string f_readerName) {
89   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
90   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusNullPointer;
91   if (this->m_running == FALSE) {  // LCOV_EXCL_BR_LINE 6:Because m_running is always FALSE
92     this->m_readerName = f_readerName;
93     BOOL l_barInit =
94         // LCOV_EXCL_BR_START 5:pthread cannot be passed because it cannot be turned mock
95         (EOK == pthread_barrier_init(&m_barrier, NULL, 2)) ? TRUE : FALSE;
96     if (l_barInit) {
97         // LCOV_EXCL_BR_STOP
98       pthread_attr_t attr;
99       struct sched_param params;
100       pthread_attr_init(&attr);
101       pthread_attr_getschedparam(&attr, &params);
102       SI_32 prio = frameworkunified::framework::CFrameworkunifiedThreadPriorities::GetPriority(
103           f_readerName);
104       if (-1 != prio) {  // LCOV_EXCL_BR_LINE 6:Because prio is always -1
105         // LCOV_EXCL_START 6:Because the prio is not always -1
106         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
107         params.sched_priority = prio;
108         pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
109         pthread_attr_setschedparam(&attr, &params);
110         // LCOV_EXCL_STOP
111       }
112
113       if (EOK  == pthread_create(&m_thread, &attr, &CReaderWriter::ThreadFunctionWrapper, this)) {  // LCOV_EXCL_BR_LINE 5:pthread cannot be passed because it cannot be turned mock  // NOLINT[whitespace/line_length]
114         this->m_running = TRUE;
115         l_eStatus = eFrameworkunifiedStatusOK;
116         pthread_barrier_wait(&this->m_barrier); /* Wait for thread to take off*/
117       }
118     }
119   } else {
120     l_eStatus = eFrameworkunifiedStatusOK;
121   }
122   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-: %d", l_eStatus);
123   return (l_eStatus);
124 }
125
126 void* CReaderWriter::ThreadFunctionWrapper(void* param) {
127   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
128   CReaderWriter* l_pObj = reinterpret_cast<CReaderWriter *>(param);
129
130   l_pObj->ThreadFunction(l_pObj);
131   FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error. ThreadFunction has exited");
132   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
133   return NULL;
134 }
135
136 void CReaderWriter::ThreadFunction(CReaderWriter* l_pObj) {
137   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
138   int l_oldState;
139
140   pthread_setname_np(pthread_self(), this->m_readerName.c_str());
141   pthread_cleanup_push(&CReaderWriter::CleanupWrapper, this);
142     pthread_mutex_init(&m_writeMutex, NULL);
143     pthread_mutex_init(&m_pauseMutex, NULL);
144     int l_wait = pthread_barrier_wait(&m_barrier);
145
146     if ((eFrameworkunifiedStatusOK == l_eStatus)
147         // LCOV_EXCL_BR_START 5:pthread cannot be passed because it cannot be turned mock
148         && (((PTHREAD_BARRIER_SERIAL_THREAD == l_wait) || (0 == l_wait)))) {
149         // LCOV_EXCL_BR_STOP
150       UI_8 data[MAX_QUEUE_MSG_SIZE + 1];
151       while (TRUE) {
152         if (TRUE == this->m_paused) {
153           if (EOK == pthread_mutex_lock(&this->m_pauseMutex)) {  // LCOV_EXCL_BR_LINE 5:pthread cannot be passed because it cannot be turned mock
154             (void)pthread_cond_wait(&m_condVariable, &m_pauseMutex);  // LCOV_EXCL_BR_LINE 5:pthread cannot be passed because it cannot be turned mock
155             (void) pthread_mutex_unlock(&this->m_pauseMutex);  // LCOV_EXCL_BR_LINE 5:pthread cannot be passed because it cannot be turned mock
156           }
157         }
158         if (!this->m_reader->IsOpen() || !this->m_writer->IsOpen()) {  // LCOV_EXCL_BR_LINE 6:As it is not always open
159           (void)this->m_reader->Open();  // LCOV_EXCL_BR_LINE 11:Unexpected branch
160           (void)this->m_writer->Open();  // LCOV_EXCL_BR_LINE 11:Unexpected branch
161         }
162
163         if (!this->m_reader->IsOpen() || !this->m_writer->IsOpen()) {
164
165 // ->Reduced frequency of accesses to IsOpen()
166           usleep(1000*1000);  // LCOV_EXCL_BR_LINE 5:C function
167         } else {
168           while ((eFrameworkunifiedStatusOK == l_eStatus) && (FALSE == this->m_paused)) {
169             SI_32 l_bytesRead = -1;
170             SI_32 l_bytesWritten = -1;
171             l_eStatus = this->m_reader->Read(data,
172                 MAX_QUEUE_MSG_SIZE,
173                 l_bytesRead);  // LCOV_EXCL_BR_LINE 11:except,C++ STL
174             if (eFrameworkunifiedStatusOK == l_eStatus) {
175               pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
176                   &l_oldState);
177               if (EOK == pthread_mutex_lock(&this->m_writeMutex)) {  // LCOV_EXCL_BR_LINE 5: c code error case
178                 l_eStatus = this->m_writer->Write(data,
179                     (UI_32) l_bytesRead,
180                     l_bytesWritten);
181                 (void) pthread_mutex_unlock(&this->m_writeMutex);
182               }
183               pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
184                   &l_oldState);
185             }
186           }
187           l_eStatus = eFrameworkunifiedStatusOK;  // Reset l_eStatus
188         }
189       }
190     }
191
192     pthread_cleanup_pop(1);
193 }
194
195
196 void CReaderWriter::CleanupWrapper(void* param) {
197   CReaderWriter* l_pObj = reinterpret_cast<CReaderWriter *>(param);
198
199   l_pObj->Cleanup(l_pObj);
200 }
201
202 void CReaderWriter::Cleanup(CReaderWriter* l_pObj) {
203
204 //  (void) pthread_mutex_unlock(&this->m_pauseMutex);
205 //  (void) pthread_mutex_unlock(&this->m_writeMutex);
206
207
208   if (this->m_reader != NULL) {  // LCOV_EXCL_BR_LINE 5: new will aways sucess, so m_reader can not be null
209     delete (this->m_reader);
210     this->m_reader = NULL;
211   }
212   if (this->m_writer != NULL) {  // LCOV_EXCL_BR_LINE 5: new will aways sucess, so m_writer can not be null
213     delete (this->m_writer);
214     this->m_writer = NULL;
215   }
216   this->m_running = FALSE;
217 }
218
219 EFrameworkunifiedStatus CReaderWriter::FlushCache(std::string f_filename) {
220   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
221   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
222   if (TRUE == this->m_pLoggerCfg->IsLoggingEnabled()) {  // LCOV_EXCL_BR_LINE 6: it can not be false
223     if (EOK == pthread_mutex_lock(&this->m_writeMutex)) {  // LCOV_EXCL_BR_LINE 5:pthread cannot be passed because it cannot be turned mock
224       if (this->m_writer != NULL) {  // LCOV_EXCL_BR_LINE 5: new will aways sucess, so m_writer can not be null
225         l_eStatus = this->m_writer->FlushCache();
226         LOG_STATUS_IF_ERRORED(l_eStatus, "this->m_writer->FlushCache()")
227       }
228       (void) pthread_mutex_unlock(&this->m_writeMutex);
229     }
230
231     UI_32 l_written;
232     if (NULL != this->m_reader) {  // LCOV_EXCL_BR_LINE 6:Because it depends on the startup process
233       l_eStatus = this->m_reader->ReadToFile(f_filename, l_written);
234       /*Don't output error, if function not implemented*/
235       l_eStatus =
236           (l_eStatus == eFrameworkunifiedStatusNotImplemented) ? eFrameworkunifiedStatusOK : l_eStatus;
237       LOG_STATUS_IF_ERRORED(l_eStatus,
238                             "this->m_reader->ReadToFile(f_filename, l_written)");
239     } else {
240       l_eStatus = eFrameworkunifiedStatusNullPointer;
241     }
242   }
243   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
244   return (l_eStatus);
245 }
246
247 EFrameworkunifiedStatus CReaderWriter::UpdateLoggingParameters(void) {
248   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
249   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
250   if (EOK == pthread_mutex_lock(&this->m_writeMutex)) {  // LCOV_EXCL_BR_LINE 5:pthread cannot be passed because it cannot be turned mock
251     if (this->m_writer != NULL) {
252       l_eStatus = this->m_writer->UpdateLoggingParameters();
253     }
254     (void) pthread_mutex_unlock(&this->m_writeMutex);
255   }
256   BOOL l_enabled = this->m_pLoggerCfg->IsLoggingEnabled();
257   if ((this->m_paused == FALSE) && (FALSE == l_enabled)) {
258     this->Pause();
259   } else if ((this->m_paused == TRUE) && (TRUE == l_enabled)) {
260     this->Resume();
261   }
262   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "- : %d", l_eStatus);
263   return (l_eStatus);
264 }
265
266 void CReaderWriter::Pause(void) {
267   (void) pthread_mutex_lock(&this->m_pauseMutex);
268   this->m_paused = TRUE;
269
270   (void) pthread_mutex_unlock(&this->m_pauseMutex);
271 }
272
273 void CReaderWriter::Resume(void) {
274   (void) pthread_mutex_lock(&this->m_pauseMutex);
275   if (this->m_reader != NULL) {  // LCOV_EXCL_BR_LINE 5: new will aways sucess, so m_reader can not be null
276     (void) this->m_reader->ResetPosition();
277   }
278   pthread_cond_signal(&m_condVariable);
279   this->m_paused = FALSE;
280   (void) pthread_mutex_unlock(&this->m_pauseMutex);
281 }
282 }  // namespace ReaderWriter