00001 #include "LCDWidget.h" 00002 #include "LCDUtils.h" 00003 #include "LCDSensor.h" 00004 00005 #include <string> 00006 #include <stdio.h> 00007 #include <unistd.h> 00008 #include <pthread.h> 00009 00010 using namespace std; 00011 00012 const int LCDSensor::MAX_CMD_RESULT_LINE_SIZE = 255; 00013 00014 LCDSensor::LCDSensor() 00015 { 00016 _exist = true; 00017 _onChangeThreadStarted = false; 00018 } 00019 00020 LCDSensor::~LCDSensor() 00021 { 00022 _exist = false; 00023 if (_onChangeThreadStarted) 00024 { 00025 if (::pthread_cancel(_onChangeThread) == 0) 00026 { 00027 ::pthread_join(_onChangeThread, 0); 00028 } 00029 _onChangeThreadStarted = false; 00030 } 00031 00032 WidgetTimeOutList::iterator it; 00033 for (it = _onTimeOutList.begin(); it != _onTimeOutList.end(); it++) 00034 { 00035 if (::pthread_cancel(it->second._thread) == 0) 00036 { 00037 ::pthread_join(it->second._thread, 0); 00038 } 00039 } 00040 } 00041 00042 bool LCDSensor::exists() 00043 { 00044 return _exist; 00045 } 00046 00047 void LCDSensor::fireChanged() 00048 { 00049 string value = getCurrentValue(); 00050 WidgetList::iterator it; 00051 for (it = _onChangeList.begin(); it != _onChangeList.end(); it++) 00052 { 00053 if (LCDElement::exists(it->first)) 00054 { 00055 it->second->valueCallback(value); 00056 } 00057 else 00058 { 00059 removeOnChangeWidget(it->first); 00060 } 00061 } 00062 } 00063 00064 const LCDWidgetTimeOut &LCDSensor::getThreadWidgetInfo(const ::pthread_t &thread) 00065 { 00066 WidgetTimeOutList::iterator it; 00067 00068 for (it = _onTimeOutList.begin(); it != _onTimeOutList.end(); it++) 00069 { 00070 if (::pthread_equal(thread, it->second._thread)) 00071 { 00072 return it->second; 00073 } 00074 } 00075 00076 static LCDWidgetTimeOut dummy; 00077 dummy._timeOut=0; 00078 dummy._widget = 0; 00079 00080 return dummy; 00081 } 00082 00083 string LCDSensor::intToString(int value) 00084 { 00085 return LCDUtils::toString(value); 00086 } 00087 00088 string LCDSensor::executeCommand(const string &cmd) 00089 { 00090 string silentCmd = cmd + " 2>/dev/null"; 00091 char buf[MAX_CMD_RESULT_LINE_SIZE + 1]; 00092 buf[0]='\0'; 00093 FILE *ptr; 00094 00095 if ((ptr = popen(silentCmd.c_str(), "r")) != NULL) 00096 { 00097 fgets(buf, MAX_CMD_RESULT_LINE_SIZE, ptr); 00098 pclose(ptr); 00099 } 00100 00101 int len = strlen(buf); 00102 00103 string result(buf, (len > 0) ? (len - 1) : 0); 00104 00105 return result; 00106 } 00107 00108 void LCDSensor::addOnChangeWidget(LCDWidget *widget) 00109 { 00110 if (!_onChangeThreadStarted) 00111 { 00112 ::pthread_create(&_onChangeThread, 0, (ThreadFunction)updateWhenChanged, (void *)this); 00113 _onChangeThreadStarted = true; 00114 } 00115 00116 _onChangeList[widget->getId()] = widget; 00117 } 00118 00119 void LCDSensor::removeOnChangeWidget(LCDWidget *widget) 00120 { 00121 removeOnChangeWidget(widget->getId()); 00122 } 00123 00124 void LCDSensor::removeOnChangeWidget(string id) 00125 { 00126 _onChangeList.erase(id); 00127 if (_onChangeList.empty() && _onChangeThreadStarted) 00128 { 00129 if (::pthread_cancel(_onChangeThread) == 0) 00130 { 00131 ::pthread_join(_onChangeThread, 0); 00132 } 00133 _onChangeThreadStarted = false; 00134 } 00135 } 00136 00137 void LCDSensor::addOnTimeOutWidget(LCDWidget *widget, int timeout) 00138 { 00139 LCDWidgetTimeOut tmpWidget; 00140 00141 tmpWidget._timeOut = timeout; 00142 tmpWidget._widget = widget; 00143 tmpWidget._widgetId = widget->getId(); 00144 00145 _onTimeOutList[widget->getId()] = tmpWidget; 00146 00147 ::pthread_create(&(_onTimeOutList[widget->getId()]._thread), 0, (ThreadFunction)updateEach, (void *)this); 00148 } 00149 00150 void LCDSensor::removeOnTimeOutWidget(LCDWidget *widget) 00151 { 00152 removeOnTimeOutWidget(widget->getId()); 00153 } 00154 00155 void LCDSensor::removeOnTimeOutWidget(string id) 00156 { 00157 if (::pthread_cancel(_onTimeOutList[id]._thread) == 0) 00158 { 00159 ::pthread_join(_onTimeOutList[id]._thread, 0); 00160 } 00161 _onTimeOutList.erase(id); 00162 } 00163 00164 void *updateWhenChanged(void *param) 00165 { 00166 ::pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0); 00167 00168 LCDSensor *daddy = (LCDSensor *)param; 00169 00170 while (daddy->exists()) 00171 { 00172 daddy->waitForChange(); 00173 daddy->fireChanged(); 00174 } 00175 } 00176 00177 void *updateEach(void *param) 00178 { 00179 ::pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0); 00180 00181 LCDSensor *daddy = (LCDSensor *)param; 00182 00183 LCDWidgetTimeOut widgetInfo; 00184 00185 while (!widgetInfo.isValid()) 00186 { 00187 widgetInfo = daddy->getThreadWidgetInfo(::pthread_self()); 00188 usleep(10); 00189 } 00190 00191 while (daddy->exists()) 00192 { 00193 if (LCDElement::exists(widgetInfo._widgetId)) 00194 { 00195 widgetInfo._widget->valueCallback(daddy->getCurrentValue()); 00196 usleep(widgetInfo._timeOut * 100000); 00197 ::pthread_testcancel(); 00198 } 00199 else 00200 { 00201 daddy->removeOnTimeOutWidget(widgetInfo._widgetId); 00202 } 00203 } 00204 }