static pj_status_t ssl_do_handshake(pj_ssl_sock_t *ssock)
{
    ossl_sock_t *ossock = (ossl_sock_t *)ssock;
    pj_status_t status;
    int err;

    /* Perform SSL handshake */
    pj_lock_acquire(ssock->write_mutex);
    err = SSL_do_handshake(ossock->ossl_ssl);
    pj_lock_release(ssock->write_mutex);

    /* SSL_do_handshake() may put some pending data into SSL write BIO, 
     * flush it if any.
     */
    status = flush_circ_buf_output(ssock, &ssock->handshake_op_key, 0, 0);
    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	return status;
    }

    if (err < 0) {
	int err2 = SSL_get_error(ossock->ossl_ssl, err);
	if (err2 != SSL_ERROR_NONE && err2 != SSL_ERROR_WANT_READ)
	{
	    /* Handshake fails */
	    status = STATUS_FROM_SSL_ERR2("Handshake", ssock, err, err2, 0);
	    return status;
	}
    }

    /* Check if handshake has been completed */
    if (SSL_is_init_finished(ossock->ossl_ssl)) {
	ssock->ssl_state = SSL_STATE_ESTABLISHED;
	return PJ_SUCCESS;
    }

    return PJ_EPENDING;
}
static pj_status_t ssl_do_handshake(pj_ssl_sock_t *ssock)
{
    ossl_sock_t *ossock = (ossl_sock_t *)ssock;
    pj_status_t status;
    int err;

     
    pj_lock_acquire(ssock->write_mutex);
    err = SSL_do_handshake(ossock->ossl_ssl);
    pj_lock_release(ssock->write_mutex);

     
    status = flush_circ_buf_output(ssock, &ssock->handshake_op_key, 0, 0);
    if (status != PJ_SUCCESS && status != PJ_EPENDING) {
	return status;
    }

    if (err < 0) {
	int err2 = SSL_get_error(ossock->ossl_ssl, err);
	if (err2 != SSL_ERROR_NONE && err2 != SSL_ERROR_WANT_READ)
	{
	     
	    status = STATUS_FROM_SSL_ERR2("Handshake", ssock, err, err2, 0);
	    return status;
	}
    }

     
    if (SSL_is_init_finished(ossock->ossl_ssl)) {
	ssock->ssl_state = SSL_STATE_ESTABLISHED;
	return PJ_SUCCESS;
    }

    return PJ_EPENDING;
}