1 #include "SSL_Asynch_Stream.h"
3 // This only works on platforms with Asynchronous IO support.
4 #if OPENSSL_VERSION_NUMBER > 0x0090581fL && (defined (ACE_WIN32) || (defined (ACE_HAS_AIO_CALLS)))
6 #if defined (ACE_WIN32)
7 # include "ace/WIN32_Proactor.h"
9 # include "ace/POSIX_Proactor.h"
10 #endif /* ACE_WIN32 */
12 #include "ace/OS_NS_string.h"
13 #include "ace/Proactor.h"
14 #include "ace/Truncate.h"
16 #if !defined(__ACE_INLINE__)
17 #include "SSL_Asynch_Stream.inl"
18 #endif /* __ACE_INLINE__ */
20 #include <openssl/err.h>
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 ACE_SSL_Asynch_Write_Stream_Result::ACE_SSL_Asynch_Write_Stream_Result
25 (ACE_Handler
& handler
,
27 ACE_Message_Block
& message_block
,
28 size_t bytes_to_write
,
34 : AWS_RESULT (handler
.proxy (),
46 ACE_SSL_Asynch_Read_Stream_Result::ACE_SSL_Asynch_Read_Stream_Result
47 (ACE_Handler
& handler
,
49 ACE_Message_Block
& message_block
,
56 : ARS_RESULT (handler
.proxy (),
68 ACE_SSL_Asynch_Result::ACE_SSL_Asynch_Result (ACE_Handler
& handler
)
69 : A_RESULT (handler
.proxy (),
75 ACE_SIGRTMIN
//signal_number
81 ACE_SSL_Asynch_Result::complete (size_t /* bytes_transferred */,
83 const void * /* completion_key */,
86 this->handler_proxy_
->handler ()->handle_wakeup ();
89 // ************************************************************
90 // ACE_SSL_Asynch_Stream Constructor / Destructor
91 // ************************************************************
92 ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream (
93 ACE_SSL_Asynch_Stream::Stream_Type s_type
,
94 ACE_SSL_Context
* context
)
102 handshake_complete_(false),
114 ACE_TRACE ("ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream");
115 // was honestly copied from ACE_SSL_SOCK_Stream :)
117 ACE_SSL_Context
* ctx
=
118 (context
== 0 ? ACE_SSL_Context::instance () : context
);
120 this->ssl_
= ::SSL_new (ctx
->context ());
125 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
126 ACE_TEXT ("- cannot allocate new SSL structure")
130 ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream ()
132 ACE_TRACE ("ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream");
135 // It is safe to delete stream if all notifications are received,
136 // i.e., state is SF_DELETE_ENABLE or if proactor event loop is
138 if (this->flags_
& SF_STREAM_OPEN
) // open
139 if ((this->flags_
& SF_DELETE_ENABLE
) == 0) // but ..
140 ACELIB_DEBUG ((LM_DEBUG
,
141 ACE_TEXT("ACE_SSL_Asynch_Stream::DTOR-")
142 ACE_TEXT("possible access violation ")
143 ACE_TEXT("if proactor still handles events\n")));
145 ::SSL_free (this->ssl_
);
147 // Was honestly copied from ACE_SSL_SOCK_Stream :)
149 // @@ Question: should we reference count the Context object or
150 // leave that to the application developer? We do not reference
151 // count reactors (for example) and following some simple rules
152 // seems to work fine!
155 // ************************************************************
158 // 0 - Stream is in the state SF_DELETE_ENABLE,
159 // so it is safe to delete stream
160 // -1 - Stream has pending AIO requests,
161 // close should be repeated later one more
162 // ************************************************************
165 ACE_SSL_Asynch_Stream::close ()
167 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
, -1));
169 if ((flags_
& SF_STREAM_OPEN
) == 0) // not open
170 flags_
|= SF_DELETE_ENABLE
;
172 if (flags_
& SF_DELETE_ENABLE
)
175 flags_
|= SF_REQ_SHUTDOWN
;
177 this->do_SSL_state_machine ();
182 // ************************************************************
183 // Asynch_Operation interface
185 // ************************************************************
187 ACE_SSL_Asynch_Stream::cancel ()
189 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
, -1));
191 if ((flags_
& SF_STREAM_OPEN
) == 0) // not open
193 return 1; // AIO_ALLDONE
196 // attempt to cancel internal, i.e. user's read/write
197 int rc_r_int
= bio_istream_
.cancel();
198 int rc_w_int
= bio_ostream_
.cancel();
200 // attempt to cancel external, i.e. bio_ssl read/write
201 int rc_r_ext
= notify_read (0, ERR_CANCELED
);
202 int rc_w_ext
= notify_write (0, ERR_CANCELED
);
204 if ((rc_r_int
< 0 || rc_w_int
< 0)
205 && (rc_r_ext
< 0 || rc_w_ext
< 0))
207 return -1; // at least one error
210 if (rc_r_int
== 1 && rc_w_int
== 1
211 && rc_r_ext
== 1 && rc_w_ext
== 1)
213 return 1; // AIO_ALLDONE
216 if ((rc_r_int
== 2 || rc_w_int
== 2)
217 && (rc_r_ext
== 2 || rc_w_ext
== 2))
219 return 2; // AIO_NOT_CANCELED , at least one not canceled
222 return 0; // AIO_CANCELED, at least will be one notification
225 // ************************************************************
226 // Asynch_Operation interface
228 // ************************************************************
230 ACE_SSL_Asynch_Stream::open (ACE_Handler
& handler
,
232 const void * completion_key
,
233 ACE_Proactor
* proactor
)
235 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
, -1));
237 if (this->flags_
& SF_STREAM_OPEN
)
240 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
241 ACE_TEXT ("- already opened")),
247 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
248 ACE_TEXT ("- SSL structure is absent")),
251 if (handle
== ACE_INVALID_HANDLE
)
254 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
255 ACE_TEXT ("- invalid handle")),
258 // Get a proactor for/from the user.
259 this->proactor_
= this->get_proactor (proactor
, handler
);
260 this->ext_handler_
= & handler
;
261 this->handle (handle
);
263 // Open internal input stream
264 if (this->bio_istream_
.open (*this, // real callbacks to this
267 this->proactor_
) != 0)
270 // Open internal output stream
271 if (this->bio_ostream_
.open (*this, // real callbacks to this
274 this->proactor_
) != 0)
277 this->bio_
= ACE_SSL_make_BIO (this);
282 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
283 ACE_TEXT ("- cannot allocate new BIO structure")),
286 ::SSL_set_bio (this->ssl_
, this->bio_
, this->bio_
);
291 ::SSL_set_connect_state (this->ssl_
);
295 ::SSL_set_accept_state (this->ssl_
);
301 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"),
302 ACE_TEXT ("- invalid stream type")),
306 this->flags_
|= SF_STREAM_OPEN
;
308 this->do_SSL_state_machine ();
314 // ************************************************************
315 // Asynch_Operation interface
317 // ************************************************************
319 ACE_SSL_Asynch_Stream::read (ACE_Message_Block
& message_block
,
320 size_t bytes_to_read
,
325 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
, -1));
327 if ((this->flags_
& SF_STREAM_OPEN
) == 0) // not open
330 if (this->flags_
& SF_REQ_SHUTDOWN
)
333 // only one read operation is allowed now
334 // later it will be possible to make a queue
336 if (this->ext_read_result_
!= 0)
339 // create result for future notification
340 ACE_NEW_RETURN (this->ext_read_result_
,
341 ACE_SSL_Asynch_Read_Stream_Result (
347 this->proactor_
->get_handle(),
352 this->do_SSL_state_machine (); // ignore return code
357 // ************************************************************
358 // Asynch_Operation interface
360 // ************************************************************
362 ACE_SSL_Asynch_Stream::write (ACE_Message_Block
& message_block
,
363 size_t bytes_to_write
,
368 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
, -1));
370 if ((this->flags_
& SF_STREAM_OPEN
) == 0) // not open
373 if (this->flags_
& SF_REQ_SHUTDOWN
)
376 // only one read operation is allowed now
377 // later it will be possible to make a queue
379 if (this->ext_write_result_
!= 0)
382 // create result for future notification
383 ACE_NEW_RETURN (this->ext_write_result_
,
384 ACE_SSL_Asynch_Write_Stream_Result (
390 this->proactor_
->get_handle(),
395 this->do_SSL_state_machine ();
400 // ************************************************************
402 // ************************************************************
404 ACE_SSL_Asynch_Stream::do_SSL_state_machine ()
406 // this protected member should be called
407 // with locked mutex_
408 int const retval
= this->do_SSL_handshake ();
410 if (retval
== 0) // handshake in progress ?
414 this->flags_
|= SF_REQ_SHUTDOWN
;
416 this->do_SSL_read (); // execute user read request
417 this->do_SSL_write (); // execute user write request
419 if ((this->flags_
& SF_REQ_SHUTDOWN
) == 0) // Do we have any errors
422 this->do_SSL_shutdown ();
424 this->notify_close ();
429 // ************************************************************
432 // 1 SSL shutdown is finished already, success
433 // 0 SSL shutdown in progress
435 // ************************************************************
437 ACE_SSL_Asynch_Stream::do_SSL_shutdown ()
439 if (this->flags_
& SF_SHUTDOWN_DONE
) // already done
442 this->flags_
|= SF_REQ_SHUTDOWN
;
444 // if we have any uncompleted user requests
446 this->notify_read (0, ERR_CANCELED
);
447 this->notify_write (0, ERR_CANCELED
);
449 int retval
= ::SSL_shutdown (this->ssl_
);
451 int const status
= ::SSL_get_error (this->ssl_
, retval
);
456 case SSL_ERROR_ZERO_RETURN
:
457 case SSL_ERROR_SYSCALL
:
461 case SSL_ERROR_WANT_READ
:
462 case SSL_ERROR_WANT_WRITE
:
463 case SSL_ERROR_WANT_CONNECT
:
464 // case SSL_ERROR_WANT_ACCEPT:
465 case SSL_ERROR_WANT_X509_LOOKUP
:
469 this->print_error (status
,
470 ACE_TEXT ("Shutdown error"));
475 this->flags_
|= SF_SHUTDOWN_DONE
;
480 // ************************************************************
481 // Do SSL handshake if necessary
483 // 1 SSL handshake is finished already, success
484 // 0 SSL handshake in progress
486 // ************************************************************
488 ACE_SSL_Asynch_Stream::do_SSL_handshake ()
490 if (SSL_is_init_finished (this->ssl_
))
492 if (!handshake_complete_
)
494 handshake_complete_
= true;
496 if (!post_handshake_check ())
504 if (this->flags_
& SF_REQ_SHUTDOWN
)
512 retval
= ::SSL_connect (this->ssl_
);
516 retval
= ::SSL_accept (this->ssl_
);
522 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
523 ACE_TEXT ("- invalid stream type")),
527 int const status
= ::SSL_get_error (this->ssl_
, retval
);
534 case SSL_ERROR_WANT_READ
:
535 case SSL_ERROR_WANT_WRITE
:
536 case SSL_ERROR_WANT_CONNECT
:
537 //case SSL_ERROR_WANT_ACCEPT:
538 case SSL_ERROR_WANT_X509_LOOKUP
:
541 case SSL_ERROR_ZERO_RETURN
:
542 case SSL_ERROR_SYSCALL
:
544 this->print_error (status
,
545 ACE_TEXT ("Handshake error"));
553 ACE_SSL_Asynch_Stream::post_handshake_check ()
558 // ************************************************************
559 // Perform SSL_read call if necessary and notify user
560 // ************************************************************
562 ACE_SSL_Asynch_Stream::do_SSL_read ()
564 if (this->ext_read_result_
== 0) // nothing to do
569 if (this->flags_
& SF_REQ_SHUTDOWN
)
571 this->notify_read (0, ERR_CANCELED
);
575 ACE_Message_Block
& mb
= this->ext_read_result_
->message_block ();
576 size_t bytes_req
= this->ext_read_result_
->bytes_to_read ();
580 const int bytes_trn
=
581 ::SSL_read (this->ssl_
,
583 ACE_Utils::truncate_cast
<int> (bytes_req
));
585 int const status
= ::SSL_get_error (this->ssl_
, bytes_trn
);
590 this->notify_read (bytes_trn
, 0);
593 case SSL_ERROR_WANT_READ
:
594 case SSL_ERROR_WANT_WRITE
:
597 case SSL_ERROR_ZERO_RETURN
:
598 this->notify_read (0, 0);
601 case SSL_ERROR_SYSCALL
:
604 this->notify_read (0, 0);
607 // If not an EOF, then fall through to "default" case.
613 this->notify_read (0, EFAULT
);
614 this->print_error (status
,
615 ACE_TEXT ("SSL_read error"));
620 // ************************************************************
621 // Perform SSL_write call if necessary and notify user
622 // ************************************************************
624 ACE_SSL_Asynch_Stream::do_SSL_write ()
626 if (this->ext_write_result_
== 0) // nothing to do
631 if (this->flags_
& SF_REQ_SHUTDOWN
)
633 this->notify_write (0, ERR_CANCELED
);
637 ACE_Message_Block
& mb
= this->ext_write_result_
->message_block ();
638 size_t bytes_req
= this->ext_write_result_
->bytes_to_write ();
642 const int bytes_trn
=
643 ::SSL_write (this->ssl_
,
645 ACE_Utils::truncate_cast
<int> (bytes_req
));
647 int const status
= ::SSL_get_error (this->ssl_
, bytes_trn
);
652 this->notify_write (bytes_trn
, 0);
655 case SSL_ERROR_WANT_READ
:
656 case SSL_ERROR_WANT_WRITE
:
659 case SSL_ERROR_ZERO_RETURN
:
660 this->notify_write (bytes_trn
, 0);
663 case SSL_ERROR_SYSCALL
:
668 this->notify_write(0, EFAULT
);
669 this->print_error (status
,
670 ACE_TEXT ("SSL_write error"));
675 // ************************************************************
676 // notify external user handler that
677 // it is now to safe destroy stream
678 // Return code looks like cancel() return code
679 // 0 - notified NOTIFIED
680 // 1 - nothing to notify ALLDONE
681 // 2 - unable to notify NOT NOTIFIED
682 // ************************************************************
684 ACE_SSL_Asynch_Stream::notify_close ()
686 if (this->flags_
& SF_CLOSE_NTF_SENT
) // already sent
689 if ((this->flags_
& SF_SHUTDOWN_DONE
) == 0) // only after shutdown
690 return 2; // too early , we will do later
692 if (this->pending_BIO_count () != 0) // wait for all internal IO
693 return 2; // too early , we will do later
695 // create result for future notification
696 ACE_SSL_Asynch_Result
* close_result
= 0;
698 ACE_NEW_RETURN (close_result
,
699 ACE_SSL_Asynch_Result (*this),
701 //@@ Not exception safe!
704 close_result
->post_completion (this->proactor_
->implementation ());
708 this->flags_
|= SF_CLOSE_NTF_SENT
;
716 // ************************************************************
717 // notify external user handler about user write completion
718 // Return code looks like cancel() return code
719 // 0 - notified NOTIFIED/CANCELED
720 // 1 - nothing to notify ALLDONE
721 // 2 - unable to notify NOT NOTIFIED/CANCELED
722 // ************************************************************
725 ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred
,
728 if (ext_read_result_
== 0) //nothing to notify
731 this->ext_read_result_
->set_bytes_transferred (bytes_transferred
);
732 this->ext_read_result_
->set_error (error
);
735 this->ext_read_result_
->post_completion (proactor_
->implementation ());
739 this->ext_read_result_
= 0;
743 return 2; // unable to notify
746 // ************************************************************
747 // notify external user handler about user write completion
748 // Return code looks like cancel() return code
749 // 0 - notified NOTIFIED/CANCELED
750 // 1 - nothing to notify ALLDONE
751 // 2 - unable to notify NOT NOTIFIED/CANCELED
752 // ************************************************************
755 ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred
,
758 if (this->ext_write_result_
== 0) //nothing to notify
761 this->ext_write_result_
->set_bytes_transferred (bytes_transferred
);
762 this->ext_write_result_
->set_error (error
);
765 this->ext_write_result_
->post_completion (
766 this->proactor_
->implementation ());
770 this->ext_write_result_
= 0;
774 return 2; // unable to notify
777 // ************************************************************
779 // ************************************************************
781 ACE_SSL_Asynch_Stream::print_error (int err_ssl
,
782 const ACE_TCHAR
* pText
)
784 ACELIB_DEBUG ((LM_DEBUG
,
785 ACE_TEXT("SSL-error:%d %s\n"),
789 #if OPENSSL_VERSION_NUMBER >= 0x0090601fL
790 // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function.
791 unsigned long lerr
= 0;
794 while ((lerr
= ERR_get_error()) != 0)
796 ERR_error_string_n (lerr
, buf
, sizeof buf
);
798 ACELIB_DEBUG ((LM_DEBUG
, "%C\n", buf
));
800 #endif /* OPENSSL_VERSION_NUMBER */
803 // ************************************************************
804 // BIO helper functions
805 // SSL library will ask BIO to do raw I/O
806 // BIO will call us to do this
807 // ************************************************************
809 ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf
,
813 // We do not have to acquire mutex
814 // as we called already with locked mutex
815 // from do_SSL_state_machine()
819 size_t cur_len
= this->bio_inp_msg_
.length ();
821 if (cur_len
> 0) // there are more data buffered
823 const char * rd_ptr
= this->bio_inp_msg_
.rd_ptr ();
830 ACE_OS::memcpy (buf
, rd_ptr
, cur_len
);
832 this->bio_inp_msg_
.rd_ptr (cur_len
); // go ahead
834 return ACE_Utils::truncate_cast
<int> (cur_len
);
837 if (this->bio_inp_errno_
!= 0) // if was error - it is permanent !
839 errval
= this->bio_inp_errno_
;
843 if (this->bio_inp_flag_
& BF_EOS
) // End of stream
848 errval
= EINPROGRESS
; // SSL will try later
850 if (this->bio_inp_flag_
& BF_AIO
) // we are busy
855 if (this->bio_inp_msg_
.size (len
) != 0)
859 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
860 ACE_TEXT ("error in ACE_Message_Block::size() ")
867 char * base
= this->bio_inp_msg_
.base ();
869 this->bio_inp_msg_
.rd_ptr (base
);
870 this->bio_inp_msg_
.wr_ptr (base
);
872 if (this->bio_istream_
.read (
873 bio_inp_msg_
, // message block
877 ACE_SIGRTMIN
// default signal
882 ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"),
883 ACE_TEXT ("attempt read failed")
886 errval
= EINVAL
; // may be leave EINPROGRESS ??
887 return -1; // to try later
890 this->bio_inp_flag_
|= BF_AIO
; // AIO is active
897 ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf
,
901 // We do not have to acquire mutex
902 // as we called already with locked mutex
903 // from do_SSL_state_machine
907 if (this->bio_out_flag_
& BF_AIO
) // sorry, we are busy
909 errval
= EINPROGRESS
; // try later
913 if (this->bio_out_errno_
!= 0) // no recovery
915 errval
= this->bio_out_errno_
;
919 if (this->bio_out_msg_
.size (len
) != 0)
923 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
924 ACE_TEXT ("error in ACE_Message_Block::size() ")
931 char * base
= this->bio_out_msg_
.base ();
933 this->bio_out_msg_
.rd_ptr (base
);
934 this->bio_out_msg_
.wr_ptr (base
);
936 if (this->bio_out_msg_
.copy (buf
, len
) == -1)
940 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
941 ACE_TEXT ("error in ACE_Message_Block::copy() ")
949 if (this->bio_ostream_
.write (
950 this->bio_out_msg_
, // message block
954 ACE_SIGRTMIN
// default signal
959 ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"),
960 ACE_TEXT ("attempt write failed")
963 errval
= EINVAL
; // may be leave EINPROGRESS ??
964 return -1; // to try later
967 this->bio_out_flag_
|= BF_AIO
; // AIO is active
968 errval
= 0; // Ok, go ahead
970 return ACE_Utils::truncate_cast
<int> (len
);
973 // ************************************************************
974 // Internal IO handlers
975 // virtual from ACE_Service_Handler
976 // ************************************************************
978 ACE_SSL_Asynch_Stream::handle_write_stream (
979 const ACE_Asynch_Write_Stream::Result
&result
)
981 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
));
983 this->bio_out_flag_
&= ~BF_AIO
;
985 ACE_Message_Block
& mb
= result
.message_block ();
987 size_t bytes_req
= result
.bytes_to_write ();
988 size_t bytes_trn
= result
.bytes_transferred ();
989 u_long errval
= result
.error ();
990 size_t len
= bytes_req
- bytes_trn
;
992 if (errval
!= 0) // error ?
993 this->bio_out_errno_
= errval
; // save err code
994 else if (len
> 0) // TCP/IP overloaded ?
995 { // continue, rd_ptr at right place
996 if (this->bio_ostream_
.write (
1001 ACE_SIGRTMIN
// default signal
1004 this->bio_out_flag_
|= BF_AIO
;
1010 ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"),
1011 ACE_TEXT ("attempt write failed")
1014 this->bio_out_errno_
= EINVAL
;
1017 this->do_SSL_state_machine ();
1023 ACE_SSL_Asynch_Stream::handle_read_stream (
1024 const ACE_Asynch_Read_Stream::Result
&result
)
1026 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
));
1028 this->bio_inp_flag_
&= ~BF_AIO
;
1030 size_t bytes_trn
= result
.bytes_transferred ();
1031 u_long errval
= result
.error ();
1033 if (errval
!= 0) // error ?
1034 this->bio_inp_errno_
= errval
; // save err code
1035 else if (bytes_trn
== 0) // end of stream ?
1036 this->bio_inp_flag_
|= BF_EOS
; // set flag EOS
1038 this->do_SSL_state_machine ();
1044 ACE_SSL_Asynch_Stream::handle_wakeup ()
1046 ACE_Handler
* user_handler
= 0;
1049 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX
, ace_mon
, this->mutex_
));
1051 this->flags_
|= SF_DELETE_ENABLE
;
1053 user_handler
= this->ext_handler_
;
1056 if (user_handler
!= 0)
1057 user_handler
->handle_wakeup();
1061 ACE_SSL_Asynch_Stream::pending_BIO_count ()
1065 if (this->bio_inp_flag_
& BF_AIO
)
1068 if (this->bio_out_flag_
& BF_AIO
)
1074 ACE_END_VERSIONED_NAMESPACE_DECL
1076 #endif /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
1077 ACE_HAS_AIO_CALLS) */