espthread.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. #ifdef ESPHTTP_EXPORTS
  15. #define esp_http_decl DECL_EXPORT
  16. #else
  17. #define esp_http_decl DECL_IMPORT
  18. #endif
  19. //Jlib
  20. #include "jliball.hpp"
  21. //CRT / OS
  22. #ifdef _WIN32
  23. #define WIN32_LEAN_AND_MEAN
  24. #include <windows.h>
  25. #include <winsock2.h>
  26. #include <ws2tcpip.h>
  27. #include <signal.h>
  28. #include <errno.h>
  29. #else
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <netinet/tcp.h>
  33. #include <netinet/in.h>
  34. #include <arpa/inet.h>
  35. #include <stddef.h>
  36. #include <errno.h>
  37. #endif
  38. //SCM Interfaces
  39. //#include "IAEsp.hpp"
  40. //#include "IAEsc.hpp"
  41. //ESP Core
  42. #include "espthread.hpp"
  43. CEspProtocolThread::CEspProtocolThread(const char *name)
  44. : Thread("CEspProtocolThread"), m_name(name), keepAlive(false)
  45. {
  46. terminating = false;
  47. }
  48. CEspProtocolThread::CEspProtocolThread(ISocket *sock, const char *name)
  49. : Thread("CEspProtocolThread"), m_name(name), keepAlive(false)
  50. {
  51. terminating = false;
  52. setSocket(sock);
  53. }
  54. CEspProtocolThread::~CEspProtocolThread()
  55. {
  56. }
  57. void CEspProtocolThread::start()
  58. {
  59. Thread::start();
  60. }
  61. const char *CEspProtocolThread::getServiceName()
  62. {
  63. return m_name.get();
  64. }
  65. bool CEspProtocolThread::onRequest()
  66. {
  67. return false;
  68. }
  69. void CEspProtocolThread::setSocket(ISocket *sock)
  70. {
  71. CriticalBlock block(sect);
  72. m_socket.setown(sock);
  73. //DBGLOG("%s -- serving socket(%d):", this->getServiceName(), sock->OShandle());
  74. char xname[256]={0};
  75. m_socket->name(xname, 256);
  76. //DBGLOG("... on net address(%s)", xname);
  77. m_socket->peer_name(xname, 256);
  78. //DBGLOG("... from net address(%s)", xname);
  79. ticksem.signal();
  80. }
  81. void CEspProtocolThread::stop(bool wait)
  82. {
  83. terminating = true;
  84. ticksem.signal();
  85. //if (wait)
  86. // join();
  87. }
  88. //Unused code cause Linker warning LNK4089:
  89. // all references to 'dynamic-link library' discarded by /OPT:REF
  90. #if 0
  91. bool wait_to_exit(bool can_continue, ISocket* sock, int timeoutsecs)
  92. {
  93. if(sock == NULL)
  94. return false;
  95. int sockid = sock->OShandle();
  96. fd_set rdfds;
  97. timeval selecttimeout;
  98. FD_ZERO(&rdfds);
  99. FD_SET(sockid, &rdfds);
  100. selecttimeout.tv_sec = timeoutsecs;
  101. selecttimeout.tv_usec = 0;
  102. int availread = 0;
  103. int n = select(sockid + 1, &rdfds, NULL, NULL, &selecttimeout);
  104. if (n < 0)
  105. {
  106. if (errno != EINTR) {
  107. DBGLOG("error selecting in wait_to_exit() error %d\n", errno);
  108. return false;
  109. }
  110. }
  111. else if(n > 0)
  112. {
  113. DBGLOG("Select on socket %d returns before timeout", sockid);
  114. availread = sock->avail_read();
  115. if(availread > 0)
  116. {
  117. // This is the only place that can possibly return true.
  118. return can_continue;
  119. }
  120. else
  121. {
  122. DBGLOG("The remote side of the socket %d has been closed.", sockid);
  123. return false;
  124. }
  125. }
  126. else
  127. {
  128. DBGLOG("Select returns after timeout");
  129. return false;
  130. }
  131. return false;
  132. }
  133. #endif
  134. int CEspProtocolThread::run()
  135. {
  136. Link();
  137. try
  138. {
  139. bool can_continue = false;
  140. do
  141. {
  142. can_continue = onRequest();
  143. }
  144. while (can_continue);
  145. }
  146. catch (IException *e)
  147. {
  148. StringBuffer estr;
  149. ERRLOG("Exception(%d, %s) in CEspProtocolThread::run while processing request.", e->errorCode(), e->errorMessage(estr).str());
  150. e->Release();
  151. }
  152. catch(...)
  153. {
  154. ERRLOG("Unknown Exception in CEspProtocolThread::run while processing request.");
  155. }
  156. if(!keepAlive)
  157. {
  158. try
  159. {
  160. m_socket->shutdown();
  161. m_socket->close();
  162. }
  163. catch (IException *e)
  164. {
  165. StringBuffer estr;
  166. DBGLOG("Exception(%d, %s) - in CEspProtocolThread::run while closing socket.", e->errorCode(), e->errorMessage(estr).str());
  167. e->Release();
  168. }
  169. catch(...)
  170. {
  171. DBGLOG("General Exception - in CEspProtocolThread::run while closing socket.");
  172. }
  173. }
  174. Release();
  175. return 0;
  176. }