VirtualBox

Changeset 100884 in vbox for trunk/src/libs


Ignore:
Timestamp:
Aug 16, 2023 2:57:08 PM (16 months ago)
Author:
vboxsync
Message:

openssl-3.1.0: Implemented CRYPTO_THREAD_run_once. Added an alternative lock implementation using proper R/W locks, but leaving it disabled as I don't want to test it and it may have questionable performance due to the unlock function. Misc style cleanups. All changes are untested. bugref:10418

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/openssl-3.1.0/crypto/threads_iprt.c

    r100882 r100884  
    11/* $Id$ */
    22/** @file
    3  * Crypto thread locking functions which make use of the IPRT.
     3 * Crypto threading and atomic functions built upon IPRT.
    44 */
    55
     
    3131#if defined(OPENSSL_THREADS)
    3232
    33 #include <iprt/asm.h>
    34 #include <iprt/assert.h>
    35 #include <iprt/critsect.h>
    36 #include <iprt/errcore.h>
    37 #include <iprt/log.h>
    38 #include <iprt/process.h>
    39 
     33# include <iprt/asm.h>
     34# include <iprt/assert.h>
     35# include <iprt/critsect.h>
     36# include <iprt/errcore.h>
     37# include <iprt/log.h>
     38# include <iprt/process.h>
     39
     40/* Use read/write sections. */
     41/*# define USE_RW_CRITSECT */ /** @todo test the code */
     42
     43# ifndef USE_RW_CRITSECT
    4044/*
    4145 * Of course it's wrong to use a critical section to implement a read/write
     
    4448 * (threads_win.c) uses {Enter,Leave}CriticalSection we do that here as well.
    4549 */
     50# endif
     51
    4652CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
    4753{
    48     RTCRITSECT *pCritSect = (RTCRITSECT*)OPENSSL_zalloc(sizeof(RTCRITSECT));
     54# ifdef USE_RW_CRITSECT
     55    PRTCRITSECTRW const pCritSect = (PRTCRITSECTRW)OPENSSL_zalloc(sizeof(*pCritSect));
     56# else
     57    PRTCRITSECT const pCritSect = (PRTCRITSECT)OPENSSL_zalloc(sizeof(*pCritSect));
     58# endif
    4959    if (pCritSect)
    5060    {
    51         int rc = RTCritSectInitEx(pCritSect, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
     61# ifdef USE_RW_CRITSECT
     62        int const rc = RTCritSectRwInitEx(pCritSect, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
     63# else
     64        int const rc = RTCritSectInitEx(pCritSect, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
     65# endif
    5266        if (RT_SUCCESS(rc))
    53             return (CRYPTO_RWLOCK*)pCritSect;
    54             OPENSSL_free(pCritSect);
     67            return (CRYPTO_RWLOCK *)pCritSect;
     68        OPENSSL_free(pCritSect);
    5569    }
    5670    return NULL;
     
    5973int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
    6074{
    61     PRTCRITSECT pCritSect = (PRTCRITSECT)lock;
    62     int rc = RTCritSectEnter(pCritSect);
    63     AssertRC(rc);
    64     if (RT_FAILURE(rc))
    65         return 0;
    66 
     75# ifdef USE_RW_CRITSECT
     76    PRTCRITSECTRW const pCritSect = (PRTCRITSECTRW)lock;
     77    int rc;
     78
     79    /* writers cannot acquire read locks the way CRYPTO_THREAD_unlock works
     80       right now. It's also looks incompatible with pthread_rwlock_rdlock,
     81       so this should never trigger. */
     82    Assert(!RTCritSectRwIsWriteOwner(pCritSect));
     83
     84    rc = RTCritSectRwEnterShared(pCritSect);
     85# else
     86    int const rc = RTCritSectEnter((PRTCRITSECT)lock);
     87# endif
     88    AssertRCReturn(rc, 0);
    6789    return 1;
    6890}
     
    7092int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
    7193{
    72     PRTCRITSECT pCritSect = (PRTCRITSECT)lock;
    73     int rc = RTCritSectEnter(pCritSect);
    74     AssertRC(rc);
    75     if (RT_FAILURE(rc))
    76         return 0;
    77 
     94# ifdef USE_RW_CRITSECT
     95    int const rc = RTCritSectRwEnterExcl((PRTCRITSECTRW)lock);
     96# else
     97    int const rc = RTCritSectEnter((PRTCRITSECT)lock);
     98# endif
     99    AssertRCReturn(rc, 0);
    78100    return 1;
    79101}
     
    81103int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
    82104{
    83     PRTCRITSECT pCritSect = (PRTCRITSECT)lock;
    84     int rc = RTCritSectLeave(pCritSect);
    85     AssertRC(rc);
    86     if (RT_FAILURE(rc))
    87         return 0;
    88 
     105# ifdef USE_RW_CRITSECT
     106    PRTCRITSECTRW const pCritSect = (PRTCRITSECTRW)lock;
     107    if (RTCritSectRwIsWriteOwner(pCritSect))
     108    {
     109        int const rc1 = RTCritSectRwLeaveExcl(pCritSect);
     110        AssertRCReturn(rc1, 0);
     111    }
     112    else
     113    {
     114        int const rc2 = RTCritSectRwLeaveShared(pCritSect);
     115        AssertRCReturn(rc2, 0);
     116    }
     117# else
     118    int const rc = RTCritSectLeave((PRTCRITSECT)lock);
     119    AssertRCReturn(rc, 0);
     120# endif
    89121    return 1;
    90122}
     
    94126    if (lock)
    95127    {
    96         PRTCRITSECT pCritSect = (PRTCRITSECT)lock;
    97         int rc = RTCritSectDelete(pCritSect);
     128# ifdef USE_RW_CRITSECT
     129        PRTCRITSECTRW const pCritSect = (PRTCRITSECTRW)lock;
     130        int const rc = RTCritSectRwDelete(pCritSect);
     131# else
     132        PRTCRITSECT const pCritSect = (PRTCRITSECT)lock;
     133        int const rc = RTCritSectDelete(pCritSect);
     134# endif
    98135        AssertRC(rc);
    99         OPENSSL_free(lock);
     136        OPENSSL_free(pCritSect);
    100137    }
    101138}
     
    104141{
    105142    int rc = RTTlsAllocEx(key, (PFNRTTLSDTOR)cleanup); /* ASSUMES default calling convention is __cdecl, or close enough to it. */
    106     if (RT_FAILURE(rc))
    107         return 0;
    108 
     143    AssertRCReturn(rc, 0);
    109144    return 1;
    110145}
     
    118153{
    119154    int rc = RTTlsSet(*key, val);
    120     if (RT_FAILURE(rc))
    121         return 0;
    122 
     155    AssertRCReturn(rc, 0);
    123156    return 1;
    124157}
     
    127160{
    128161    int rc = RTTlsFree(*key);
    129     if (RT_FAILURE(rc))
    130         return 0;
    131 
     162    AssertRCReturn(rc, 0);
    132163    return 1;
    133164}
     
    143174}
    144175
     176/** @callback_method_impl{FNRTONCE,
     177 * Wrapper that calls the @a init function given CRYPTO_THREAD_run_once().}
     178 */
     179static int32_t cryptoThreadRunOnceWrapper(void *pvUser)
     180{
     181    void (*pfnInit)(void) = (void (*)(void))pvUser;
     182    pfnInit();
     183    return VINF_SUCCESS;
     184}
     185
    145186int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
    146187{
    147 /** @todo Implement function */
    148 /*    if (*once != 0)
    149         return 1;
    150 
    151     init();
    152     *once = 1;
    153 */
     188    int rc = RTOnce(once, cryptoThreadRunOnceWrapper, (void *)(uintptr_t)init);
     189    AssertRCReturn(rc, 0);
    154190    return 1;
    155191}
     
    180216}
    181217
    182 #endif
     218#endif /* defined(OPENSSL_THREADS) */
    183219
    184220int openssl_init_fork_handlers(void)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette