@@ -412,6 +412,9 @@ private X509Certificate2 makeCertificate(string certificateName, bool isRootCert
412412 return certificate ;
413413 }
414414
415+ private static ConcurrentDictionary < string , object > saveCertificateLocks
416+ = new ConcurrentDictionary < string , object > ( ) ;
417+
415418 /// <summary>
416419 /// Create an SSL certificate
417420 /// </summary>
@@ -445,7 +448,21 @@ private X509Certificate2 makeCertificate(string certificateName, bool isRootCert
445448
446449 try
447450 {
448- certificateCache . SaveCertificate ( subjectName , certificate ) ;
451+ //acquire lock by subjectName
452+ //Async lock is not needed. Since this is a rare race-condition
453+ lock ( saveCertificateLocks . GetOrAdd ( subjectName , new object ( ) ) )
454+ {
455+ try
456+ {
457+ //no two tasks with same subject name should together enter here
458+ certificateCache . SaveCertificate ( subjectName , certificate ) ;
459+ }
460+ finally
461+ {
462+ //save operation is complete. Free lock from memory.
463+ saveCertificateLocks . TryRemove ( subjectName , out var _ ) ;
464+ }
465+ }
449466 }
450467 catch ( Exception e )
451468 {
@@ -482,13 +499,17 @@ private X509Certificate2 makeCertificate(string certificateName, bool isRootCert
482499 }
483500
484501 // handle burst requests with same certificate name
485- // by checking for existing task for same certificate name
502+ // by checking for existing task for same certificate name.
503+ // If two or more requests hit this block at the same time, then multiple tasks will be created,
504+ // which is okay. That certificate will be created twice or more. We don't anticipate many requests for same host at the same time.
505+ // This saves us from another expensive lock. The goal here is to minimize creation of multiple tasks for same certification name.
506+ // Goal is not to guarantee single certificate creation, which is not needed in our case.
486507 if ( pendingCertificateCreationTasks . TryGetValue ( certificateName , out var task ) )
487508 {
488509 return await task ;
489510 }
490511
491- // run certificate creation task & add it to pending tasks
512+ // run certificate creation task & add it to pending tasks
492513 task = Task . Run ( ( ) =>
493514 {
494515 var result = CreateCertificate ( certificateName , false ) ;
0 commit comments