communicationthread.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. = StarPU-Top for StarPU =
  3. Copyright (C) 2011
  4. William Braik
  5. Yann Courtois
  6. Jean-Marie Couteyen
  7. Anthony Roy
  8. Copyright (C) 2011 Université de Bordeaux 1
  9. This library is free software; you can redistribute it and/or
  10. modify it under the terms of the GNU Lesser General Public
  11. License as published by the Free Software Foundation; either
  12. version 2.1 of the License, or (at your option) any later version.
  13. This library is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. Lesser General Public License for more details.
  17. You should have received a copy of the GNU Lesser General Public
  18. License along with this library; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <QMessageBox>
  22. #include "communicationthread.h"
  23. #include "configurationmanager.h"
  24. #include "mainwindow.h"
  25. #include "communicationmanager.h"
  26. #include "starpu_top_types.h"
  27. const int MAX_CONNECTION_ATTEMPTS = 10;
  28. CommunicationThread::CommunicationThread(
  29. MainWindow *mainWindow,
  30. ConfigurationManager *configurationManager)
  31. {
  32. static bool instanciated = false;
  33. Q_ASSERT_X(instanciated == false, "CommunicationThread's' constructor",
  34. "Singleton pattern violated - "
  35. "CommunicationThread instanciated more than once");
  36. _mainWindow = mainWindow;
  37. _configurationManager = configurationManager;
  38. _communicationManager = 0;
  39. _SSHProcess = NULL;
  40. instanciated = true;
  41. QObject::connect(this, SIGNAL(progress(QString)),
  42. _mainWindow, SLOT(updateStatusBarMessage(QString)));
  43. QObject::connect(this, SIGNAL(disconnected()),
  44. _mainWindow, SLOT(disconnected()));
  45. QObject::connect(this, SIGNAL(abort(QString)),
  46. _mainWindow, SLOT(connectionAborted(QString)));
  47. qDebug() << "CommunicationThread : initializing";
  48. }
  49. CommunicationThread::~CommunicationThread()
  50. {
  51. qDebug() << "CommunicationThread : terminating";
  52. delete _communicationManager;
  53. }
  54. void CommunicationThread::createNewCommunicationManager(void)
  55. {
  56. emit progress(tr("Connecting..."));
  57. if (_communicationManager == 0)
  58. delete(_communicationManager );
  59. _communicationManager = new CommunicationManager(this);
  60. // Type registering is necessary for Qt "Queued Connections"
  61. // as we are going to send signals to a different thread
  62. qRegisterMetaType<QAbstractSocket::SocketError> (
  63. "QAbstractSocket::SocketError");
  64. // Connection events
  65. QObject::connect(_communicationManager, SIGNAL(protoConnected()),
  66. _mainWindow, SLOT(connectionSucceeded()));
  67. QObject::connect(_communicationManager, SIGNAL(protoConnected()),
  68. this, SLOT(connectionSucceeded()));
  69. QObject::connect(_communicationManager, SIGNAL(error(QAbstractSocket::SocketError)),
  70. this, SLOT(connectionError(QAbstractSocket::SocketError)));
  71. QObject::connect(_communicationManager, SIGNAL(disconnected()),
  72. this, SLOT(connectionDisconnected()));
  73. // Change communication state
  74. QObject::connect(_communicationManager, SIGNAL(protocolError(QString)),
  75. _mainWindow, SLOT(protocolErrorCaught(QString)));
  76. QObject::connect(_communicationManager,
  77. SIGNAL(sessionTimeSynchronized(qlonglong)),
  78. _mainWindow,
  79. SLOT(synchronizeSessionTime(qlonglong)));
  80. QObject::connect(_communicationManager,
  81. SIGNAL(serverInitCompleted(QString,
  82. QList<DataDescription*>*,
  83. QList<ParamDescription*>*,
  84. QList<Starpu_TopDevice>*)),
  85. _mainWindow, SLOT(initClient(
  86. QString,
  87. QList<DataDescription*>*,
  88. QList<ParamDescription*>*,
  89. QList<Starpu_TopDevice>*)));
  90. // Output data
  91. QObject::connect(_mainWindow, SIGNAL(clientLaunched()),
  92. _communicationManager, SLOT(sendGoMessage()));
  93. QObject::connect(_mainWindow, SIGNAL(dataEnabled(int)),
  94. _communicationManager, SLOT(sendDataEnableMessage(int)));
  95. QObject::connect(_mainWindow, SIGNAL(dataDisabled(int)),
  96. _communicationManager, SLOT(sendDataDisableMessage(int)));
  97. QObject::connect(_mainWindow, SIGNAL(paramValueUpdated(int,bool)),
  98. _communicationManager, SLOT(sendParamSetMessage(int,bool)));
  99. QObject::connect(_mainWindow, SIGNAL(paramValueUpdated(int,int)),
  100. _communicationManager, SLOT(sendParamSetMessage(int,int)));
  101. QObject::connect(_mainWindow, SIGNAL(paramValueUpdated(int,double)),
  102. _communicationManager, SLOT(sendParamSetMessage(int,double)));
  103. QObject::connect(_mainWindow, SIGNAL(debugEnabled(bool)),
  104. _communicationManager, SLOT(sendDebugEnabledMessage(bool)));
  105. QObject::connect(_mainWindow, SIGNAL(debugStepped()),
  106. _communicationManager, SLOT(sendStepMessage()));
  107. // Input data
  108. QObject::connect(_communicationManager,
  109. SIGNAL(notifyDebugEnabled(bool)),
  110. _mainWindow, SLOT(setDebug(bool)));
  111. QObject::connect(_communicationManager,
  112. SIGNAL(notifyDebugMessage(QString)), _mainWindow,
  113. SLOT(setDebugMessage(QString)));
  114. QObject::connect(_communicationManager,
  115. SIGNAL(notifyDebugLock(QString)), _mainWindow,
  116. SLOT(setDebugLock(QString)));
  117. QObject ::connect(_communicationManager,
  118. SIGNAL(notifyParamUpdate(int,bool,qlonglong)),
  119. _mainWindow, SLOT(updateInteractiveWidget(int,bool,qlonglong)));
  120. QObject::connect(_communicationManager,
  121. SIGNAL(notifyParamUpdate(int,int,qlonglong)),
  122. _mainWindow, SLOT(updateInteractiveWidget(int,int,qlonglong)));
  123. QObject::connect(_communicationManager,
  124. SIGNAL(notifyParamUpdate(int,double,qlonglong)),
  125. _mainWindow, SLOT(updateInteractiveWidget(int,double,qlonglong)));
  126. QObject::connect(_communicationManager,
  127. SIGNAL(notifyTaskPrevUpdate(int,int,qlonglong,qlonglong,qlonglong)),
  128. _mainWindow,
  129. SLOT(updateTaskPrev(int,int,qlonglong,qlonglong,qlonglong)));
  130. QObject::connect(_communicationManager,
  131. SIGNAL(notifyTaskStartUpdate(int,int,qlonglong)),
  132. _mainWindow, SLOT(updateTaskStart(int,int,qlonglong)));
  133. QObject::connect(_communicationManager,
  134. SIGNAL(notifyTaskEndUpdate(int,qlonglong)),
  135. _mainWindow, SLOT(updateTaskEnd(int,qlonglong)));
  136. QObject::connect(_communicationManager,
  137. SIGNAL(notifyDataUpdate(int,bool,qlonglong)),
  138. _mainWindow, SLOT(updateDataWidget(int,bool,qlonglong)));
  139. QObject::connect(_communicationManager,
  140. SIGNAL(notifyDataUpdate(int,int,qlonglong)),
  141. _mainWindow, SLOT(updateDataWidget(int,int,qlonglong)));
  142. QObject::connect(_communicationManager,
  143. SIGNAL(notifyDataUpdate(int,double,qlonglong)),
  144. _mainWindow, SLOT(updateDataWidget(int,double,qlonglong)));
  145. _communicationManager->connectToHost(_configurationManager->serverHost(),
  146. _configurationManager->serverPort());
  147. }
  148. void CommunicationThread::run()
  149. {
  150. if(_configurationManager->ssh())
  151. {
  152. _connectionAttemptsCount = 0;
  153. QString commandLine;
  154. #ifdef WIN32
  155. commandLine.append("cmd /c start ");
  156. #else
  157. commandLine.append("xterm -e ");
  158. #endif
  159. commandLine.append(_configurationManager->commandLine());
  160. qDebug() << "CommunicationThread : executing SSH command line : "
  161. << commandLine;
  162. _SSHProcess = new QProcess();
  163. _SSHProcess->start(commandLine);
  164. }
  165. createNewCommunicationManager();
  166. exec();
  167. }
  168. void CommunicationThread::connectionError(QAbstractSocket::SocketError error)
  169. {
  170. qDebug() << "CommunicationThread : connection error occured" << error;
  171. switch (error)
  172. {
  173. case QAbstractSocket::ConnectionRefusedError:
  174. if (_configurationManager->ssh()) {
  175. if (_connectionAttemptsCount++ <= MAX_CONNECTION_ATTEMPTS) {
  176. qDebug() << "refused, retrying";
  177. emit progress(tr("Connecting refused, retrying (") + QString::number(_connectionAttemptsCount)+(")..."));
  178. this->sleep(1);
  179. _communicationManager->connectToHost(_configurationManager->serverHost(),
  180. _configurationManager->serverPort());
  181. break;
  182. }
  183. }
  184. qDebug() << "Too many retries, giving up";
  185. emit abort(tr("Connection refused by server (port : ") + QString::number(
  186. _configurationManager->serverPort()) + tr(") !"));
  187. delete _SSHProcess;
  188. exit(1);
  189. break;
  190. case QAbstractSocket::RemoteHostClosedError:
  191. if (_connectionAttemptsCount == INT_MAX) {
  192. _communicationManager->abort();
  193. } else {
  194. if (_configurationManager->ssh()) {
  195. if (_connectionAttemptsCount++ <= MAX_CONNECTION_ATTEMPTS) {
  196. qDebug() << "closed, retrying";
  197. emit progress(tr("Connecting closed, retrying (") + QString::number(_connectionAttemptsCount)+(")..."));
  198. _communicationManager->abort();
  199. break;
  200. }
  201. }
  202. qDebug() << "Too many retries, giving up";
  203. emit abort(tr("Server closed the connection !"));
  204. }
  205. delete _SSHProcess;
  206. exit(1);
  207. break;
  208. case QAbstractSocket::HostNotFoundError:
  209. emit abort(tr("Server not found (host name : ")
  210. + _configurationManager->serverHost() + tr(") !"));
  211. delete _SSHProcess;
  212. exit(1);
  213. break;
  214. default:
  215. emit abort(tr("Connection to server is broken !"));
  216. delete _SSHProcess;
  217. exit(1);
  218. }
  219. }
  220. void CommunicationThread::connectionSucceeded()
  221. {
  222. /* Connected at application level, do not try to reconnect on closure */
  223. _connectionAttemptsCount = INT_MAX;
  224. }
  225. void CommunicationThread::connectionDisconnected()
  226. {
  227. if (_connectionAttemptsCount == INT_MAX) {
  228. /* Only raise to mainWindow if we had connected */
  229. emit disconnected();
  230. } else {
  231. /* Just closing for a retry, do retry */
  232. qDebug() << "and retrying";
  233. this->sleep(1);
  234. createNewCommunicationManager();
  235. }
  236. }