2 * @file Bug_2912_Regression_Test.cpp
4 * Reproduces the problems reported in bug 2912:
5 * http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2912
7 * This test reproduces the following interactions:
9 * ACE_TMAIN Client proactor Server proactor
10 * thread dispatcher thread dispatcher thread
11 * ---------------- ------------------- --------------------
18 * SH::handle_read_stream
21 * SH::handle_read_stream
23 * SH::write (causes do_SSL_read to fail)
25 * @author Paul Daugherty <paul@nxicom.com>
29 #include "../test_config.h"
30 #include "ace/SSL/SSL_Asynch_Stream.h"
31 #include "ace/Proactor.h"
33 #include "ace/Asynch_Acceptor.h"
34 #include "ace/Asynch_Connector.h"
35 #include "ace/Manual_Event.h"
36 #include "ace/OS_NS_unistd.h"
38 /* Linux kernels can't hack multiple outstanding I/O, which this
40 #if defined (ACE_HAS_THREADS) && \
41 (defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)) && \
45 * Data payload sent between client and server. Test is not dependent
46 * on payload characteristics.
48 #define DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
49 #define DATA_SIZE ACE_OS::strlen(DATA)
51 // Function to remove signals from the signal mask.
53 disable_signal (int sigmin
, int sigmax
)
55 #if !defined (ACE_LACKS_UNIX_SIGNALS)
57 if (ACE_OS::sigemptyset (&signal_set
) == - 1)
59 ACE_TEXT ("Error: (%P|%t):%p\n"),
60 ACE_TEXT ("sigemptyset failed")));
62 for (int i
= sigmin
; i
<= sigmax
; i
++)
63 ACE_OS::sigaddset (&signal_set
, i
);
65 // Put the <signal_set>.
66 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
67 // In multi-threaded application this is not POSIX compliant
68 // but let's leave it just in case.
69 if (ACE_OS::sigprocmask (SIG_BLOCK
, &signal_set
, 0) != 0)
71 if (ACE_OS::thr_sigsetmask (SIG_BLOCK
, &signal_set
, 0) != 0)
72 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
73 ACE_ERROR_RETURN ((LM_ERROR
,
74 ACE_TEXT ("Error: (%P|%t): %p\n"),
75 ACE_TEXT ("SIG_BLOCK failed")),
78 ACE_UNUSED_ARG (sigmin
);
79 ACE_UNUSED_ARG (sigmax
);
80 #endif /* ACE_LACKS_UNIX_SIGNALS */
88 * The client and server must use different proactors since this bug is
89 * dependent on threads.
91 class Client_Proactor
: public ACE_Proactor
{};
92 typedef ACE_Singleton
<Client_Proactor
, ACE_SYNCH_RECURSIVE_MUTEX
>
93 Client_Proactor_Singleton
;
94 #define CLIENT_PROACTOR Client_Proactor_Singleton::instance()
96 class Client_Proactor_Task
: public ACE_Task_Base
102 typedef ACE_Singleton
<Client_Proactor_Task
, ACE_SYNCH_RECURSIVE_MUTEX
>
103 Client_Proactor_Task_Singleton
;
104 #define CLIENT_PROACTOR_TASK Client_Proactor_Task_Singleton::instance()
107 Client_Proactor_Task::svc ()
109 // Keep RT signals on POSIX from killing us.
110 disable_signal (ACE_SIGRTMIN
, ACE_SIGRTMAX
);
112 CLIENT_PROACTOR
->proactor_reset_event_loop ();
113 CLIENT_PROACTOR
->proactor_run_event_loop ();
120 class Server_Proactor
: public ACE_Proactor
{};
121 typedef ACE_Singleton
<Server_Proactor
, ACE_SYNCH_RECURSIVE_MUTEX
>
122 Server_Proactor_Singleton
;
123 #define SERVER_PROACTOR Server_Proactor_Singleton::instance ()
125 class Server_Proactor_Task
: public ACE_Task_Base
131 typedef ACE_Singleton
<Server_Proactor_Task
, ACE_SYNCH_RECURSIVE_MUTEX
>
132 Server_Proactor_Task_Singleton
;
133 #define SERVER_PROACTOR_TASK Server_Proactor_Task_Singleton::instance ()
136 Server_Proactor_Task::svc ()
138 // Keep RT signals on POSIX from killing us.
139 disable_signal (ACE_SIGRTMIN
, ACE_SIGRTMAX
);
141 SERVER_PROACTOR
->proactor_reset_event_loop ();
142 SERVER_PROACTOR
->proactor_run_event_loop ();
147 * This test depends on ADH since the error is related to a missing cert.pem
149 static DH
* dh1024
= 0;
154 static unsigned char dh1024_p
[]={
155 0xD7,0xFE,0xEC,0x06,0x28,0x03,0x34,0x96,0xB8,0x08,0x86,0x62,
156 0xF1,0xA2,0xBA,0x84,0x7C,0xAF,0xA3,0x1F,0x6A,0x3D,0x03,0x20,
157 0x81,0x8D,0x0E,0x43,0x3A,0x54,0x74,0x9F,0x83,0xD2,0xB7,0xE9,
158 0x57,0xC1,0x67,0xE9,0x11,0x38,0x2B,0x8E,0x9B,0x1C,0x5D,0x14,
159 0x18,0x7D,0x4F,0xEB,0xB1,0x4D,0xFA,0x6F,0x06,0xDD,0xDD,0x6D,
160 0x9A,0xD0,0x9E,0x4F,0xE4,0x04,0x3E,0x86,0x6F,0x15,0x60,0x35,
161 0x9B,0xA1,0xBA,0x53,0xBA,0x84,0xB5,0x06,0xB1,0xAD,0x94,0x25,
162 0xD1,0xED,0xD2,0xF4,0xD7,0x02,0x2F,0x35,0x25,0xE7,0x2D,0x60,
163 0xEE,0x7A,0x61,0xAD,0x98,0xA8,0x3D,0xAD,0xB1,0x8A,0x5E,0xCE,
164 0xF0,0x09,0xD4,0x67,0x28,0x3D,0x52,0x64,0x78,0xBB,0xC3,0x9D,
165 0x40,0xF4,0x72,0xDC,0xC9,0x31,0x0D,0xA3,
167 static unsigned char dh1024_g
[]={
172 if ((dh
=DH_new()) == 0) return(0);
174 BIGNUM
* p
= BN_bin2bn(dh1024_p
,sizeof(dh1024_p
),0);
175 BIGNUM
* g
= BN_bin2bn(dh1024_g
,sizeof(dh1024_g
),0);
177 if ((p
== 0) || (g
== 0))
183 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
187 DH_set0_pqg(dh
, p
, 0, g
);
194 tmp_dh_callback (SSL
*s
, int is_export
, int keylength
)
197 ACE_UNUSED_ARG(is_export
);
203 dh1024
= get_dh1024();
207 /* Generating a key on the fly is very costly, so use what is there */
208 ACE_ERROR ((LM_ERROR
,
209 ACE_TEXT ("tmp_dh_callback, unsupported key length, %d\n"),
218 SSL_CTX_set_quiet_shutdown (ACE_SSL_Context::instance ()->context(), 1);
219 SSL_CTX_set_options (ACE_SSL_Context::instance ()->context(),
220 SSL_OP_SINGLE_DH_USE
);
221 SSL_CTX_set_tmp_dh_callback (ACE_SSL_Context::instance ()->context (),
224 if (SSL_CTX_set_cipher_list (ACE_SSL_Context::instance ()->context (), "ADH"))
230 ACE_DEBUG ((LM_ERROR
,
231 ACE_TEXT ("SSL_CTX_set_cipher_list failed\n")));
238 * Server's ACE_Service_Handler
240 class Server_Service_Handler
: public ACE_Service_Handler
243 Server_Service_Handler ();
245 virtual ~Server_Service_Handler ();
247 //FUZZ: disable check_for_lack_ACE_OS
248 virtual void open (ACE_HANDLE h
, ACE_Message_Block
&);
249 //FUZZ: enable check_for_lack_ACE_OS
251 virtual void handle_read_stream (
252 const ACE_Asynch_Read_Stream::Result
&result
);
254 virtual void handle_write_stream (
255 const ACE_Asynch_Write_Stream::Result
&result
);
257 virtual void handle_wakeup ();
259 void cancel_and_close ();
265 //FUZZ: disable check_for_lack_ACE_OS
266 int read (ACE_Message_Block
&mb
, size_t bytes_to_read
);
268 int write (ACE_Message_Block
&mb
, size_t bytes_to_write
);
269 //FUZZ: enable check_for_lack_ACE_OS
271 int safe_to_delete () const;
274 mutable ACE_SYNCH_RECURSIVE_MUTEX mtx_
;
275 ACE_SSL_Asynch_Stream ssl_stream_
;
278 int handle_wakeup_expected_
;
279 int handle_wakeup_received_
;
283 Server_Service_Handler::Server_Service_Handler () :
284 ssl_stream_ (ACE_SSL_Asynch_Stream::ST_SERVER
),
287 handle_wakeup_expected_ (0),
288 handle_wakeup_received_ (0),
293 Server_Service_Handler::~Server_Service_Handler ()
295 if (ACE_INVALID_HANDLE
!= this->handle ())
297 ACE_OS::closesocket (this->handle ());
298 this->handle (ACE_INVALID_HANDLE
);
303 Server_Service_Handler::open (ACE_HANDLE h
, ACE_Message_Block
&)
305 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
307 if (this->ssl_stream_
.open (*this, h
, 0, this->proactor ()) != 0)
309 //FUZZ: disable check_for_lack_ACE_OS
310 ACE_DEBUG ((LM_DEBUG
,
311 ACE_TEXT("Server_Service_Handler::open: ")
312 ACE_TEXT("ACE_SSL_Asynch_Stream::open failed, %d\n"),
314 //FUZZ: enable check_for_lack_ACE_OS
316 this->cancel_and_close ();
320 if (this->read_data () < 0)
322 this->cancel_and_close ();
328 Server_Service_Handler::handle_read_stream(
329 const ACE_Asynch_Read_Stream::Result
&result
)
331 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
333 this->pending_reads_
--;
335 if (!result
.success () || 0 == result
.bytes_transferred ())
337 // Error or remote disconnect
339 result
.message_block ().release ();
343 // No error message when shutting down
345 if (!result
.success ())
347 ACE_DEBUG ((LM_DEBUG
,
348 ACE_TEXT ("Server_Service_Handler::handle_read_stream: error: %d\n"),
353 ACE_DEBUG ((LM_DEBUG
,
354 ACE_TEXT ("Server_Service_Handler::handle_read_stream: remote disconnect\n")));
358 this->cancel_and_close ();
360 else if (result
.bytes_transferred () < result
.bytes_to_read ())
364 if (this->read (result
.message_block (),
365 result
.bytes_to_read () - result
.bytes_transferred ()) < 0)
367 result
.message_block ().release ();
369 this->cancel_and_close ();
376 result
.message_block ().release ();
380 if (this->write_data () < 0)
382 this->cancel_and_close ();
387 else if (this->read_data () < 0)
389 this->cancel_and_close ();
395 Server_Service_Handler::handle_write_stream (
396 const ACE_Asynch_Write_Stream::Result
&result
)
398 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
400 this->pending_writes_
--;
402 if (!result
.success () || 0 == result
.bytes_transferred ())
406 result
.message_block ().release ();
408 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
409 "Server_Service_Handler::handle_write_stream: error: %d\n"),
412 this->cancel_and_close ();
414 else if (result
.bytes_transferred () < result
.bytes_to_write ())
418 if (this->write(result
.message_block (),
419 result
.bytes_to_write () - result
.bytes_transferred ()) < 0)
421 result
.message_block ().release ();
423 this->cancel_and_close ();
430 result
.message_block().release ();
435 Server_Service_Handler::handle_wakeup ()
437 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
439 this->handle_wakeup_received_
= 1;
443 Server_Service_Handler::cancel_and_close ()
445 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
448 this->ssl_stream_
.cancel ();
449 this->handle_wakeup_expected_
= -1 == this->ssl_stream_
.close ();
453 Server_Service_Handler::read_data ()
455 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
457 ACE_Message_Block
*mb
= 0;
458 ACE_NEW_NORETURN(mb
, ACE_Message_Block (DATA_SIZE
));
460 int ret
= this->read (*mb
, DATA_SIZE
);
473 Server_Service_Handler::write_data ()
475 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
477 ACE_Message_Block
*mb
= 0;
478 ACE_NEW_NORETURN(mb
, ACE_Message_Block (DATA_SIZE
));
479 ACE_OS::memcpy (mb
->wr_ptr (), DATA
, DATA_SIZE
);
480 mb
->wr_ptr (DATA_SIZE
);
482 int ret
= this->write (*mb
, DATA_SIZE
);
495 Server_Service_Handler::read (ACE_Message_Block
&mb
, size_t bytes_to_read
)
497 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
500 if ((ret
= this->ssl_stream_
.read (mb
, bytes_to_read
)) < 0)
502 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
503 "Server_Service_Handler::read: read failed: %d\n"), (int)errno
));
507 this->pending_reads_
++;
513 Server_Service_Handler::write (ACE_Message_Block
&mb
, size_t bytes_to_write
)
515 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
518 if ((ret
= this->ssl_stream_
.write (mb
, bytes_to_write
)) < 0)
520 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
521 "Server_Service_Handler::write: write failed: %d\n"), (int)errno
));
525 this->pending_writes_
++;
531 Server_Service_Handler::safe_to_delete () const
533 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
535 return 0 == this->pending_writes_
&&
536 0 == this->pending_reads_
&&
537 (!this->handle_wakeup_expected_
|| this->handle_wakeup_received_
);
543 class Acceptor
: public ACE_Asynch_Acceptor
<Server_Service_Handler
>
548 virtual ~Acceptor ();
550 virtual int cancel ();
552 virtual int validate_connection (const ACE_Asynch_Accept::Result
& result
,
553 const ACE_INET_Addr
&remote
, const ACE_INET_Addr
& local
);
555 virtual Server_Service_Handler
*make_handler ();
557 //FUZZ: disable check_for_lack_ACE_OS
558 virtual int accept (size_t bytes_to_read
= 0, const void *act
= 0);
559 //FUZZ: enable check_for_lack_ACE_OS
561 virtual void handle_accept (const ACE_Asynch_Accept::Result
&result
);
563 int safe_to_delete () const;
565 void prepare_for_connection (Server_Service_Handler
*service_handler
);
567 mutable ACE_SYNCH_RECURSIVE_MUTEX mtx_
;
570 Server_Service_Handler
*service_handler_
;
573 typedef ACE_Singleton
<Acceptor
, ACE_SYNCH_RECURSIVE_MUTEX
> Acceptor_Singleton
;
574 #define ACCEPTOR Acceptor_Singleton::instance ()
576 Acceptor::Acceptor () :
583 Acceptor::~Acceptor ()
590 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
592 this->cancel_flag_
= 1;
593 this->reissue_accept (0);
595 ACE_HANDLE h
= this->get_handle ();
596 if (h
!= ACE_INVALID_HANDLE
)
598 this->ACE_Asynch_Acceptor
<Server_Service_Handler
>::cancel ();
600 ACE_OS::closesocket (h
);
601 this->handle (ACE_INVALID_HANDLE
);
608 Acceptor::safe_to_delete () const
610 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
611 return (this->cancel_flag_
!= 0 && this->accept_cnt_
== 0) ? 1 : 0;
615 Acceptor::prepare_for_connection (Server_Service_Handler
*service_handler
)
617 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
618 this->service_handler_
= service_handler
;
622 Acceptor::validate_connection (const ACE_Asynch_Accept::Result
& result
,
623 const ACE_INET_Addr
& /*remote*/, const ACE_INET_Addr
& /*local*/)
625 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
627 if (0 != this->service_handler_
&& result
.success ())
637 Server_Service_Handler
*
638 Acceptor::make_handler ()
640 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, 0);
642 ACE_ASSERT (0 != this->service_handler_
);
643 Server_Service_Handler
*service_handler
= this->service_handler_
;
644 this->service_handler_
= 0;
645 return service_handler
;
649 Acceptor::accept (size_t bytes_to_read
, const void *act
)
651 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
653 if (this->cancel_flag_
!= 0)
657 int rc
= this->ACE_Asynch_Acceptor
<Server_Service_Handler
>::accept (
666 Acceptor::handle_accept (const ACE_Asynch_Accept::Result
&result
)
668 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
670 this->ACE_Asynch_Acceptor
<Server_Service_Handler
>::handle_accept (result
);
677 * Client's ACE_Service_Handler
679 class Client_Service_Handler
: public ACE_Service_Handler
682 Client_Service_Handler ();
684 virtual ~Client_Service_Handler ();
686 //FUZZ: disable check_for_lack_ACE_OS
687 virtual void open (ACE_HANDLE h
, ACE_Message_Block
&);
688 //FUZZ: enable check_for_lack_ACE_OS
690 virtual void handle_read_stream (
691 const ACE_Asynch_Read_Stream::Result
&result
);
693 virtual void handle_write_stream (
694 const ACE_Asynch_Write_Stream::Result
&result
);
696 virtual void handle_wakeup ();
698 void cancel_and_close ();
704 //FUZZ: disable check_for_lack_ACE_OS
705 int read (ACE_Message_Block
&mb
, size_t bytes_to_read
);
707 int write (ACE_Message_Block
&mb
, size_t bytes_to_write
);
708 //FUZZ: enable check_for_lack_ACE_OS
710 int safe_to_delete () const;
712 int wait_for_external_write_queue (ACE_Time_Value
*wait_time
);
714 int wait_for_read_completed (ACE_Time_Value
*wait_time
);
716 int read_successful () const;
719 mutable ACE_SYNCH_RECURSIVE_MUTEX mtx_
;
720 ACE_SSL_Asynch_Stream ssl_stream_
;
721 ACE_Manual_Event ready_for_external_write_
;
722 ACE_Manual_Event read_completed_
;
723 int read_successful_
;
726 int handle_wakeup_expected_
;
727 int handle_wakeup_received_
;
728 int completed_reads_
;
732 Client_Service_Handler::Client_Service_Handler () :
733 ssl_stream_ (ACE_SSL_Asynch_Stream::ST_CLIENT
),
734 read_successful_ (0),
737 handle_wakeup_expected_ (0),
738 handle_wakeup_received_ (0),
739 completed_reads_ (0),
744 Client_Service_Handler::~Client_Service_Handler ()
746 if (ACE_INVALID_HANDLE
!= this->handle ())
748 ACE_OS::closesocket (this->handle ());
749 this->handle (ACE_INVALID_HANDLE
);
754 Client_Service_Handler::open (ACE_HANDLE h
, ACE_Message_Block
&)
756 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
758 if (this->ssl_stream_
.open (*this, h
, 0, this->proactor ()) != 0)
760 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
761 "Client_Service_Handler::open: ACE_SSL_Asynch_Stream::open failed, %d\n"),
763 this->cancel_and_close ();
767 ACE_Message_Block
*mb
= 0;
768 ACE_NEW_NORETURN(mb
, ACE_Message_Block (DATA_SIZE
));
770 if (this->read_data () < 0 || this->write_data () < 0)
772 this->cancel_and_close ();
778 Client_Service_Handler::handle_read_stream (
779 const ACE_Asynch_Read_Stream::Result
&result
)
781 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
783 this->pending_reads_
--;
785 if (!result
.success () || 0 == result
.bytes_transferred ())
787 // Error or remote disconnect
789 result
.message_block ().release ();
793 // No error message when shutting down
795 if (!result
.success ())
797 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
798 "Client_Service_Handler::handle_read_stream: error: %d\n"),
803 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
804 "Client_Service_Handler::handle_read_stream: remote disconnect\n")));
808 this->read_completed_
.signal ();
810 this->cancel_and_close ();
812 else if (result
.bytes_transferred () < result
.bytes_to_read ())
816 if (this->read (result
.message_block(),
817 result
.bytes_to_read () - result
.bytes_transferred ()) < 0)
819 result
.message_block ().release ();
821 this->cancel_and_close ();
828 this->completed_reads_
++;
830 result
.message_block ().release ();
832 // We now have sent and received data in the proactor thread. Signal the
833 // main thread to try sending data in the main thread.
834 if (this->completed_reads_
== 1)
836 this->ready_for_external_write_
.signal ();
840 // The main thread wrote data that was echoed back to us on our
841 // second read. If we get here, the test was successful in that
842 // the main thread successfully sent data to the server.
843 this->read_successful_
= 1;
844 this->read_completed_
.signal ();
848 if (this->read_data () < 0)
850 this->cancel_and_close ();
856 Client_Service_Handler::handle_write_stream (
857 const ACE_Asynch_Write_Stream::Result
&result
)
859 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
861 this->pending_writes_
--;
863 if (!result
.success () || 0 == result
.bytes_transferred ())
867 result
.message_block ().release ();
869 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
870 "Client_Service_Handler::handle_write_stream: error: %d\n"),
873 this->cancel_and_close ();
875 else if (result
.bytes_transferred () < result
.bytes_to_write ())
879 if (this->write (result
.message_block(),
880 result
.bytes_to_write () - result
.bytes_transferred ()) < 0)
882 result
.message_block ().release ();
884 this->cancel_and_close ();
891 result
.message_block ().release ();
896 Client_Service_Handler::handle_wakeup ()
898 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
900 this->handle_wakeup_received_
= 1;
904 Client_Service_Handler::cancel_and_close ()
906 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
909 this->ssl_stream_
.cancel ();
910 this->handle_wakeup_expected_
= -1 == this->ssl_stream_
.close ();
914 Client_Service_Handler::read_data ()
916 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
918 ACE_Message_Block
*mb
= 0;
919 ACE_NEW_NORETURN(mb
, ACE_Message_Block (DATA_SIZE
));
921 int ret
= this->read (*mb
, DATA_SIZE
);
934 Client_Service_Handler::write_data ()
936 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
938 ACE_Message_Block
*mb
= 0;
939 ACE_NEW_NORETURN (mb
, ACE_Message_Block (DATA_SIZE
));
940 ACE_OS::memcpy (mb
->wr_ptr (), DATA
, DATA_SIZE
);
941 mb
->wr_ptr (DATA_SIZE
);
943 int ret
= this->write (*mb
, DATA_SIZE
);
956 Client_Service_Handler::read (ACE_Message_Block
&mb
, size_t bytes_to_read
)
958 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
961 if ((ret
= this->ssl_stream_
.read (mb
, bytes_to_read
)) < 0)
963 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
964 "Client_Service_Handler::read: read failed: %d\n"), (int)errno
));
968 this->pending_reads_
++;
974 Client_Service_Handler::write (ACE_Message_Block
&mb
, size_t bytes_to_write
)
976 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
979 if ((ret
= this->ssl_stream_
.write (mb
, bytes_to_write
)) < 0)
981 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
982 "Client_Service_Handler::write: write failed: %d\n"), (int)errno
));
986 this->pending_writes_
++;
992 Client_Service_Handler::safe_to_delete () const
994 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
996 return 0 == this->pending_writes_
&&
997 0 == this->pending_reads_
&&
998 (!this->handle_wakeup_expected_
|| this->handle_wakeup_received_
);
1002 Client_Service_Handler::wait_for_external_write_queue (ACE_Time_Value
*wait_time
)
1004 return this->ready_for_external_write_
.wait (wait_time
, 0);
1008 Client_Service_Handler::wait_for_read_completed (ACE_Time_Value
*wait_time
)
1010 return this->read_completed_
.wait (wait_time
, 0);
1014 Client_Service_Handler::read_successful () const
1016 return this->read_successful_
;
1020 * Client's connector
1022 class Connector
: public ACE_Asynch_Connector
<Client_Service_Handler
>
1027 virtual ~Connector ();
1029 //FUZZ: disable check_for_lack_ACE_OS
1030 virtual int connect (
1031 const ACE_INET_Addr
&remote_sap
,
1032 const ACE_INET_Addr
&local_sap
=
1033 (const ACE_INET_Addr
&)ACE_Addr::sap_any
,
1035 const void *act
= 0);
1036 //FUZZ: enable check_for_lack_ACE_OS
1038 virtual int validate_connection (
1039 const ACE_Asynch_Connect::Result
& result
,
1040 const ACE_INET_Addr
&remote
,
1041 const ACE_INET_Addr
& local
);
1043 int safe_to_delete () const;
1045 void prepare_for_connection (Client_Service_Handler
*service_handler
);
1048 virtual void handle_connect (const ACE_Asynch_Connect::Result
&result
);
1050 virtual Client_Service_Handler
* make_handler ();
1052 mutable ACE_SYNCH_RECURSIVE_MUTEX mtx_
;
1053 Client_Service_Handler
*service_handler_
;
1057 typedef ACE_Singleton
<Connector
, ACE_SYNCH_RECURSIVE_MUTEX
> Connector_Singleton
;
1058 #define CONNECTOR Connector_Singleton::instance ()
1060 Connector::Connector () :
1061 service_handler_ (0)
1065 Connector::~Connector ()
1070 Connector::connect (const ACE_INET_Addr
&remote_sap
,
1071 const ACE_INET_Addr
&local_sap
, int reuse_addr
, const void *act
)
1073 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
1075 this->connecting_
= 1;
1077 return this->ACE_Asynch_Connector
<Client_Service_Handler
>::connect (
1078 remote_sap
, local_sap
, reuse_addr
, act
);
1082 Connector::validate_connection (const ACE_Asynch_Connect::Result
& result
,
1083 const ACE_INET_Addr
&remote
, const ACE_INET_Addr
& local
)
1085 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
1087 ACE_UNUSED_ARG (result
);
1088 ACE_UNUSED_ARG (remote
);
1089 ACE_UNUSED_ARG (local
);
1091 if (!result
.success ())
1093 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
1094 "Connector::validate_connection failed: %d\n"), result
.error ()));
1104 Connector::handle_connect (const ACE_Asynch_Connect::Result
&result
)
1106 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
1108 this->ACE_Asynch_Connector
<Client_Service_Handler
>::handle_connect (result
);
1110 this->connecting_
= 0;
1113 Client_Service_Handler
*
1114 Connector::make_handler ()
1116 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, 0);
1118 ACE_ASSERT(0 != this->service_handler_
);
1119 Client_Service_Handler
*service_handler
= this->service_handler_
;
1120 this->service_handler_
= 0;
1121 return service_handler
;
1125 Connector::safe_to_delete () const
1127 ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
, -1);
1129 return 0 == this->connecting_
;
1133 Connector::prepare_for_connection (Client_Service_Handler
*service_handler
)
1135 ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX
, guard
, this->mtx_
);
1136 this->service_handler_
= service_handler
;
1140 run_main (int, ACE_TCHAR
*[])
1142 ACE_START_TEST (ACE_TEXT ("Bug_2912_Regression_Test"));
1144 // SSL_CTX_set_cipher_list, etc.
1147 // Keep RT signals on POSIX from killing us.
1148 disable_signal (ACE_SIGRTMIN
, ACE_SIGRTMAX
);
1151 Client_Service_Handler client_handler
;
1152 Server_Service_Handler server_handler
;
1153 ACE_Time_Value
wait_time (10, 0);
1155 // Client and Server will utilize different proactors since this test
1156 // depends on SSL thread error state behavior.
1158 CLIENT_PROACTOR_TASK
->activate ();
1159 SERVER_PROACTOR_TASK
->activate ();
1161 // Open server acceptor and client connector
1165 ret
= ACCEPTOR
->open (
1166 ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT
),
1169 ACE_DEFAULT_ASYNCH_BACKLOG
,
1176 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
1177 "ACE_Asynch_Acceptor::open failed, %d\n"), (int)errno
));
1183 ret
= CONNECTOR
->open (0, CLIENT_PROACTOR
, 1);
1187 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
1188 "ACE_Asynch_Connector::open failed, %d\n"), (int)errno
));
1192 // Supply server_handler and client_handler to acceptor and connector and
1193 // connect client to the server.
1197 ACCEPTOR
->prepare_for_connection (&server_handler
);
1198 CONNECTOR
->prepare_for_connection (&client_handler
);
1200 ret
= CONNECTOR
->connect (
1201 ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT
, ACE_LOCALHOST
));
1205 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
1206 "ACE_Asynch_Connector::connect failed, %d\n"), (int)errno
));
1212 ret
= client_handler
.wait_for_external_write_queue (&wait_time
);
1215 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
1216 "Timed out waiting for client's write readiness\n")));
1220 // Client sends data to server
1224 ret
= client_handler
.write_data ();
1227 // Client waits for echo reply from server
1231 ret
= client_handler
.wait_for_read_completed (&wait_time
);
1235 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT (
1236 "Timed out waiting for client's read to complete\n")));
1242 if (client_handler
.read_successful () == 1)
1244 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Success\n")));
1249 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Client's read failed\n")));
1254 // Cleanup and shutdown
1256 ACCEPTOR
->cancel ();
1257 while (!ACCEPTOR
->safe_to_delete ())
1258 ACE_OS::sleep (ACE_Time_Value (0, 500000));
1260 CONNECTOR
->cancel ();
1261 while (!CONNECTOR
->safe_to_delete ())
1262 ACE_OS::sleep (ACE_Time_Value (0, 500000));
1264 client_handler
.cancel_and_close ();
1265 while (!client_handler
.safe_to_delete ())
1266 ACE_OS::sleep (ACE_Time_Value (0, 500000));
1268 server_handler
.cancel_and_close ();
1269 while (!server_handler
.safe_to_delete ())
1270 ACE_OS::sleep (ACE_Time_Value (0, 500000));
1272 CLIENT_PROACTOR
->proactor_end_event_loop ();
1273 CLIENT_PROACTOR_TASK
->wait ();
1275 SERVER_PROACTOR
->proactor_end_event_loop ();
1276 SERVER_PROACTOR_TASK
->wait ();
1285 run_main (int, ACE_TCHAR
*[])
1287 ACE_START_TEST (ACE_TEXT ("Bug_2912_Regression_Test"));
1289 ACE_DEBUG ((LM_INFO
,
1290 ACE_TEXT ("threads or proactor not supported on this platform\n")));
1295 #endif /* ACE_HAS_THREADS && (ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS) && !linux */