reap_threads();
PR_Lock( stopLock ); while ( !stopping && threadCount > 0 ) { PR_WaitCondVar(stopQ, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock( stopLock );
server_main(    unsigned short      port,     int                 requestCert,     SECKEYPrivateKey ** privKey,    CERTCertificate **  cert){    PRFileDesc *listen_sock;    PRFileDesc *model_sock	= NULL;    int         rv;    SSLKEAType  kea;    PRNetAddr   addr;    SECStatus	secStatus;    PRSocketOptionData opt;    networkStart();    addr.inet.family = PR_AF_INET;    addr.inet.ip     = PR_INADDR_ANY;    addr.inet.port   = PR_htons(port);    /* all suites except RSA_NULL_MD5 are enabled by default */    listen_sock = PR_NewTCPSocket();    if (listen_sock == NULL) {	errExit("PR_NewTCPSocket");    }    opt.option = PR_SockOpt_Nonblocking;    opt.value.non_blocking = PR_FALSE;    PR_SetSocketOption(listen_sock, &opt);    opt.option=PR_SockOpt_Reuseaddr;    opt.value.reuse_addr = PR_TRUE;    PR_SetSocketOption(listen_sock, &opt);    if (useModelSocket) {    	model_sock = PR_NewTCPSocket();	if (model_sock == NULL) {	    errExit("PR_NewTCPSocket on model socket");	}	model_sock = SSL_ImportFD(NULL, model_sock);	if (model_sock == NULL) {	    errExit("SSL_ImportFD");	}    } else {	model_sock = listen_sock = SSL_ImportFD(NULL, listen_sock);	if (listen_sock == NULL) {	    errExit("SSL_ImportFD");	}    }    /* do SSL configuration. */#if 0    /* This is supposed to be true by default.    ** Setting it explicitly should not be necessary.    ** Let's test and make sure that's true.    */    rv = SSL_Enable(model_sock, SSL_SECURITY, 1);    if (rv < 0) {	errExit("SSL_Enable SSL_SECURITY");    }#endif    rv = SSL_Enable(model_sock, SSL_ENABLE_SSL3, !disableSSL3);    if (rv != SECSuccess) {	errExit("error enabling SSLv3 ");    }    rv = SSL_Enable(model_sock, SSL_ENABLE_TLS, !disableTLS);    if (rv != SECSuccess) {	errExit("error enabling TLS ");    }    rv = SSL_Enable(model_sock, SSL_ROLLBACK_DETECTION, !disableRollBack);    if (rv != SECSuccess) {	errExit("error enabling RollBack detection ");    }    for (kea = kt_rsa; kea < kt_kea_size; kea++) {	if (cert[kea] != NULL) {	    secStatus = SSL_ConfigSecureServer(model_sock, 	    		cert[kea], privKey[kea], kea);	    if (secStatus != SECSuccess)		errExit("SSL_ConfigSecureServer");	}    }    if (bigBuf.data) { /* doing FDX */	rv = SSL_Enable(model_sock, SSL_ENABLE_FDX, 1);	if (rv < 0) {	    errExit("SSL_Enable SSL_ENABLE_FDX");	}    }    /* This cipher is not on by default. The Acceptance test     * would like it to be. Turn this cipher on.     */    secStatus = SSL_EnableCipher( SSL_RSA_WITH_NULL_MD5, PR_TRUE);    if ( secStatus != SECSuccess ) {	errExit("SSL_EnableCipher:SSL_RSA_WITH_NULL_MD5");    }    if (requestCert) {	SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, 	                        (void *)CERT_GetDefaultCertDB());	if (requestCert <= 2) { 	    rv = SSL_Enable(model_sock, SSL_REQUEST_CERTIFICATE, 1);	    if (rv < 0) {		errExit("first SSL_Enable SSL_REQUEST_CERTIFICATE");	    }	    rv = SSL_Enable(model_sock, SSL_REQUIRE_CERTIFICATE, 	                    (requestCert == 2));	    if (rv < 0) {		errExit("first SSL_Enable SSL_REQUIRE_CERTIFICATE");	    }	}    }    /* end of ssl configuration. */    rv = PR_Bind(listen_sock, &addr);    if (rv < 0) {	errExit("PR_Bind");    }    rv = PR_Listen(listen_sock, 5);    if (rv < 0) {	errExit("PR_Listen");    }    rv = launch_thread(do_accepts, listen_sock, model_sock, requestCert);    if (rv != SECSuccess) {    	PR_Close(listen_sock);    } else {	reap_threads();	destroy_thread_data();    }    if (useModelSocket && model_sock) {    	PR_Close(model_sock);    }    networkEnd();}