Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MQTTSNGWProcess.cpp
00001 /************************************************************************************** 00002 * Copyright (c) 2016, Tomoaki Yamaguchi 00003 * 00004 * All rights reserved. This program and the accompanying materials 00005 * are made available under the terms of the Eclipse Public License v1.0 00006 * and Eclipse Distribution License v1.0 which accompany this distribution. 00007 * 00008 * The Eclipse Public License is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * and the Eclipse Distribution License is available at 00011 * http://www.eclipse.org/org/documents/edl-v10.php. 00012 * 00013 * Contributors: 00014 * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation 00015 **************************************************************************************/ 00016 00017 #include <stdio.h> 00018 #include <stdlib.h> 00019 #include <string.h> 00020 #include <stdarg.h> 00021 #include <signal.h> 00022 #include <Timer.h> 00023 #include <exception> 00024 #include <getopt.h> 00025 #include <unistd.h> 00026 #include "MQTTSNGWProcess.h" 00027 #include "Threading.h" 00028 00029 using namespace std; 00030 using namespace MQTTSNGW; 00031 00032 char* currentDateTime(void); 00033 00034 /*===================================== 00035 Global Variables & Functions 00036 ======================================*/ 00037 Process* MQTTSNGW::theProcess = nullptr; 00038 MultiTaskProcess* MQTTSNGW::theMultiTaskProcess = nullptr; 00039 00040 /* 00041 * Save the type of signal 00042 */ 00043 volatile int theSignaled = 0; 00044 00045 static void signalHandler(int sig) 00046 { 00047 theSignaled = sig; 00048 } 00049 00050 /*===================================== 00051 Class Process 00052 ====================================*/ 00053 Process::Process() 00054 { 00055 _argc = 0; 00056 _argv = 0; 00057 _configDir = CONFIG_DIRECTORY; 00058 _configFile = CONFIG_FILE; 00059 _log = 0; 00060 } 00061 00062 Process::~Process() 00063 { 00064 if (_rb ) 00065 { 00066 delete _rb; 00067 } 00068 if ( _rbsem ) 00069 { 00070 delete _rbsem; 00071 } 00072 } 00073 00074 void Process::run() 00075 { 00076 00077 } 00078 00079 void Process::initialize(int argc, char** argv) 00080 { 00081 char param[MQTTSNGW_PARAM_MAX]; 00082 _argc = argc; 00083 _argv = argv; 00084 signal(SIGINT, signalHandler); 00085 signal(SIGTERM, signalHandler); 00086 signal(SIGHUP, signalHandler); 00087 00088 int opt; 00089 while ((opt = getopt(_argc, _argv, "f:")) != -1) 00090 { 00091 if ( opt == 'f' ) 00092 { 00093 string config = string(optarg); 00094 size_t pos = 0; 00095 if ( (pos = config.find_last_of("/")) == string::npos ) 00096 { 00097 _configFile = optarg; 00098 } 00099 else 00100 { 00101 _configFile = config.substr(pos + 1, config.size() - pos - 1);; 00102 _configDir = config.substr(0, pos + 1); 00103 } 00104 } 00105 } 00106 _rbsem = new Semaphore(MQTTSNGW_RB_SEMAPHOR_NAME, 0); 00107 _rb = new RingBuffer(_configDir.c_str()); 00108 00109 if (getParam("ShearedMemory", param) == 0) 00110 { 00111 if (!strcasecmp(param, "YES")) 00112 { 00113 _log = 1; 00114 } 00115 else 00116 { 00117 _log = 0; 00118 } 00119 } 00120 } 00121 00122 void Process::putLog(const char* format, ...) 00123 { 00124 _mt.lock(); 00125 va_list arg; 00126 va_start(arg, format); 00127 vsprintf(_rbdata, format, arg); 00128 va_end(arg); 00129 if (strlen(_rbdata)) 00130 { 00131 if ( _log > 0 ) 00132 { 00133 _rb->put(_rbdata); 00134 _rbsem->post(); 00135 } 00136 else 00137 { 00138 printf("%s", _rbdata); 00139 } 00140 } 00141 _mt.unlock(); 00142 } 00143 00144 int Process::getArgc() 00145 { 00146 return _argc; 00147 } 00148 00149 char** Process::getArgv() 00150 { 00151 return _argv; 00152 } 00153 00154 int Process::getParam(const char* parameter, char* value) 00155 { 00156 char str[MQTTSNGW_PARAM_MAX]; 00157 char param[MQTTSNGW_PARAM_MAX]; 00158 FILE *fp; 00159 00160 int i = 0, j = 0; 00161 string configPath = _configDir + _configFile; 00162 00163 if ((fp = fopen(configPath.c_str(), "r")) == NULL) 00164 { 00165 WRITELOG("No config file:[%s]\n", configPath.c_str()); 00166 return -1; 00167 } 00168 00169 while (true) 00170 { 00171 if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL) 00172 { 00173 fclose(fp); 00174 return -3; 00175 } 00176 if (!strncmp(str, parameter, strlen(parameter))) 00177 { 00178 while (str[i++] != '=') 00179 { 00180 ; 00181 } 00182 while (str[i] != '\n') 00183 { 00184 param[j++] = str[i++]; 00185 } 00186 param[j] = '\0'; 00187 00188 for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--) 00189 ; 00190 param[i + 1] = '\0'; 00191 for (i = 0; isspace(param[i]); i++) 00192 ; 00193 if (i > 0) 00194 { 00195 j = 0; 00196 while (param[i]) 00197 param[j++] = param[i++]; 00198 param[j] = '\0'; 00199 } 00200 strcpy(value, param); 00201 fclose(fp); 00202 return 0; 00203 } 00204 } 00205 fclose(fp); 00206 return -2; 00207 } 00208 00209 const char* Process::getLog() 00210 { 00211 int len = 0; 00212 _mt.lock(); 00213 while ((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0) 00214 { 00215 _rbsem->timedwait(1000); 00216 if ( checkSignal() == SIGINT) 00217 { 00218 break; 00219 } 00220 } 00221 *(_rbdata + len) = 0; 00222 _mt.unlock(); 00223 return _rbdata; 00224 } 00225 00226 void Process::resetRingBuffer() 00227 { 00228 _rb->reset(); 00229 } 00230 00231 int Process::checkSignal(void) 00232 { 00233 return theSignaled; 00234 } 00235 00236 const string* Process::getConfigDirName(void) 00237 { 00238 return &_configDir; 00239 } 00240 00241 const string* Process::getConfigFileName(void) 00242 { 00243 return &_configFile; 00244 } 00245 00246 /*===================================== 00247 Class MultiTaskProcess 00248 ====================================*/ 00249 MultiTaskProcess::MultiTaskProcess() 00250 { 00251 theMultiTaskProcess = this; 00252 _threadCount = 0; 00253 _stopCount = 0; 00254 } 00255 00256 MultiTaskProcess::~MultiTaskProcess() 00257 { 00258 for (int i = 0; i < _threadCount; i++) 00259 { 00260 _threadList[i]->stop(); 00261 } 00262 } 00263 00264 void MultiTaskProcess::initialize(int argc, char** argv) 00265 { 00266 Process::initialize(argc, argv); 00267 for (int i = 0; i < _threadCount; i++) 00268 { 00269 _threadList[i]->initialize(argc, argv); 00270 } 00271 00272 } 00273 00274 void MultiTaskProcess::run(void) 00275 { 00276 for (int i = 0; i < _threadCount; i++) 00277 { 00278 _threadList[i]->start(); 00279 } 00280 00281 try 00282 { 00283 while(true) 00284 { 00285 if (theProcess->checkSignal() == SIGINT) 00286 { 00287 return; 00288 } 00289 sleep(1); 00290 } 00291 } 00292 catch(Exception* ex) 00293 { 00294 ex->writeMessage(); 00295 } 00296 catch(...) 00297 { 00298 throw; 00299 } 00300 } 00301 00302 void MultiTaskProcess::waitStop(void) 00303 { 00304 while (_stopCount < _threadCount) 00305 { 00306 sleep(1); 00307 } 00308 } 00309 00310 void MultiTaskProcess::threadStoped(void) 00311 { 00312 _mutex.lock(); 00313 _stopCount++; 00314 _mutex.unlock(); 00315 00316 } 00317 00318 void MultiTaskProcess::attach(Thread* thread) 00319 { 00320 _mutex.lock(); 00321 if (_threadCount < MQTTSNGW_MAX_TASK) 00322 { 00323 _threadList[_threadCount] = thread; 00324 _threadCount++; 00325 } 00326 else 00327 { 00328 _mutex.unlock(); 00329 throw Exception("Full of Threads"); 00330 } 00331 _mutex.unlock(); 00332 } 00333 00334 int MultiTaskProcess::getParam(const char* parameter, char* value) 00335 { 00336 _mutex.lock(); 00337 int rc = Process::getParam(parameter, value); 00338 _mutex.unlock(); 00339 if (rc == -1) 00340 { 00341 throw Exception("No config file."); 00342 } 00343 return rc; 00344 } 00345 00346 /*===================================== 00347 Class Exception 00348 ======================================*/ 00349 Exception::Exception(const string& message) 00350 { 00351 _message = message; 00352 _exNo = 0; 00353 _fileName = 0; 00354 _functionName = 0; 00355 _line = 0; 00356 } 00357 00358 Exception::Exception(const int exNo, const string& message) 00359 { 00360 _message = message; 00361 _exNo = exNo; 00362 _fileName = nullptr; 00363 _functionName = nullptr; 00364 _line = 0; 00365 } 00366 00367 Exception::Exception(const int exNo, const string& message, const char* file, 00368 const char* function, const int line) 00369 { 00370 _message = message; 00371 _exNo = exNo; 00372 _fileName = file; 00373 _functionName = function; 00374 _line = line; 00375 } 00376 00377 Exception::~Exception() throw () 00378 { 00379 00380 } 00381 00382 const char* Exception::what() const throw () 00383 { 00384 return _message.c_str(); 00385 } 00386 00387 const char* Exception::getFileName() 00388 { 00389 return _fileName; 00390 } 00391 00392 const char* Exception::getFunctionName() 00393 { 00394 return _functionName; 00395 } 00396 00397 const int Exception::getLineNo() 00398 { 00399 return _line; 00400 } 00401 00402 const int Exception::getExceptionNo() 00403 { 00404 return _exNo; 00405 } 00406 00407 void Exception::writeMessage() 00408 { 00409 if (getExceptionNo() == 0 ) 00410 { 00411 WRITELOG("%s %s\n", currentDateTime(), what()); 00412 } 00413 else 00414 { 00415 WRITELOG("%s:%-6d %s line %-4d %s() : %s\n", currentDateTime(), getExceptionNo(), 00416 getFileName(), getLineNo(), getFunctionName(), what()); 00417 } 00418 }
Generated on Wed Jul 13 2022 10:46:03 by
1.7.2