bn_mont.c (256281) | bn_mont.c (267258) |
---|---|
1/* crypto/bn/bn_mont.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * --- 464 unchanged lines hidden (view full) --- 473 to->n0[0]=from->n0[0]; 474 to->n0[1]=from->n0[1]; 475 return(to); 476 } 477 478BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, 479 const BIGNUM *mod, BN_CTX *ctx) 480 { | 1/* crypto/bn/bn_mont.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * --- 464 unchanged lines hidden (view full) --- 473 to->n0[0]=from->n0[0]; 474 to->n0[1]=from->n0[1]; 475 return(to); 476 } 477 478BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, 479 const BIGNUM *mod, BN_CTX *ctx) 480 { |
481 int got_write_lock = 0; | |
482 BN_MONT_CTX *ret; 483 484 CRYPTO_r_lock(lock); | 481 BN_MONT_CTX *ret; 482 483 CRYPTO_r_lock(lock); |
485 if (!*pmont) | 484 ret = *pmont; 485 CRYPTO_r_unlock(lock); 486 if (ret) 487 return ret; 488 489 /* We don't want to serialise globally while doing our lazy-init math in 490 * BN_MONT_CTX_set. That punishes threads that are doing independent 491 * things. Instead, punish the case where more than one thread tries to 492 * lazy-init the same 'pmont', by having each do the lazy-init math work 493 * independently and only use the one from the thread that wins the race 494 * (the losers throw away the work they've done). */ 495 ret = BN_MONT_CTX_new(); 496 if (!ret) 497 return NULL; 498 if (!BN_MONT_CTX_set(ret, mod, ctx)) |
486 { | 499 { |
487 CRYPTO_r_unlock(lock); 488 CRYPTO_w_lock(lock); 489 got_write_lock = 1; | 500 BN_MONT_CTX_free(ret); 501 return NULL; 502 } |
490 | 503 |
491 if (!*pmont) 492 { 493 ret = BN_MONT_CTX_new(); 494 if (ret && !BN_MONT_CTX_set(ret, mod, ctx)) 495 BN_MONT_CTX_free(ret); 496 else 497 *pmont = ret; 498 } | 504 /* The locked compare-and-set, after the local work is done. */ 505 CRYPTO_w_lock(lock); 506 if (*pmont) 507 { 508 BN_MONT_CTX_free(ret); 509 ret = *pmont; |
499 } | 510 } |
500 501 ret = *pmont; 502 503 if (got_write_lock) 504 CRYPTO_w_unlock(lock); | |
505 else | 511 else |
506 CRYPTO_r_unlock(lock); 507 | 512 *pmont = ret; 513 CRYPTO_w_unlock(lock); |
508 return ret; 509 } | 514 return ret; 515 } |