943,515 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Marked Solved
  • Views: 2693
  • C++ RSS
Nov 17th, 2008
0

GCC Exception handling w/ threads

Expand Post »
Hi. I have written a small test socket program that uses a background thread that accepts tcp connections and adds them to a connection list that is accessed by main().

When a connection is opened, then later closed, recv() is called (see line highlighted in code below), which throws an exception stating that the socket is closed.

When I compile in Dev-C++ the exception thrown in the main() thread is caught in the background thread. -- Why is this??

When I compile in Visual Studio 6 the exception is caught in the main() thread as I expected.

I upgraded the Dev-c++ compiler from mingw 3.4.2 to 3.4.5, but the problem still exists.

Does anyone know why this is happening, and if there are any workarounds?

Thanks.

The file is shown following:
Note: the TcpServerSocket.accept() method returns a new open TcpClientObject. All member functions simply call a socket function using the handle stored in the object. Exceptions thrown are derived from std::exception, with what() implemented.
The 2 socket classes are in separate files included in the project during compilation.
cpp Syntax (Toggle Plain Text)
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <string>
  4. #include <list>
  5. #include <conio.h>
  6. #include <stdio.h>
  7.  
  8. #include "../WindowsPorts/TcpClientSocket.h"
  9. #include "../WindowsPorts/TcpServerSocket.h"
  10.  
  11. using namespace std;
  12.  
  13. list<TcpClientSocket*> skts;
  14. bool abortProgram = false;
  15.  
  16. DWORD __stdcall acceptThread(void *_port){
  17. int port = *(int*)_port;
  18. try{
  19. cout << "Listening on " << port << endl;
  20. TcpServerSocket listenSocket(port);
  21.  
  22. while(1){
  23. TcpClientSocket *acc = NULL;
  24.  
  25. try{
  26. acc = listenSocket.accept();
  27. }
  28. catch(exception &x){
  29. cout << "acceptThread" << " (inner loop) Caught Exception: " << x.what() << endl;
  30. }
  31.  
  32. if(acc){
  33. cout << "Accepted connection from " << acc->getHost() << ":" << acc->getPort() << endl;
  34. skts.push_back(acc);
  35. }
  36.  
  37. Sleep(1); // useless
  38. }
  39. }
  40. catch(exception &x){
  41. cout << "acceptThread" << " Caught Exception: " << x.what() << endl;
  42. cout << "Listening Port Closed. Quitting Thread." << endl;
  43. cin.get();
  44. abortProgram = true;
  45. Sleep(10000);
  46. }
  47.  
  48. return 0;
  49. }
  50.  
  51. int main(int argc, char *argv[]){
  52. DWORD port = 12350;
  53. if(argc == 2){
  54. port = atoi(argv[1]);
  55. }
  56.  
  57. try{
  58.  
  59. CreateThread(0, 0, acceptThread, &port, 0, 0);
  60.  
  61. TcpServerSocket listen(12300);
  62.  
  63. list<TcpClientSocket*>::iterator socketInUse = skts.begin();
  64.  
  65. while(!abortProgram){
  66. Sleep(1);
  67. char ch = 0;
  68.  
  69. if(kbhit()){
  70. ch = getch();
  71. if(ch == 27){
  72. if(++socketInUse == skts.end()){
  73. socketInUse = skts.begin();
  74. }
  75.  
  76. if(skts.size() > 0 && socketInUse != skts.end()){
  77. cout << "Data will be directed to " << (*socketInUse)->getHost() << " \r";
  78. }
  79.  
  80. ch = 0;
  81. }
  82. else{
  83. try{
  84. if(skts.size() > 0 && socketInUse != skts.end()){
  85. (*socketInUse)->send(&ch, 1);
  86. }
  87. }
  88. catch(exception &x){
  89. cout << "main" << " Caught Exception: " << x.what() << endl;
  90. }
  91. }
  92. }
  93.  
  94. for(list<TcpClientSocket*>::iterator it = skts.begin(); it != skts.end(); it++){
  95. try{
  96. if((*it)->waitForData(10) == 1){ // got data, display it
  97. char buff[1500];
  98. // ########### the following line will throw the exception when the connection is closed (remotely)
  99. unsigned int len = (*it)->recv(buff, sizeof(buff));
  100.  
  101. // cout << "read " << len << " bytes " << (len == 0) << endl;
  102. if(len > 0)
  103. cout << (*it)->getHost() << ": " << string(buff, len) << endl;
  104. }
  105. }
  106. catch(exception &x){
  107. cout << "main" << " Caught Exception: " << x.what() << endl;
  108. cout << "Closing port" << endl;
  109.  
  110. bool reset = false;
  111. if(socketInUse == it){
  112. reset = true;
  113. }
  114.  
  115. delete *it; // destroy object
  116. skts.erase(it); // destroy reference
  117.  
  118. if(reset)
  119. socketInUse = skts.end();
  120.  
  121. break;
  122. }
  123. catch(...){
  124. cout << "main" << " Unhandled Exception" << endl;
  125. cout << "Closing port" << endl;
  126.  
  127. bool reset = false;
  128. if(socketInUse == it){
  129. reset = true;
  130. }
  131.  
  132. delete *it; // destroy object
  133. skts.erase(it); // destroy reference
  134.  
  135. if(reset)
  136. socketInUse = skts.end();
  137.  
  138. break;
  139. }
  140. }
  141. }
  142. }
  143. catch(exception &x){
  144. cout << "main" << " Caught Exception: " << x.what() << endl;
  145. }
  146. catch(...){
  147. cout << "main" << " Unhandled Exception" << endl;
  148. }
  149.  
  150. system("PAUSE");
  151. return EXIT_SUCCESS;
  152. }
Reputation Points: 85
Solved Threads: 45
Posting Whiz in Training
dougy83 is offline Offline
275 posts
since Jun 2007
Nov 18th, 2008
0

Re: GCC Exception handling w/ threads

OK, I found out the compilation option -mthreads (MinGW specific) is needed to allow safe threaded code with exceptions. It may also be the case that -pthreads is required for non-MinGW gcc.
Last edited by dougy83; Nov 18th, 2008 at 12:42 am.
Reputation Points: 85
Solved Threads: 45
Posting Whiz in Training
dougy83 is offline Offline
275 posts
since Jun 2007

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: C++ I/O Files
Next Thread in C++ Forum Timeline: Need help not allowing a negative number to be input





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC