Merge lp:~fpstovall/nrtb/unique_ptr_fix into lp:nrtb
- unique_ptr_fix
- Merge into alpha
Proposed by
Rick Stovall
Status: | Merged |
---|---|
Approved by: | Rick Stovall |
Approved revision: | 21 |
Merge reported by: | Rick Stovall |
Merged at revision: | not available |
Proposed branch: | lp:~fpstovall/nrtb/unique_ptr_fix |
Merge into: | lp:nrtb |
Diff against target: |
1067 lines (+405/-334) 7 files modified
common/sockets/Makefile (+3/-3) common/sockets/base_socket.cpp (+97/-112) common/sockets/base_socket.h (+2/-2) common/sockets/socket_test.cpp (+98/-80) common/transceiver/Makefile (+2/-2) common/transceiver/transceiver.h (+44/-36) common/transceiver/transceiver_test.cpp (+159/-99) |
To merge this branch: | bzr merge lp:~fpstovall/nrtb/unique_ptr_fix |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rick Stovall | Approve | ||
Review via email: mp+100340@code.launchpad.net |
Commit message
First C++11 update; using std::unique_ptr for socket handling.
Description of the change
First of the changes to bring the code up to C+11 spec, particularly focused on replacing boost::shared_ptr with std::unique_ptr where appropriate.
This merge includes significant updates to the sockets and transceiver libs, improving stability, reporting and enforcing the logical constraint that a socket can have only one owner and that code which accepts a connection from the tcp_server socket factory must take actual ownership of the new socket. Fixes were also added which allowed the removal of arbitrary time delays in the associated unit test programs.
This will be the first of several merges assuming the move to C++11 is approved.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'common/sockets/Makefile' | |||
2 | --- common/sockets/Makefile 2011-09-17 01:21:36 +0000 | |||
3 | +++ common/sockets/Makefile 2012-04-01 15:57:19 +0000 | |||
4 | @@ -24,13 +24,13 @@ | |||
5 | 24 | 24 | ||
6 | 25 | socket_test: base_socket.o socket_test.cpp | 25 | socket_test: base_socket.o socket_test.cpp |
7 | 26 | @rm -f socket_test | 26 | @rm -f socket_test |
10 | 27 | g++ -c -O3 socket_test.cpp -I ../include | 27 | g++ -c -O3 socket_test.cpp -I ../include -std=gnu++0x |
11 | 28 | g++ -o socket_test socket_test.o base_socket.o ../obj/hires_timer.o ../obj/common.o ../obj/base_thread.o -lpthread | 28 | g++ -o socket_test socket_test.o base_socket.o ../obj/hires_timer.o ../obj/common.o ../obj/base_thread.o -lpthread -std=gnu++0x |
12 | 29 | 29 | ||
13 | 30 | 30 | ||
14 | 31 | base_socket.o: base_socket.cpp base_socket.h Makefile | 31 | base_socket.o: base_socket.cpp base_socket.h Makefile |
15 | 32 | @rm -f base_socket.o | 32 | @rm -f base_socket.o |
17 | 33 | g++ -c -O3 base_socket.cpp -I ../include | 33 | g++ -c -O3 base_socket.cpp -I ../include -std=gnu++0x |
18 | 34 | 34 | ||
19 | 35 | clean: | 35 | clean: |
20 | 36 | @rm -vf *.o ../include/base_socket.h socket_test | 36 | @rm -vf *.o ../include/base_socket.h socket_test |
21 | 37 | 37 | ||
22 | === modified file 'common/sockets/base_socket.cpp' | |||
23 | --- common/sockets/base_socket.cpp 2011-09-17 01:21:36 +0000 | |||
24 | +++ common/sockets/base_socket.cpp 2012-04-01 15:57:19 +0000 | |||
25 | @@ -605,32 +605,21 @@ | |||
26 | 605 | // take action only if the listen thread is running. | 605 | // take action only if the listen thread is running. |
27 | 606 | if (listening()) | 606 | if (listening()) |
28 | 607 | { | 607 | { |
38 | 608 | // stop the listener thread | 608 | // stop the listener thread |
39 | 609 | if (is_running()) stop(); | 609 | stop(); |
40 | 610 | // wait here until the thread stops. | 610 | join(); |
32 | 611 | if (is_running()) join(); | ||
33 | 612 | // try | ||
34 | 613 | // { | ||
35 | 614 | // if (listen_sock) close(listen_sock); | ||
36 | 615 | // } | ||
37 | 616 | // catch (...) {}; | ||
41 | 617 | }; | 611 | }; |
42 | 618 | }; | 612 | }; |
43 | 619 | 613 | ||
44 | 620 | bool tcp_server_socket_factory::listening() | 614 | bool tcp_server_socket_factory::listening() |
45 | 621 | { | 615 | { |
58 | 622 | bool running = is_running(); | 616 | bool running = is_running(); |
59 | 623 | /* if (!running) | 617 | return running; |
60 | 624 | { | 618 | }; |
61 | 625 | // check to be sure the thread did not die due to an error. | 619 | |
62 | 626 | if (_last_thread_fault != 0) | 620 | int tcp_server_socket_factory::last_fault() |
63 | 627 | { | 621 | { |
64 | 628 | // if thread_return was non-zero, it is assumed the thread died an | 622 | return _last_thread_fault; |
53 | 629 | // evil and useless death. Scream in anger! | ||
54 | 630 | throw listen_terminated_exception(); | ||
55 | 631 | }; | ||
56 | 632 | }; | ||
57 | 633 | */ return running; | ||
65 | 634 | }; | 623 | }; |
66 | 635 | 624 | ||
67 | 636 | unsigned short int tcp_server_socket_factory::backlog() | 625 | unsigned short int tcp_server_socket_factory::backlog() |
68 | @@ -643,108 +632,104 @@ | |||
69 | 643 | { | 632 | { |
70 | 644 | std::cerr << "in thread cleanup sock closer" << std::endl; | 633 | std::cerr << "in thread cleanup sock closer" << std::endl; |
71 | 645 | int & socket = *(static_cast<int*>(sock)); | 634 | int & socket = *(static_cast<int*>(sock)); |
73 | 646 | ::close(socket); | 635 | try { ::close(socket); } catch (...) {}; |
74 | 647 | std::cerr << "socker closer done." << std::endl; | 636 | std::cerr << "socker closer done." << std::endl; |
75 | 648 | }; | 637 | }; |
76 | 649 | 638 | ||
77 | 650 | void tcp_server_socket_factory::run() | 639 | void tcp_server_socket_factory::run() |
78 | 651 | { | 640 | { |
85 | 652 | /* Put this entire thing in a try block to protect the application. | 641 | // set up the listening socket. |
80 | 653 | * Without this, an untrapped exception thrown here or in the | ||
81 | 654 | * user supplied on_accept() method would abort the entire | ||
82 | 655 | * application instead of just this | ||
83 | 656 | * thread. | ||
84 | 657 | */ | ||
86 | 658 | int listen_sock; | 642 | int listen_sock; |
89 | 659 | // make sure the listener is closed when we exit. | 643 | _last_thread_fault = 0; |
90 | 660 | pthread_cleanup_push(closeme, (void*) &listen_sock); | 644 | bool go = false; |
91 | 661 | try | 645 | try |
92 | 662 | { | 646 | { |
169 | 663 | bool go = true; | 647 | listen_sock = socket(AF_INET,SOCK_STREAM,0); |
170 | 664 | // set up our listening socket. | 648 | sockaddr_in myaddr; |
171 | 665 | listen_sock = socket(AF_INET,SOCK_STREAM,0); | 649 | myaddr = tcp_socket::str_to_sockaddr(_address); |
172 | 666 | sockaddr_in myaddr; | 650 | int a = bind(listen_sock,(sockaddr *) &myaddr,sizeof(myaddr)); |
173 | 667 | try | 651 | int b = listen(listen_sock,_backlog); |
174 | 668 | { | 652 | if (a || b) |
175 | 669 | myaddr = tcp_socket::str_to_sockaddr(_address); | 653 | { |
176 | 670 | } | 654 | go = false; |
177 | 671 | catch (...) | 655 | if (a) _last_thread_fault += 1; |
178 | 672 | { | 656 | if (b) _last_thread_fault += 2; |
179 | 673 | // probably a tcp_socket::bad_address_exception, | 657 | } |
180 | 674 | // but any reason will do. | 658 | else go = true; |
105 | 675 | go = false; | ||
106 | 676 | }; | ||
107 | 677 | if (bind(listen_sock,(sockaddr *) &myaddr,sizeof(myaddr))) | ||
108 | 678 | { | ||
109 | 679 | // bind did not work. | ||
110 | 680 | go = false; | ||
111 | 681 | }; | ||
112 | 682 | if (listen(listen_sock,_backlog)) | ||
113 | 683 | { | ||
114 | 684 | // listen failed in some way.. I don't care which. | ||
115 | 685 | go = false; | ||
116 | 686 | }; | ||
117 | 687 | // processing loop | ||
118 | 688 | while (go) | ||
119 | 689 | { | ||
120 | 690 | // accept a new connection | ||
121 | 691 | bool good_connect = true; | ||
122 | 692 | int new_conn = accept(listen_sock,NULL,NULL); | ||
123 | 693 | // validate the accept return value. | ||
124 | 694 | if (new_conn == -1) | ||
125 | 695 | { | ||
126 | 696 | // accept returned an error. | ||
127 | 697 | switch (errno) | ||
128 | 698 | { | ||
129 | 699 | // case ENETDOWN : | ||
130 | 700 | case EPROTO : | ||
131 | 701 | // case ENOPROTOOPT : | ||
132 | 702 | case EHOSTDOWN : | ||
133 | 703 | // case ENONET : | ||
134 | 704 | case EHOSTUNREACH : | ||
135 | 705 | // case EOPNOTSUPP : | ||
136 | 706 | // case ENETUNREACH : | ||
137 | 707 | case EAGAIN : | ||
138 | 708 | // case EPERM : | ||
139 | 709 | case ECONNABORTED : | ||
140 | 710 | { | ||
141 | 711 | good_connect = false; | ||
142 | 712 | break; | ||
143 | 713 | }; | ||
144 | 714 | default : | ||
145 | 715 | { | ||
146 | 716 | // for any other error, we're going to shutdown the | ||
147 | 717 | // this listener thread. | ||
148 | 718 | go = false; | ||
149 | 719 | good_connect = false; | ||
150 | 720 | _last_thread_fault = errno; | ||
151 | 721 | break; | ||
152 | 722 | }; | ||
153 | 723 | }; // switch (errno) | ||
154 | 724 | }; // error thrown by accept. | ||
155 | 725 | if (good_connect) | ||
156 | 726 | { | ||
157 | 727 | // create connect_sock | ||
158 | 728 | connect_sock.reset(new tcp_socket(new_conn)); | ||
159 | 729 | // make the thread easily cancelable. | ||
160 | 730 | set_cancel_anytime(); | ||
161 | 731 | // call on_accept | ||
162 | 732 | go = on_accept(); | ||
163 | 733 | // set back to cancel_deferred. | ||
164 | 734 | set_deferred_cancel(); | ||
165 | 735 | // release our claim to the new socket | ||
166 | 736 | connect_sock.reset(); | ||
167 | 737 | }; | ||
168 | 738 | }; // while go; | ||
181 | 739 | } | 659 | } |
182 | 740 | catch (...) | 660 | catch (...) |
183 | 741 | { | 661 | { |
190 | 742 | /* an untrapped exception was thrown by someone in this thread. | 662 | _last_thread_fault = 100; |
191 | 743 | * We'll shutdown this thread and put -1 in the thread_return field | 663 | }; |
192 | 744 | * to let the world know that we don't know what killed us. | 664 | // if not in a good state, terminate the thread. |
193 | 745 | */ | 665 | if (!go) |
194 | 746 | _last_thread_fault = -1; | 666 | { |
195 | 747 | }; | 667 | _last_thread_fault =+ 200; |
196 | 668 | exit(0); | ||
197 | 669 | }; | ||
198 | 670 | // make sure the listener is closed when we exit. | ||
199 | 671 | pthread_cleanup_push(closeme, (void*) &listen_sock); | ||
200 | 672 | // processing loop | ||
201 | 673 | while (go) | ||
202 | 674 | { | ||
203 | 675 | // accept a new connection | ||
204 | 676 | bool good_connect = true; | ||
205 | 677 | int new_conn = accept(listen_sock,NULL,NULL); | ||
206 | 678 | // validate the accept return value. | ||
207 | 679 | if (new_conn == -1) | ||
208 | 680 | { | ||
209 | 681 | // accept returned an error. | ||
210 | 682 | switch (errno) | ||
211 | 683 | { | ||
212 | 684 | case EPROTO : | ||
213 | 685 | case EHOSTDOWN : | ||
214 | 686 | case EHOSTUNREACH : | ||
215 | 687 | case EAGAIN : | ||
216 | 688 | case ECONNABORTED : | ||
217 | 689 | { | ||
218 | 690 | // abandon this connection | ||
219 | 691 | good_connect = false; | ||
220 | 692 | break; | ||
221 | 693 | }; | ||
222 | 694 | default : | ||
223 | 695 | { | ||
224 | 696 | // for any other error, we're going to shutdown the | ||
225 | 697 | // this listener thread. | ||
226 | 698 | go = false; | ||
227 | 699 | good_connect = false; | ||
228 | 700 | _last_thread_fault = errno; | ||
229 | 701 | break; | ||
230 | 702 | }; | ||
231 | 703 | }; // switch (errno) | ||
232 | 704 | }; // error thrown by accept. | ||
233 | 705 | if (good_connect) | ||
234 | 706 | { | ||
235 | 707 | connect_sock.reset(new tcp_socket(new_conn)); | ||
236 | 708 | set_cancel_anytime(); | ||
237 | 709 | // call the connection handler. | ||
238 | 710 | try | ||
239 | 711 | { | ||
240 | 712 | go = on_accept(); | ||
241 | 713 | } | ||
242 | 714 | catch (...) | ||
243 | 715 | { | ||
244 | 716 | go = false; | ||
245 | 717 | _last_thread_fault = 501; | ||
246 | 718 | }; | ||
247 | 719 | set_deferred_cancel(); | ||
248 | 720 | // safety check. | ||
249 | 721 | if (connect_sock) | ||
250 | 722 | { | ||
251 | 723 | std::cerr << "WARNING: on_accept() did not take ownership of " | ||
252 | 724 | << "connect_sock.\n" | ||
253 | 725 | << " This can lead to leaks and should be fixed." | ||
254 | 726 | << std::endl; | ||
255 | 727 | connect_sock.reset(); | ||
256 | 728 | _last_thread_fault = 500; | ||
257 | 729 | go = false; | ||
258 | 730 | }; | ||
259 | 731 | }; | ||
260 | 732 | }; // while go; | ||
261 | 748 | pthread_cleanup_pop(0); | 733 | pthread_cleanup_pop(0); |
262 | 749 | }; | 734 | }; |
263 | 750 | 735 | ||
264 | 751 | 736 | ||
265 | === modified file 'common/sockets/base_socket.h' | |||
266 | --- common/sockets/base_socket.h 2011-09-17 00:33:23 +0000 | |||
267 | +++ common/sockets/base_socket.h 2012-04-01 15:57:19 +0000 | |||
268 | @@ -20,7 +20,7 @@ | |||
269 | 20 | #define base_socket_header | 20 | #define base_socket_header |
270 | 21 | 21 | ||
271 | 22 | #include <base_thread.h> | 22 | #include <base_thread.h> |
273 | 23 | #include <boost/shared_ptr.hpp> | 23 | #include <memory> |
274 | 24 | #include <sys/socket.h> | 24 | #include <sys/socket.h> |
275 | 25 | #include <netinet/in.h> | 25 | #include <netinet/in.h> |
276 | 26 | 26 | ||
277 | @@ -373,7 +373,7 @@ | |||
278 | 373 | }; | 373 | }; |
279 | 374 | 374 | ||
280 | 375 | /// smart pointer for use with tcp_sockets | 375 | /// smart pointer for use with tcp_sockets |
282 | 376 | typedef boost::shared_ptr<nrtb::tcp_socket> tcp_socket_p; | 376 | typedef std::unique_ptr<nrtb::tcp_socket> tcp_socket_p; |
283 | 377 | 377 | ||
284 | 378 | /** Abstract "listener" TCP/IP socket for servers. | 378 | /** Abstract "listener" TCP/IP socket for servers. |
285 | 379 | ** | 379 | ** |
286 | 380 | 380 | ||
287 | === modified file 'common/sockets/socket_test.cpp' | |||
288 | --- common/sockets/socket_test.cpp 2011-09-17 01:21:36 +0000 | |||
289 | +++ common/sockets/socket_test.cpp 2012-04-01 15:57:19 +0000 | |||
290 | @@ -21,7 +21,6 @@ | |||
291 | 21 | #include <string> | 21 | #include <string> |
292 | 22 | #include <boost/random.hpp> | 22 | #include <boost/random.hpp> |
293 | 23 | #include "base_socket.h" | 23 | #include "base_socket.h" |
294 | 24 | #include <boost/shared_ptr.hpp> | ||
295 | 25 | 24 | ||
296 | 26 | using namespace nrtb; | 25 | using namespace nrtb; |
297 | 27 | using namespace std; | 26 | using namespace std; |
298 | @@ -29,46 +28,48 @@ | |||
299 | 29 | class myserver: public tcp_server_socket_factory | 28 | class myserver: public tcp_server_socket_factory |
300 | 30 | { | 29 | { |
301 | 31 | public: | 30 | public: |
304 | 32 | int hits; | 31 | int hits; |
305 | 33 | int errors; | 32 | int errors; |
306 | 34 | 33 | ||
316 | 35 | // constructor | 34 | // constructor |
317 | 36 | myserver(const string & a, const unsigned short int & b) | 35 | myserver(const string & a, const unsigned short int & b) |
318 | 37 | : tcp_server_socket_factory(a,b) | 36 | : tcp_server_socket_factory(a,b) |
319 | 38 | { | 37 | { |
320 | 39 | // Don't need to lock here because we know the | 38 | // Don't need to lock here because we know the |
321 | 40 | // listener thread is not running. | 39 | // listener thread is not running. |
322 | 41 | hits = 0; | 40 | hits = 0; |
323 | 42 | errors = 0; | 41 | errors = 0; |
324 | 43 | }; | 42 | }; |
325 | 44 | 43 | ||
326 | 45 | protected: | 44 | protected: |
353 | 46 | // on_accept() is called on each connection. | 45 | |
354 | 47 | bool on_accept() | 46 | // on_accept() is called on each connection. |
355 | 48 | { | 47 | bool on_accept() |
356 | 49 | try | 48 | { |
357 | 50 | { | 49 | try |
358 | 51 | // just return what we've recieved. | 50 | { |
359 | 52 | string msg = connect_sock->getln(); | 51 | tcp_socket_p sock = std::move(connect_sock); |
360 | 53 | connect_sock->put(msg); | 52 | // just return what we've recieved. |
361 | 54 | // Update our hit count. | 53 | string msg = sock->getln(); |
362 | 55 | hits++; | 54 | sock->put(msg); |
363 | 56 | } | 55 | // Update our hit count. |
364 | 57 | catch (base_exception & e) | 56 | hits++; |
365 | 58 | { | 57 | } |
366 | 59 | errors++; | 58 | catch (base_exception & e) |
367 | 60 | cerr << "server Caught " << e.what() << endl; | 59 | { |
368 | 61 | } | 60 | errors++; |
369 | 62 | catch (...) | 61 | cerr << "server Caught " << e.what() << endl; |
370 | 63 | { | 62 | } |
371 | 64 | errors++; | 63 | catch (...) |
372 | 65 | cerr << "Unexpected error in on_accept()" << endl; | 64 | { |
373 | 66 | }; | 65 | errors++; |
374 | 67 | if (hits > 99) | 66 | cerr << "Unexpected error in on_accept()" << endl; |
375 | 68 | return false; | 67 | }; |
376 | 69 | else | 68 | if (hits > 99) |
377 | 70 | return true; | 69 | return false; |
378 | 71 | }; | 70 | else |
379 | 71 | return true; | ||
380 | 72 | }; | ||
381 | 72 | }; | 73 | }; |
382 | 73 | 74 | ||
383 | 74 | string transceiver(const string address, const string sendme) | 75 | string transceiver(const string address, const string sendme) |
384 | @@ -78,7 +79,7 @@ | |||
385 | 78 | sender.connect(address); | 79 | sender.connect(address); |
386 | 79 | sender.put(sendme); | 80 | sender.put(sendme); |
387 | 80 | returnme = sender.getln(); | 81 | returnme = sender.getln(); |
389 | 81 | sender.close();//cerr << "tc>> sock closed" << endl; | 82 | sender.close(); |
390 | 82 | return returnme; | 83 | return returnme; |
391 | 83 | }; | 84 | }; |
392 | 84 | 85 | ||
393 | @@ -101,86 +102,103 @@ | |||
394 | 101 | 102 | ||
395 | 102 | try | 103 | try |
396 | 103 | { | 104 | { |
416 | 104 | // start the receiver/server | 105 | // start the receiver/server |
417 | 105 | test_server.start_listen(); | 106 | test_server.start_listen(); |
418 | 106 | usleep(5e5); | 107 | int countdown = 99; |
419 | 107 | 108 | while ((!test_server.listening()) and countdown) | |
420 | 108 | // Send test messages | 109 | { |
421 | 109 | for (int i = 0; i < 100; i++) | 110 | usleep(1e3); |
422 | 110 | { | 111 | countdown++; |
423 | 111 | stringstream msg; | 112 | }; |
424 | 112 | msg << "test message " << i << "\r"; | 113 | if (!countdown) |
425 | 113 | string checkme = msg.str(); | 114 | { |
426 | 114 | string returned = transceiver(address, checkme); | 115 | cerr << "Could not start listener." << endl; |
427 | 115 | if (returned != checkme) | 116 | exit(1); |
428 | 116 | { | 117 | } |
429 | 117 | er_count++; | 118 | cout << "test_server ready." << endl; |
430 | 118 | }; | 119 | |
431 | 119 | cout << returned.substr(0,returned.size()-1) << ": " | 120 | // Send test messages |
432 | 120 | << ((returned == checkme) ? "Passed" : "Failed") | 121 | for (int i = 0; i < 100; i++) |
433 | 121 | << endl; | 122 | { |
434 | 122 | }; | 123 | stringstream msg; |
435 | 124 | msg << "test message " << i << "\r"; | ||
436 | 125 | string checkme = msg.str(); | ||
437 | 126 | string returned = transceiver(address, checkme); | ||
438 | 127 | if (returned != checkme) | ||
439 | 128 | { | ||
440 | 129 | er_count++; | ||
441 | 130 | }; | ||
442 | 131 | cout << returned.substr(0,returned.size()-1) << ": " | ||
443 | 132 | << ((returned == checkme) ? "Passed" : "Failed") | ||
444 | 133 | << endl; | ||
445 | 134 | }; | ||
446 | 123 | } | 135 | } |
447 | 124 | catch (myserver::bind_failure_exception) | 136 | catch (myserver::bind_failure_exception) |
448 | 125 | { | 137 | { |
450 | 126 | cout << "Could not bind port" << endl; | 138 | cout << "Could not bind port" << endl; |
451 | 127 | } | 139 | } |
452 | 128 | catch (myserver::mem_exhasted_exception) | 140 | catch (myserver::mem_exhasted_exception) |
453 | 129 | { | 141 | { |
455 | 130 | cout << "myserver reports out of memory." << endl; | 142 | cout << "myserver reports out of memory." << endl; |
456 | 131 | } | 143 | } |
457 | 132 | catch (myserver::listen_terminated_exception) | 144 | catch (myserver::listen_terminated_exception) |
458 | 133 | { | 145 | { |
460 | 134 | cout << "Listener terminated unexpectedly." << endl; | 146 | cout << "Listener terminated unexpectedly." << endl; |
461 | 135 | } | 147 | } |
462 | 136 | catch (myserver::on_accept_bound_exception) | 148 | catch (myserver::on_accept_bound_exception) |
463 | 137 | { | 149 | { |
465 | 138 | cout << "myserver::on_accept() seems bound." << endl; | 150 | cout << "myserver::on_accept() seems bound." << endl; |
466 | 139 | } | 151 | } |
467 | 140 | catch (tcp_socket::bad_connect_exception & e) | 152 | catch (tcp_socket::bad_connect_exception & e) |
468 | 141 | { | 153 | { |
471 | 142 | cout << "A bad_connect_exception was thrown.\n" | 154 | cout << "A bad_connect_exception was thrown.\n" |
472 | 143 | << e.comment() << endl; | 155 | << " comment: " << e.comment() << endl; |
473 | 156 | cout << " test_server.last_fault() = " | ||
474 | 157 | << test_server.last_fault() << endl; | ||
475 | 144 | } | 158 | } |
476 | 145 | catch (tcp_socket::not_open_exception & e) | 159 | catch (tcp_socket::not_open_exception & e) |
477 | 146 | { | 160 | { |
480 | 147 | cout << "A tcp not open exception was caught.\n" | 161 | cout << "A tcp not open exception was caught.\n" |
481 | 148 | << e.comment() << endl; | 162 | << e.comment() << endl; |
482 | 149 | } | 163 | } |
483 | 150 | catch (tcp_socket::close_exception & e) | 164 | catch (tcp_socket::close_exception & e) |
484 | 151 | { | 165 | { |
487 | 152 | cout << "A close_exception was caught.\n" | 166 | cout << "A close_exception was caught.\n" |
488 | 153 | << e.comment() << endl; | 167 | << e.comment() << endl; |
489 | 154 | } | 168 | } |
490 | 155 | catch (tcp_socket::overrun_exception & e) | 169 | catch (tcp_socket::overrun_exception & e) |
491 | 156 | { | 170 | { |
494 | 157 | cout << "An overrun_exception was caught.\n" | 171 | cout << "An overrun_exception was caught.\n" |
495 | 158 | << e.comment() << endl; | 172 | << e.comment() << endl; |
496 | 159 | } | 173 | } |
497 | 160 | catch (tcp_socket::buffer_full_exception & e) | 174 | catch (tcp_socket::buffer_full_exception & e) |
498 | 161 | { | 175 | { |
501 | 162 | cout << "A buffer_full_exception was caught.\n" | 176 | cout << "A buffer_full_exception was caught.\n" |
502 | 163 | << e.comment() << endl; | 177 | << e.comment() << endl; |
503 | 164 | } | 178 | } |
504 | 165 | catch (tcp_socket::general_exception & e) | 179 | catch (tcp_socket::general_exception & e) |
505 | 166 | { | 180 | { |
508 | 167 | cout << "A tcp_socket exception was caught.\n" | 181 | cout << "A tcp_socket exception was caught.\n" |
509 | 168 | << e.comment() << endl; | 182 | << " comment: " << e.comment() << endl; |
510 | 183 | cout << " test_server.last_fault() = " | ||
511 | 184 | << test_server.last_fault() << endl; | ||
512 | 169 | } | 185 | } |
513 | 170 | catch (exception & e) | 186 | catch (exception & e) |
514 | 171 | { | 187 | { |
516 | 172 | cout << "A unexpected " << e.what() << " exception was caught." << endl; | 188 | cout << "A unexpected " << e.what() |
517 | 189 | << " exception was caught." << endl; | ||
518 | 173 | }; | 190 | }; |
519 | 174 | 191 | ||
520 | 175 | // final check. | 192 | // final check. |
521 | 176 | if (test_server.hits != 100) | 193 | if (test_server.hits != 100) |
522 | 177 | { | 194 | { |
527 | 178 | er_count++; | 195 | er_count++; |
528 | 179 | cout << "Server does not report the proper number of hits.\n" | 196 | cout << "Server does not report the proper number of hits.\n" |
529 | 180 | << "\tExpected 100, got " << test_server.hits | 197 | << "\tExpected 100, got " << test_server.hits |
530 | 181 | << endl; | 198 | << endl; |
531 | 182 | }; | 199 | }; |
533 | 183 | cout << "=========== tcp_socket test complete =============" << endl; | 200 | cout << "=========== tcp_socket test complete =============" |
534 | 201 | << endl; | ||
535 | 184 | 202 | ||
536 | 185 | return er_count; | 203 | return er_count; |
537 | 186 | }; | 204 | }; |
538 | 187 | 205 | ||
539 | === modified file 'common/transceiver/Makefile' | |||
540 | --- common/transceiver/Makefile 2011-08-25 04:22:52 +0000 | |||
541 | +++ common/transceiver/Makefile 2012-04-01 15:57:19 +0000 | |||
542 | @@ -23,8 +23,8 @@ | |||
543 | 23 | 23 | ||
544 | 24 | transceiver_test: transceiver.h transceiver_test.cpp | 24 | transceiver_test: transceiver.h transceiver_test.cpp |
545 | 25 | @rm -f transceiver_test | 25 | @rm -f transceiver_test |
548 | 26 | g++ -c transceiver_test.cpp -I../include | 26 | g++ -c transceiver_test.cpp -I../include -std=gnu++0x |
549 | 27 | g++ -o transceiver_test transceiver_test.o ../obj/common.o ../obj/log_setup.o ../obj/serializer.o ../obj/base_thread.o ../obj/base_socket.o ../obj/confreader.o -lpthread -lprotobuf ../lib/nrtb_gpb.a -lPocoFoundation | 27 | g++ -o transceiver_test transceiver_test.o ../obj/common.o ../obj/log_setup.o ../obj/serializer.o ../obj/base_thread.o ../obj/base_socket.o ../obj/confreader.o -lpthread -lprotobuf ../lib/nrtb_gpb.a -lPocoFoundation -std=gnu++0x |
550 | 28 | 28 | ||
551 | 29 | clean: | 29 | clean: |
552 | 30 | @rm -rvf *.o transceiver_test ../include/transceiver.h *.log ../obj/transceiver.o | 30 | @rm -rvf *.o transceiver_test ../include/transceiver.h *.log ../obj/transceiver.o |
553 | 31 | 31 | ||
554 | === modified file 'common/transceiver/transceiver.h' | |||
555 | --- common/transceiver/transceiver.h 2011-09-15 22:53:06 +0000 | |||
556 | +++ common/transceiver/transceiver.h 2012-04-01 15:57:19 +0000 | |||
557 | @@ -26,7 +26,6 @@ | |||
558 | 26 | #include <serializer.h> | 26 | #include <serializer.h> |
559 | 27 | #include <confreader.h> | 27 | #include <confreader.h> |
560 | 28 | #include <Poco/Logger.h> | 28 | #include <Poco/Logger.h> |
561 | 29 | #include <boost/shared_ptr.hpp> | ||
562 | 30 | #include <boost/circular_buffer.hpp> | 29 | #include <boost/circular_buffer.hpp> |
563 | 31 | 30 | ||
564 | 32 | namespace nrtb | 31 | namespace nrtb |
565 | @@ -51,8 +50,8 @@ | |||
566 | 51 | * specification this class implements. | 50 | * specification this class implements. |
567 | 52 | * ***************************************************************/ | 51 | * ***************************************************************/ |
568 | 53 | template <class out, class in, | 52 | template <class out, class in, |
571 | 54 | class outp = boost::shared_ptr<out>, | 53 | class outp = std::unique_ptr<out>, |
572 | 55 | class inp = boost::shared_ptr<in> > | 54 | class inp = std::unique_ptr<in> > |
573 | 56 | class transceiver | 55 | class transceiver |
574 | 57 | { | 56 | { |
575 | 58 | public: | 57 | public: |
576 | @@ -70,12 +69,17 @@ | |||
577 | 70 | * socket. Once created this class assumes it uniquely owns the | 69 | * socket. Once created this class assumes it uniquely owns the |
578 | 71 | * socket and will close it upon distruction. | 70 | * socket and will close it upon distruction. |
579 | 72 | * ***********************************************************/ | 71 | * ***********************************************************/ |
581 | 73 | transceiver(tcp_socket_p socket); | 72 | transceiver(tcp_socket_p & socket); |
582 | 74 | /************************************************************* | 73 | /************************************************************* |
583 | 75 | * Closes the socket and releases all mmemory associated with | 74 | * Closes the socket and releases all mmemory associated with |
584 | 76 | * this class. | 75 | * this class. |
585 | 77 | * ***********************************************************/ | 76 | * ***********************************************************/ |
586 | 78 | virtual ~transceiver(); | 77 | virtual ~transceiver(); |
587 | 78 | /************************************************************* | ||
588 | 79 | * is_connected() returns true if the socket is up and ready | ||
589 | 80 | * to use, false otherwise. | ||
590 | 81 | *************************************************************/ | ||
591 | 82 | bool is_connected(); | ||
592 | 79 | /************************************************************** | 83 | /************************************************************** |
593 | 80 | * gets the next message from the socket. If no messages are | 84 | * gets the next message from the socket. If no messages are |
594 | 81 | * ready, blocks util one arrives. | 85 | * ready, blocks util one arrives. |
595 | @@ -85,7 +89,7 @@ | |||
596 | 85 | * Sends a message over the socket and adds it to the | 89 | * Sends a message over the socket and adds it to the |
597 | 86 | * sent_messages buffer in case it's needed for error recovery. | 90 | * sent_messages buffer in case it's needed for error recovery. |
598 | 87 | * ***********************************************************/ | 91 | * ***********************************************************/ |
600 | 88 | void send(outp sendme); | 92 | void send(outp & sendme); |
601 | 89 | /************************************************************** | 93 | /************************************************************** |
602 | 90 | * Called by the data consumer when an inbound message was | 94 | * Called by the data consumer when an inbound message was |
603 | 91 | * not valid in the current application context. msg_number | 95 | * not valid in the current application context. msg_number |
604 | @@ -124,7 +128,7 @@ | |||
605 | 124 | unsigned long long last_inbound; | 128 | unsigned long long last_inbound; |
606 | 125 | /// buffer to hold previously sent messages; required for | 129 | /// buffer to hold previously sent messages; required for |
607 | 126 | /// error recovery. | 130 | /// error recovery. |
609 | 127 | boost::circular_buffer<outp> sent_messages; | 131 | boost::circular_buffer<out> sent_messages; |
610 | 128 | /// fence post for recovery efforts, zero if none in play | 132 | /// fence post for recovery efforts, zero if none in play |
611 | 129 | unsigned long long nak_fence_post; | 133 | unsigned long long nak_fence_post; |
612 | 130 | /// These methods implment actual nak recovery. | 134 | /// These methods implment actual nak recovery. |
613 | @@ -136,7 +140,7 @@ | |||
614 | 136 | serializer tscvr_sequence(0); | 140 | serializer tscvr_sequence(0); |
615 | 137 | 141 | ||
616 | 138 | template <class out, class in, class outp, class inp> | 142 | template <class out, class in, class outp, class inp> |
618 | 139 | transceiver<out,in,outp,inp>::transceiver(tcp_socket_p socket) | 143 | transceiver<out,in,outp,inp>::transceiver(tcp_socket_p & socket) |
619 | 140 | { | 144 | { |
620 | 141 | // get the configuration parameters. | 145 | // get the configuration parameters. |
621 | 142 | global_conf_reader & config = global_conf_reader::get_instance(); | 146 | global_conf_reader & config = global_conf_reader::get_instance(); |
622 | @@ -152,7 +156,7 @@ | |||
623 | 152 | logname = s.str(); | 156 | logname = s.str(); |
624 | 153 | Poco::Logger & log = Poco::Logger::get(logname); | 157 | Poco::Logger & log = Poco::Logger::get(logname); |
625 | 154 | // set up the socket. | 158 | // set up the socket. |
627 | 155 | sock = socket; | 159 | sock = std::move(socket); |
628 | 156 | // annouce ourselves... | 160 | // annouce ourselves... |
629 | 157 | log.information("Instanciated."); | 161 | log.information("Instanciated."); |
630 | 158 | s.str(""); | 162 | s.str(""); |
631 | @@ -173,10 +177,10 @@ | |||
632 | 173 | // shutdown and release the socket. | 177 | // shutdown and release the socket. |
633 | 174 | try | 178 | try |
634 | 175 | { | 179 | { |
639 | 176 | if (sock) | 180 | if (sock) |
640 | 177 | { | 181 | { |
641 | 178 | sock.reset(); | 182 | sock.reset(); |
642 | 179 | }; | 183 | }; |
643 | 180 | } catch (...) {}; | 184 | } catch (...) {}; |
644 | 181 | // discard the sent messages list. | 185 | // discard the sent messages list. |
645 | 182 | sent_messages.clear(); | 186 | sent_messages.clear(); |
646 | @@ -184,65 +188,69 @@ | |||
647 | 184 | }; | 188 | }; |
648 | 185 | 189 | ||
649 | 186 | template <class out, class in, class outp, class inp> | 190 | template <class out, class in, class outp, class inp> |
650 | 191 | bool transceiver<out,in,outp,inp>::is_connected() | ||
651 | 192 | { | ||
652 | 193 | bool returnme = false; | ||
653 | 194 | if (sock and (sock->status() == tcp_socket::sock_connect)) | ||
654 | 195 | { | ||
655 | 196 | returnme = true; | ||
656 | 197 | }; | ||
657 | 198 | return returnme; | ||
658 | 199 | }; | ||
659 | 200 | |||
660 | 201 | template <class out, class in, class outp, class inp> | ||
661 | 187 | inp transceiver<out,in,outp,inp>::get() | 202 | inp transceiver<out,in,outp,inp>::get() |
662 | 188 | { | 203 | { |
663 | 189 | // get the message length first. | 204 | // get the message length first. |
664 | 190 | std::string len_field = sock->get(4,10); | 205 | std::string len_field = sock->get(4,10); |
665 | 191 | //std::cout << "len_field=" << http_chartohex(len_field) << std::endl; | ||
666 | 192 | msg_num_t msg_len; | 206 | msg_num_t msg_len; |
667 | 193 | for (int i=0; i<4; i++) | 207 | for (int i=0; i<4; i++) |
668 | 194 | { | 208 | { |
670 | 195 | msg_len.bytes[i] = len_field[i]; | 209 | msg_len.bytes[i] = len_field[i]; |
671 | 196 | }; | 210 | }; |
672 | 197 | //std::cout << ":len=" << msg_len.number << std::endl; | ||
673 | 198 | // get the rest of the message. | 211 | // get the rest of the message. |
674 | 199 | inp returnme(new in); | 212 | inp returnme(new in); |
675 | 200 | std::string input = sock->get(msg_len.number); | 213 | std::string input = sock->get(msg_len.number); |
676 | 201 | //std::cout << ":received=" << http_chartohex(input) << std::endl; | ||
677 | 202 | returnme->ParseFromString(input); | 214 | returnme->ParseFromString(input); |
678 | 203 | // for the first messsge any number is | 215 | // for the first messsge any number is |
679 | 204 | // accepted. | 216 | // accepted. |
680 | 205 | if (last_inbound == 0) | 217 | if (last_inbound == 0) |
681 | 206 | { | 218 | { |
683 | 207 | last_inbound = returnme->msg_uid(); | 219 | last_inbound = returnme->msg_uid(); |
684 | 208 | } | 220 | } |
685 | 209 | else | 221 | else |
686 | 210 | { | 222 | { |
698 | 211 | last_inbound++; | 223 | last_inbound++; |
699 | 212 | int temp = returnme->msg_uid(); | 224 | int temp = returnme->msg_uid(); |
700 | 213 | if (temp != last_inbound) | 225 | if (temp != last_inbound) |
701 | 214 | { | 226 | { |
702 | 215 | inbound_seq_error e; | 227 | inbound_seq_error e; |
703 | 216 | std::stringstream message; | 228 | std::stringstream message; |
704 | 217 | message << "Expected " << last_inbound | 229 | message << "Expected " << last_inbound |
705 | 218 | << " received " << temp; | 230 | << " received " << temp; |
706 | 219 | e.store(message.str()); | 231 | e.store(message.str()); |
707 | 220 | throw e; | 232 | throw e; |
708 | 221 | }; | 233 | }; |
709 | 222 | }; | 234 | }; |
710 | 223 | return returnme; | 235 | return returnme; |
711 | 224 | }; | 236 | }; |
712 | 225 | 237 | ||
713 | 226 | template <class out, class in, class outp, class inp> | 238 | template <class out, class in, class outp, class inp> |
715 | 227 | void transceiver<out,in,outp,inp>::send(outp sendme) | 239 | void transceiver<out,in,outp,inp>::send(outp & sendme) |
716 | 228 | { | 240 | { |
717 | 229 | sendme->set_msg_uid(out_msg_num()); | 241 | sendme->set_msg_uid(out_msg_num()); |
718 | 230 | std::string output; | 242 | std::string output; |
719 | 231 | output = sendme->SerializeAsString(); | 243 | output = sendme->SerializeAsString(); |
720 | 232 | msg_num_t msg_len; | 244 | msg_num_t msg_len; |
721 | 233 | msg_len.number = output.size(); | 245 | msg_len.number = output.size(); |
722 | 234 | //std::cout << "num:len" << msg_len.number << ":" << output.length() << //std::endl; | ||
723 | 235 | std::string num_field = " "; | 246 | std::string num_field = " "; |
724 | 236 | for (int i=0; i<4; i++) | 247 | for (int i=0; i<4; i++) |
725 | 237 | { | 248 | { |
728 | 238 | num_field[i] = msg_len.bytes[i]; | 249 | num_field[i] = msg_len.bytes[i]; |
727 | 239 | //std::cout << int(num_field[i]) << "," ; | ||
729 | 240 | }; | 250 | }; |
730 | 241 | //std::cout << " = " << msg_len.number << std::endl; | ||
731 | 242 | output = num_field + output; | 251 | output = num_field + output; |
732 | 243 | //std::cout << "out msg=" << http_chartohex(output) << std::endl; | ||
733 | 244 | sock->put(output); | 252 | sock->put(output); |
735 | 245 | sent_messages.push_back(sendme); | 253 | sent_messages.push_back(*sendme); |
736 | 246 | }; | 254 | }; |
737 | 247 | 255 | ||
738 | 248 | template <class out, class in, class outp, class inp> | 256 | template <class out, class in, class outp, class inp> |
739 | @@ -279,4 +287,4 @@ | |||
740 | 279 | 287 | ||
741 | 280 | } // namespace nrtb | 288 | } // namespace nrtb |
742 | 281 | 289 | ||
743 | 282 | #endif //nrtb_transceiver_h// | ||
744 | 283 | \ No newline at end of file | 290 | \ No newline at end of file |
745 | 291 | #endif //nrtb_transceiver_h// | ||
746 | 284 | 292 | ||
747 | === modified file 'common/transceiver/transceiver_test.cpp' | |||
748 | --- common/transceiver/transceiver_test.cpp 2011-09-17 01:08:29 +0000 | |||
749 | +++ common/transceiver/transceiver_test.cpp 2012-04-01 15:57:19 +0000 | |||
750 | @@ -45,14 +45,14 @@ | |||
751 | 45 | 45 | ||
752 | 46 | void inc() | 46 | void inc() |
753 | 47 | { | 47 | { |
756 | 48 | scope_lock lock(data_lock); | 48 | scope_lock lock(data_lock); |
757 | 49 | er_count++; | 49 | er_count++; |
758 | 50 | }; | 50 | }; |
759 | 51 | 51 | ||
760 | 52 | int operator ()() | 52 | int operator ()() |
761 | 53 | { | 53 | { |
764 | 54 | scope_lock lock(data_lock); | 54 | scope_lock lock(data_lock); |
765 | 55 | return er_count; | 55 | return er_count; |
766 | 56 | }; | 56 | }; |
767 | 57 | }; | 57 | }; |
768 | 58 | 58 | ||
769 | @@ -64,90 +64,124 @@ | |||
770 | 64 | 64 | ||
771 | 65 | tcp_socket_p sock; | 65 | tcp_socket_p sock; |
772 | 66 | unsigned long long last_inbound; | 66 | unsigned long long last_inbound; |
773 | 67 | |||
774 | 68 | server_work_thread() | ||
775 | 69 | { | ||
776 | 70 | cout << "Creating server_work_thread." << endl; | ||
777 | 71 | last_inbound = 0; | ||
778 | 72 | } | ||
779 | 67 | 73 | ||
780 | 68 | ~server_work_thread() | 74 | ~server_work_thread() |
781 | 69 | { | 75 | { |
784 | 70 | cout << "Destructing server_work_thread" << endl; | 76 | cout << "Destructing server_work_thread" << endl; |
783 | 71 | sock.reset(); | ||
785 | 72 | }; | 77 | }; |
786 | 73 | 78 | ||
787 | 74 | void run() | 79 | void run() |
788 | 75 | { | 80 | { |
822 | 76 | set_cancel_anytime(); | 81 | set_cancel_anytime(); |
823 | 77 | linkt link(sock); | 82 | linkt link(sock); |
824 | 78 | while (sock->status() == tcp_socket::sock_connect) | 83 | while (link.is_connected()) |
825 | 79 | { | 84 | { |
826 | 80 | try | 85 | try |
827 | 81 | { | 86 | { |
828 | 82 | linkt::out_ptr inbound = link.get(); | 87 | linkt::in_ptr inbound = link.get(); |
829 | 83 | last_inbound = inbound->msg_uid(); | 88 | last_inbound = inbound->msg_uid(); |
830 | 84 | cout << "\tReceived #" << last_inbound << endl; | 89 | link.send(inbound); |
831 | 85 | link.send(inbound); | 90 | if (last_inbound == 99) |
832 | 86 | if (last_inbound == 99) | 91 | { |
833 | 87 | { | 92 | cout << "Receiver thread closing." << endl; |
834 | 88 | cout << "Receiver thread closing." << endl; | 93 | exit(0); |
835 | 89 | exit(0); | 94 | }; |
836 | 90 | }; | 95 | } |
837 | 91 | } | 96 | catch (linkt::general_exception & e) |
838 | 92 | catch (linkt::general_exception & e) | 97 | { |
839 | 93 | { | 98 | cerr << "Server work thread caught " << e.what() |
840 | 94 | cerr << "Server work thread caught " << e.what() | 99 | << "\n\tComment: " << e.comment() << endl; |
841 | 95 | << "\n\tComment: " << e.comment() << endl; | 100 | er_count.inc();; |
842 | 96 | er_count.inc();; | 101 | } |
843 | 97 | } | 102 | catch (tcp_socket::general_exception & e) |
844 | 98 | catch (tcp_socket::general_exception & e) | 103 | { |
845 | 99 | { | 104 | cerr << "Server work thread caught " << e.what() |
846 | 100 | cerr << "Server work thread caught " << e.what() | 105 | << "\n\tComment: " << e.comment() << endl; |
847 | 101 | << "\n\tComment: " << e.comment() << endl; | 106 | er_count.inc();; |
848 | 102 | er_count.inc();; | 107 | } |
849 | 103 | } | 108 | catch (std::exception & e) |
850 | 104 | catch (std::exception & e) | 109 | { |
851 | 105 | { | 110 | cerr << "Server work thread caught " << e.what() |
852 | 106 | cerr << "Server work thread caught " << e.what() | 111 | << endl; |
853 | 107 | << endl; | 112 | er_count.inc();; |
854 | 108 | er_count.inc();; | 113 | }; |
855 | 109 | }; | 114 | }; |
856 | 110 | }; | ||
857 | 111 | }; | 115 | }; |
858 | 112 | }; | 116 | }; |
859 | 113 | 117 | ||
860 | 114 | class listener: public tcp_server_socket_factory | 118 | class listener: public tcp_server_socket_factory |
861 | 115 | { | 119 | { |
862 | 116 | protected: | ||
863 | 117 | boost::shared_ptr<server_work_thread> task; | ||
864 | 118 | |||
865 | 119 | public: | 120 | public: |
866 | 121 | |||
867 | 122 | std::unique_ptr<server_work_thread> task; | ||
868 | 123 | |||
869 | 120 | listener(const string & add, const int & back) | 124 | listener(const string & add, const int & back) |
871 | 121 | : tcp_server_socket_factory(add, back) {}; | 125 | : tcp_server_socket_factory(add, back) |
872 | 126 | { | ||
873 | 127 | cout << "Listener constructed." << endl; | ||
874 | 128 | }; | ||
875 | 129 | |||
876 | 122 | ~listener() | 130 | ~listener() |
877 | 123 | { | 131 | { |
880 | 124 | cout << "Destructing listener" << endl; | 132 | cout << "Destructing listener" << endl; |
881 | 125 | task.reset(); | 133 | // check to see if the listener is still up. |
882 | 134 | try | ||
883 | 135 | { | ||
884 | 136 | if (listening()) | ||
885 | 137 | { | ||
886 | 138 | cerr << " Listener is still running..."; | ||
887 | 139 | stop_listen(); | ||
888 | 140 | cerr << " shutdown is complete." << endl; | ||
889 | 141 | }; | ||
890 | 142 | } | ||
891 | 143 | catch (...) | ||
892 | 144 | { | ||
893 | 145 | cerr << " Presuming listener is down." << endl; | ||
894 | 146 | }; | ||
895 | 147 | if (!task) | ||
896 | 148 | { | ||
897 | 149 | cerr << " Task is not allocated. " << endl; | ||
898 | 150 | } | ||
899 | 151 | // check to see if task is still running and display | ||
900 | 152 | // a warning if it is. | ||
901 | 153 | if (task and (task->is_running())) | ||
902 | 154 | { | ||
903 | 155 | cerr << "WARNING: Worker is still running!!" << endl; | ||
904 | 156 | task->stop(); | ||
905 | 157 | task->join(); | ||
906 | 158 | cerr << "Worker thread shutdown is complete." << endl; | ||
907 | 159 | }; | ||
908 | 126 | }; | 160 | }; |
909 | 127 | 161 | ||
910 | 128 | bool on_accept() | 162 | bool on_accept() |
911 | 129 | { | 163 | { |
928 | 130 | if (!task) | 164 | if (!task) |
929 | 131 | { | 165 | { |
930 | 132 | task.reset(new server_work_thread); | 166 | cout << "In listener::on_accept()" << endl; |
931 | 133 | task->last_inbound = 0; | 167 | task.reset(new server_work_thread); |
932 | 134 | task->sock = connect_sock; | 168 | task->sock = std::move(connect_sock); |
933 | 135 | task->start(*(task.get())); | 169 | task->start(); |
934 | 136 | cout << "server thread running." << endl; | 170 | cout << "server thread started." << endl; |
935 | 137 | // shutdown the listener thead.. our work is done here. | 171 | // shutdown the listener thead.. our work is done here. |
936 | 138 | return false; | 172 | return false; |
937 | 139 | } | 173 | } |
938 | 140 | else | 174 | else |
939 | 141 | { | 175 | { |
940 | 142 | connect_sock->close(); | 176 | connect_sock->close(); |
941 | 143 | cerr << "Multiple attempts to connect to server" | 177 | cerr << "Multiple attempts to connect to server" |
942 | 144 | << endl; | 178 | << endl; |
943 | 145 | }; | 179 | }; |
944 | 146 | }; | 180 | }; |
945 | 147 | }; | 181 | }; |
946 | 148 | 182 | ||
947 | 149 | string address = "127.0.0.1:"; | 183 | string address = "127.0.0.1:"; |
949 | 150 | int port_base = 12334; | 184 | int port_base = 14334; |
950 | 151 | 185 | ||
951 | 152 | int main() | 186 | int main() |
952 | 153 | { | 187 | { |
953 | @@ -155,51 +189,77 @@ | |||
954 | 155 | 189 | ||
955 | 156 | try | 190 | try |
956 | 157 | { | 191 | { |
986 | 158 | //set up our port and address | 192 | //set up our port and address |
987 | 159 | boost::mt19937 rng; | 193 | boost::mt19937 rng; |
988 | 160 | rng.seed(time(0)); | 194 | rng.seed(time(0)); |
989 | 161 | boost::uniform_int<> r(0,1000); | 195 | boost::uniform_int<> r(0,1000); |
990 | 162 | stringstream s; | 196 | stringstream s; |
991 | 163 | s << address << port_base + r(rng); | 197 | s << address << port_base + r(rng); |
992 | 164 | address = s.str(); | 198 | address = s.str(); |
993 | 165 | cout << "Using " << address << endl; | 199 | cout << "Using " << address << endl; |
994 | 166 | 200 | ||
995 | 167 | // kick off the listener thread. | 201 | // kick off the listener thread. |
996 | 168 | listener server(address,5); | 202 | listener server(address,5); |
997 | 169 | server.start_listen(); | 203 | server.start_listen(); |
998 | 170 | usleep(1e4); | 204 | while (!server.listening()) |
999 | 171 | 205 | { | |
1000 | 172 | // set up our sender | 206 | usleep(1e3); |
1001 | 173 | tcp_socket_p sock(new tcp_socket); | 207 | }; |
1002 | 174 | sock->connect(address); | 208 | cout << "Listener thread is ready." << endl; |
1003 | 175 | linkt sender(sock); | 209 | |
1004 | 176 | 210 | // set up our sender | |
1005 | 177 | // Let's send a few things. | 211 | tcp_socket_p sock(new tcp_socket); |
1006 | 178 | for (int i=0; i<100; i++) | 212 | int trycount = 0; |
1007 | 179 | { | 213 | while (sock->status() != tcp_socket::sock_connect) |
1008 | 180 | linkt::out_ptr msg(new my_msg); | 214 | { |
1009 | 181 | sender.send(msg); | 215 | try |
1010 | 182 | cout << "Sent " << msg->msg_uid() << endl; | 216 | { |
1011 | 183 | msg = sender.get(); | 217 | sock->connect(address); |
1012 | 184 | cout << "Got back " << msg->msg_uid() << endl; | 218 | } |
1013 | 185 | }; | 219 | catch (tcp_socket::bad_connect_exception & e) |
1014 | 186 | usleep(1e4); | 220 | { |
1015 | 221 | trycount++; | ||
1016 | 222 | if (trycount > 99) | ||
1017 | 223 | { | ||
1018 | 224 | cerr << "Too many connect failures for the sender socket." | ||
1019 | 225 | << endl; | ||
1020 | 226 | throw e; | ||
1021 | 227 | }; | ||
1022 | 228 | usleep(1e4); | ||
1023 | 229 | }; | ||
1024 | 230 | } | ||
1025 | 231 | cout << "sender socket is connected to listener" << endl; | ||
1026 | 232 | linkt sender(sock); | ||
1027 | 233 | cout << "Sender transciever is ready to use." << endl; | ||
1028 | 234 | |||
1029 | 235 | // Let's send a few things. | ||
1030 | 236 | for (int i=0; i<100; i++) | ||
1031 | 237 | { | ||
1032 | 238 | linkt::out_ptr msg(new my_msg); | ||
1033 | 239 | sender.send(msg); | ||
1034 | 240 | cout << "Sent " << msg->msg_uid() << ", "; | ||
1035 | 241 | msg = sender.get(); | ||
1036 | 242 | cout << "good return." << endl; | ||
1037 | 243 | }; | ||
1038 | 244 | usleep(1e4); | ||
1039 | 187 | } | 245 | } |
1040 | 188 | catch (...) | 246 | catch (...) |
1041 | 189 | { | 247 | { |
1044 | 190 | cout << "exception caught during test." << endl; | 248 | cout << "exception caught during test." << endl; |
1045 | 191 | er_count.inc(); | 249 | er_count.inc(); |
1046 | 192 | }; | 250 | }; |
1047 | 193 | 251 | ||
1048 | 194 | int faults = er_count(); | 252 | int faults = er_count(); |
1049 | 195 | if (faults) | 253 | if (faults) |
1050 | 196 | { | 254 | { |
1053 | 197 | cout << "========== ** There were " << faults | 255 | cout << "========== ** There were " << faults |
1054 | 198 | << "errors logged. =========" << endl; | 256 | << " errors logged. =========" << endl; |
1055 | 199 | } | 257 | } |
1056 | 200 | else | 258 | else |
1059 | 201 | cout << "========= nrtb::transceiver test complete.=========" | 259 | { |
1060 | 202 | << endl; | 260 | cout << "========= nrtb::transceiver test complete.=========" |
1061 | 261 | << endl; | ||
1062 | 262 | }; | ||
1063 | 203 | 263 | ||
1064 | 204 | return faults; | 264 | return faults; |
1065 | 205 | }; | ||
1066 | 206 | \ No newline at end of file | 265 | \ No newline at end of file |
1067 | 266 | }; |
Merge test complete. As there has been no comments or response from the team, I'll be moving the code to the alpha stream. We need to be using the -std=gnu++0x switch on all compiles and links from this point on.