espthread.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning (disable : 4786)
  14. #include "esphttp.hpp"
  15. //Jlib
  16. #include "jliball.hpp"
  17. //CRT / OS
  18. #ifdef _WIN32
  19. #define WIN32_LEAN_AND_MEAN
  20. #include <windows.h>
  21. #include <winsock2.h>
  22. #include <ws2tcpip.h>
  23. #include <signal.h>
  24. #include <errno.h>
  25. #else
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <netinet/tcp.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. #include <stddef.h>
  32. #include <errno.h>
  33. #endif
  34. //SCM Interfaces
  35. //#include "IAEsp.hpp"
  36. //#include "IAEsc.hpp"
  37. //ESP Core
  38. #include "espthread.hpp"
  39. CEspProtocolThread::CEspProtocolThread(const char *name)
  40. : Thread("CEspProtocolThread"), m_name(name), keepAlive(false)
  41. {
  42. terminating = false;
  43. }
  44. CEspProtocolThread::CEspProtocolThread(ISocket *sock, const char *name)
  45. : Thread("CEspProtocolThread"), m_name(name), keepAlive(false)
  46. {
  47. terminating = false;
  48. setSocket(sock);
  49. }
  50. CEspProtocolThread::~CEspProtocolThread()
  51. {
  52. }
  53. void CEspProtocolThread::start()
  54. {
  55. Thread::start();
  56. }
  57. const char *CEspProtocolThread::getServiceName()
  58. {
  59. return m_name.get();
  60. }
  61. bool CEspProtocolThread::onRequest()
  62. {
  63. return false;
  64. }
  65. void CEspProtocolThread::setSocket(ISocket *sock)
  66. {
  67. CriticalBlock block(sect);
  68. m_socket.setown(sock);
  69. //DBGLOG("%s -- serving socket(%d):", this->getServiceName(), sock->OShandle());
  70. char xname[256]={0};
  71. m_socket->name(xname, 256);
  72. //DBGLOG("... on net address(%s)", xname);
  73. m_socket->peer_name(xname, 256);
  74. //DBGLOG("... from net address(%s)", xname);
  75. ticksem.signal();
  76. }
  77. void CEspProtocolThread::stop(bool wait)
  78. {
  79. terminating = true;
  80. ticksem.signal();
  81. //if (wait)
  82. // join();
  83. }
  84. //Unused code cause Linker warning LNK4089:
  85. // all references to 'dynamic-link library' discarded by /OPT:REF
  86. #if 0
  87. bool wait_to_exit(bool can_continue, ISocket* sock, int timeoutsecs)
  88. {
  89. if(sock == NULL)
  90. return false;
  91. int sockid = sock->OShandle();
  92. fd_set rdfds;
  93. timeval selecttimeout;
  94. FD_ZERO(&rdfds);
  95. FD_SET(sockid, &rdfds);
  96. selecttimeout.tv_sec = timeoutsecs;
  97. selecttimeout.tv_usec = 0;
  98. int availread = 0;
  99. int n = select(sockid + 1, &rdfds, NULL, NULL, &selecttimeout);
  100. if (n < 0)
  101. {
  102. if (errno != EINTR) {
  103. DBGLOG("error selecting in wait_to_exit() error %d\n", errno);
  104. return false;
  105. }
  106. }
  107. else if(n > 0)
  108. {
  109. DBGLOG("Select on socket %d returns before timeout", sockid);
  110. availread = sock->avail_read();
  111. if(availread > 0)
  112. {
  113. // This is the only place that can possibly return true.
  114. return can_continue;
  115. }
  116. else
  117. {
  118. DBGLOG("The remote side of the socket %d has been closed.", sockid);
  119. return false;
  120. }
  121. }
  122. else
  123. {
  124. DBGLOG("Select returns after timeout");
  125. return false;
  126. }
  127. return false;
  128. }
  129. #endif
  130. int CEspProtocolThread::run()
  131. {
  132. Link();
  133. try
  134. {
  135. bool can_continue = false;
  136. do
  137. {
  138. can_continue = onRequest();
  139. }
  140. while (can_continue);
  141. }
  142. catch (IException *e)
  143. {
  144. StringBuffer estr;
  145. ERRLOG("Exception(%d, %s) in CEspProtocolThread::run while processing request.", e->errorCode(), e->errorMessage(estr).str());
  146. e->Release();
  147. }
  148. catch(...)
  149. {
  150. ERRLOG("Unknown Exception in CEspProtocolThread::run while processing request.");
  151. }
  152. if(!keepAlive)
  153. {
  154. try
  155. {
  156. m_socket->shutdown();
  157. m_socket->close();
  158. }
  159. catch (IException *e)
  160. {
  161. StringBuffer estr;
  162. DBGLOG("Exception(%d, %s) - in CEspProtocolThread::run while closing socket.", e->errorCode(), e->errorMessage(estr).str());
  163. e->Release();
  164. }
  165. catch(...)
  166. {
  167. DBGLOG("General Exception - in CEspProtocolThread::run while closing socket.");
  168. }
  169. }
  170. Release();
  171. return 0;
  172. }