PORT_Assert( ssl_Have1stHandshakeLock(ss) ); PORT_Assert( !ssl_HaveRecvBufLock(ss)   ); PORT_Assert( !ssl_HaveXmitBufLock(ss)   );
PORT_Assert(ss->opt.noLocks ||  ssl_Have1stHandshakeLock(ss) ); PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
ssl_Do1stHandshake(sslSocket *ss){    int rv        = SECSuccess;    int loopCount = 0;    do {	PORT_Assert( ssl_Have1stHandshakeLock(ss) );	PORT_Assert( !ssl_HaveRecvBufLock(ss)   );	PORT_Assert( !ssl_HaveXmitBufLock(ss)   );	if (ss->handshake == 0) {	    /* Previous handshake finished. Switch to next one */	    ss->handshake = ss->nextHandshake;	    ss->nextHandshake = 0;	}	if (ss->handshake == 0) {	    /* Previous handshake finished. Switch to security handshake */	    ss->handshake = ss->securityHandshake;	    ss->securityHandshake = 0;	}	if (ss->handshake == 0) {	    ssl_GetRecvBufLock(ss);	    ss->gs.recordLen = 0;	    ssl_ReleaseRecvBufLock(ss);	    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",			SSL_GETPID(), ss->fd));            /* call handshake callback for ssl v2 */	    /* for v3 this is done in ssl3_HandleFinished() */	    if ((ss->handshakeCallback != NULL) && /* has callback */		(!ss->firstHsDone) &&              /* only first time */		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */		ss->firstHsDone     = PR_TRUE;		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);	    }	    ss->firstHsDone         = PR_TRUE;	    ss->gs.writeOffset = 0;	    ss->gs.readOffset  = 0;	    break;	}	rv = (*ss->handshake)(ss);	++loopCount;    /* This code must continue to loop on SECWouldBlock,      * or any positive value.	See XXX_1 comments.     */    } while (rv != SECFailure);  	/* was (rv >= 0); XXX_1 */    PORT_Assert( !ssl_HaveRecvBufLock(ss)   );    PORT_Assert( !ssl_HaveXmitBufLock(ss)   );    if (rv == SECWouldBlock) {	PORT_SetError(PR_WOULD_BLOCK_ERROR);	rv = SECFailure;    }    return rv;}