VirtualBox

Changeset 69433 in vbox


Ignore:
Timestamp:
Oct 27, 2017 2:49:11 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
118768
Message:

scm: Reuse the subversion client context and pool, the former is very expensive to create.

Location:
trunk/src/bldprogs
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/scm.cpp

    r69432 r69433  
    22922292    rc = RTGetOptInit(&GetOptState, argc, argv, &s_aOpts[0], RT_ELEMENTS(s_aOpts), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    22932293    AssertReleaseRCReturn(rc, 1);
    2294     size_t          cProcessed = 0;
    2295 
    2296     while ((rc = RTGetOpt(&GetOptState, &ValueUnion)) != 0)
     2294
     2295    while (   (rc = RTGetOpt(&GetOptState, &ValueUnion)) != 0
     2296           && rc != VINF_GETOPT_NOT_OPTION)
    22972297    {
    22982298        switch (rc)
     
    23642364                g_fDiffSpecialChars = false;
    23652365                break;
    2366 
    2367             case VINF_GETOPT_NOT_OPTION:
    2368             {
    2369                 if (!g_fDryRun)
    2370                 {
    2371                     if (!cProcessed)
    2372                     {
    2373                         RTPrintf("%s: Warning! This program will make changes to your source files and\n"
    2374                                  "%s:          there is a slight risk that bugs or a full disk may cause\n"
    2375                                  "%s:          LOSS OF DATA.   So, please make sure you have checked in\n"
    2376                                  "%s:          all your changes already.  If you didn't, then don't blame\n"
    2377                                  "%s:          anyone for not warning you!\n"
    2378                                  "%s:\n"
    2379                                  "%s:          Press any key to continue...\n",
    2380                                  g_szProgName, g_szProgName, g_szProgName, g_szProgName, g_szProgName,
    2381                                  g_szProgName, g_szProgName);
    2382                         RTStrmGetCh(g_pStdIn);
    2383                     }
    2384                     cProcessed++;
    2385                 }
    2386                 rc = scmProcessSomething(ValueUnion.psz, pSettings);
    2387                 if (RT_FAILURE(rc))
    2388                 {
    2389                     scmPrintStats();
    2390                     return RTEXITCODE_FAILURE;
    2391                 }
    2392                 break;
    2393             }
    23942366
    23952367            default:
     
    24052377    }
    24062378
    2407     scmPrintStats();
     2379    /*
     2380     * Process non-options.
     2381     */
     2382    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
     2383    if (rc == VINF_GETOPT_NOT_OPTION)
     2384    {
     2385        ScmSvnInit();
     2386
     2387        bool fWarned = g_fDryRun;
     2388        while (rc == VINF_GETOPT_NOT_OPTION)
     2389        {
     2390            if (!fWarned)
     2391            {
     2392                RTPrintf("%s: Warning! This program will make changes to your source files and\n"
     2393                         "%s:          there is a slight risk that bugs or a full disk may cause\n"
     2394                         "%s:          LOSS OF DATA.   So, please make sure you have checked in\n"
     2395                         "%s:          all your changes already.  If you didn't, then don't blame\n"
     2396                         "%s:          anyone for not warning you!\n"
     2397                         "%s:\n"
     2398                         "%s:          Press any key to continue...\n",
     2399                         g_szProgName, g_szProgName, g_szProgName, g_szProgName, g_szProgName,
     2400                         g_szProgName, g_szProgName);
     2401                RTStrmGetCh(g_pStdIn);
     2402                fWarned = true;
     2403            }
     2404
     2405            rc = scmProcessSomething(ValueUnion.psz, pSettings);
     2406            if (RT_FAILURE(rc))
     2407            {
     2408                rcExit = RTEXITCODE_FAILURE;
     2409                break;
     2410            }
     2411
     2412            /* next */
     2413            rc = RTGetOpt(&GetOptState, &ValueUnion);
     2414            if (RT_FAILURE(rc))
     2415                rcExit = RTGetOptPrintError(rc, &ValueUnion);
     2416        }
     2417
     2418        scmPrintStats();
     2419        ScmSvnTerm();
     2420    }
     2421    else
     2422        RTMsgWarning("No files or directories specified. Doing nothing");
     2423
    24082424    scmSettingsDestroy(pSettings);
    2409     return 0;
    2410 }
    2411 
     2425    return rcExit;
     2426}
     2427
  • trunk/src/bldprogs/scm.h

    r69324 r69433  
    5151
    5252
     53void ScmSvnInit(void);
     54void ScmSvnTerm(void);
    5355bool ScmSvnIsDirInWorkingCopy(const char *pszDir);
    5456bool ScmSvnIsInWorkingCopy(PSCMRWSTATE pState);
  • trunk/src/bldprogs/scmsubversion.cpp

    r69344 r69433  
    160160                                                                apr_pool_t *pScratchPool);
    161161/**@} */
     162
     163/** Cached APR pool. */
     164static apr_pool_t          *g_pSvnPool = NULL;
     165/** Cached SVN client context. */
     166static svn_client_ctx_t    *g_pSvnClientCtx = NULL;
     167/** Number of times the current context has been used. */
     168static uint32_t             g_cSvnClientCtxUsed = 0;
     169
     170#endif
     171
     172/*********************************************************************************************************************************
     173*   Internal Functions                                                                                                           *
     174*********************************************************************************************************************************/
     175#ifdef SCM_WITH_DYNAMIC_LIB_SVN
     176static void scmSvnFlushClientContextAndPool(void);
    162177#endif
    163178
     
    567582    *ppszStdOut = NULL;
    568583
     584#ifdef SCM_WITH_DYNAMIC_LIB_SVN
     585    scmSvnFlushClientContextAndPool();
     586#endif
     587
    569588    char *pszCmdLine = NULL;
    570589    int rc = RTGetOptArgvToString(&pszCmdLine, papszArgs, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
     
    621640static int scmSvnRun(PSCMRWSTATE pState, const char **papszArgs, bool fNormalFailureOk)
    622641{
     642#ifdef SCM_WITH_DYNAMIC_LIB_SVN
     643    scmSvnFlushClientContextAndPool();
     644#endif
     645
    623646    char *pszCmdLine = NULL;
    624647    int rc = RTGetOptArgvToString(&pszCmdLine, papszArgs, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
     
    627650    ScmVerbose(pState, 2, "executing: %s\n", pszCmdLine);
    628651
    629     /* Lazy bird uses RTProcExecToString. */
     652    /* Lazy bird uses RTProcExec. */
    630653    RTPROCSTATUS Status;
    631654    rc = RTProcExec(g_szSvnPath, papszArgs, RTENV_DEFAULT, RTPROCEXEC_FLAGS_STD_NULL, &Status);
     
    924947{
    925948    int rc = RTPathAbs(pszPath, pszAbsPath, cbAbsPath);
    926 # if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     949# if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
    927950    if (RT_SUCCESS(rc))
     951    {
    928952        RTPathChangeToUnixSlashes(pszAbsPath, true /*fForce*/);
     953        /* To avoid: svn: E235000: In file '..\..\..\subversion\libsvn_client\prop_commands.c' line 796: assertion failed (svn_dirent_is_absolute(target)) */
     954        if (pszAbsPath[1] == ':')
     955            pszAbsPath[0] = RT_C_TO_UPPER(pszAbsPath[0]);
     956    }
    929957# endif
    930958    return rc;
     
    933961
    934962/**
     963 * Gets a client context and pool.
     964 *
     965 * This implements caching.
     966 *
     967 * @returns IPRT status code.
     968 * @param   ppCtx               Where to return the context
     969 * @param   ppPool              Where to return the pool.
     970 */
     971static int scmSvnGetClientContextAndPool(svn_client_ctx_t **ppCtx, apr_pool_t **ppPool)
     972{
     973    /*
     974     * Use cached if present.
     975     */
     976    if (g_pSvnClientCtx && g_pSvnPool)
     977    {
     978        g_cSvnClientCtxUsed++;
     979        *ppCtx  = g_pSvnClientCtx;
     980        *ppPool = g_pSvnPool;
     981        return VINF_SUCCESS;
     982    }
     983    Assert(!g_pSvnClientCtx);
     984    Assert(!g_pSvnPool);
     985
     986    /*
     987     * Create new pool and context.
     988     */
     989    apr_pool_t *pPool = g_pfnSvnPoolCreateEx(NULL, NULL);
     990    if (pPool)
     991    {
     992        svn_client_ctx_t *pCtx = NULL;
     993        svn_error_t *pErr = g_pfnSvnClientCreateContext(&pCtx, pPool);
     994        if (!pErr)
     995        {
     996            g_cSvnClientCtxUsed = 1;
     997            g_pSvnClientCtx     = *ppCtx  = pCtx;
     998            g_pSvnPool          = *ppPool = pPool;
     999            return VINF_SUCCESS;
     1000        }
     1001        g_pfnAprPoolDestroy(pPool);
     1002    }
     1003
     1004    *ppCtx  = NULL;
     1005    *ppPool = NULL;
     1006    return VERR_GENERAL_FAILURE;
     1007}
     1008
     1009
     1010/**
     1011 * Puts back a client context and pool after use.
     1012 *
     1013 * @param   pCtx                The context.
     1014 * @param   pPool               The pool.
     1015 * @param   fFlush              Whether to flush it.
     1016 */
     1017static void scmSvnPutClientContextAndPool(svn_client_ctx_t *pCtx, apr_pool_t *pPool, bool fFlush)
     1018{
     1019    if (fFlush || g_cSvnClientCtxUsed > 4096) /* Disable this to force new context every time. */
     1020    {
     1021        g_pfnAprPoolDestroy(pPool);
     1022        g_pSvnPool = NULL;
     1023        g_pSvnClientCtx = NULL;
     1024    }
     1025    RT_NOREF(pCtx, fFlush);
     1026}
     1027
     1028
     1029/**
     1030 * Flushes the cached client context and pool
     1031 */
     1032static void scmSvnFlushClientContextAndPool(void)
     1033{
     1034    if (g_pSvnPool)
     1035        scmSvnPutClientContextAndPool(g_pSvnClientCtx, g_pSvnPool, true /*fFlush*/);
     1036    Assert(!g_pSvnPool);
     1037}
     1038
     1039
     1040/**
    9351041 * Checks if @a pszPath exists in the current WC.
    9361042 *
     
    9401046static int scmSvnIsObjectInWorkingCopy(const char *pszPath)
    9411047{
    942     int rc = -1;
    943 
    9441048    /* svn_client_propget4 and later requires absolute target path. */
    9451049    char szAbsPath[RTPATH_MAX];
    946     int  rc2 = scmSvnAbsPath(pszPath, szAbsPath, sizeof(szAbsPath));
    947     if (RT_SUCCESS(rc2))
    948     {
    949 # if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
    950         /* To avoid: svn: E235000: In file '..\..\..\subversion\libsvn_client\prop_commands.c' line 796: assertion failed (svn_dirent_is_absolute(target)) */
    951         if (szAbsPath[1] == ':')
    952             szAbsPath[0] = RT_C_TO_UPPER(szAbsPath[0]);
    953 # endif
    954 
    955         /* Create calling context. */
    956         apr_pool_t *pPool = g_pfnSvnPoolCreateEx(NULL, NULL);
    957         if (pPool)
    958         {
    959             svn_client_ctx_t *pCtx = NULL;
    960             svn_error_t *pErr = g_pfnSvnClientCreateContext(&pCtx, pPool);
     1050    int  rc = scmSvnAbsPath(pszPath, szAbsPath, sizeof(szAbsPath));
     1051    if (RT_SUCCESS(rc))
     1052    {
     1053        apr_pool_t *pPool;
     1054        svn_client_ctx_t *pCtx = NULL;
     1055        rc = scmSvnGetClientContextAndPool(&pCtx, &pPool);
     1056        if (RT_SUCCESS(rc))
     1057        {
     1058            /* Make the call. */
     1059            apr_hash_t         *pHash = NULL;
     1060            svn_opt_revision_t  Rev;
     1061            RT_ZERO(Rev);
     1062            Rev.kind          = svn_opt_revision_working;
     1063            Rev.value.number  = -1L;
     1064            svn_error_t *pErr = g_pfnSvnClientPropGet4(&pHash, "svn:no-such-property", szAbsPath, &Rev, &Rev,
     1065                                                       NULL /*pActualRev*/, svn_depth_empty, NULL /*pChangeList*/,
     1066                                                       pCtx, pPool, pPool);
    9611067            if (!pErr)
    962             {
    963                 /* Make the call. */
    964                 apr_hash_t         *pHash = NULL;
    965                 svn_opt_revision_t  Rev;
    966                 RT_ZERO(Rev);
    967                 Rev.kind          = svn_opt_revision_working;
    968                 Rev.value.number  = -1L;
    969                 pErr = g_pfnSvnClientPropGet4(&pHash, "svn:no-such-property", szAbsPath, &Rev, &Rev,
    970                                               NULL /*pActualRev*/, svn_depth_empty, NULL /*pChangeList*/, pCtx, pPool, pPool);
    971                 if (!pErr)
    972                     rc = true;
    973                 else if (pErr->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
    974                     rc = false;
    975             }
    976             g_pfnAprPoolDestroy(pPool);
     1068                rc = true;
     1069            else if (pErr->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
     1070                rc = false;
     1071
     1072            scmSvnPutClientContextAndPool(pCtx, pPool, false);
    9771073        }
    9781074    }
     
    9911087bool ScmSvnIsInWorkingCopy(PSCMRWSTATE pState)
    9921088{
    993     scmSvnFindSvnBinary(pState);
    994 
    9951089#ifdef SCM_WITH_DYNAMIC_LIB_SVN
    9961090    if (g_fSvnFunctionPointersValid)
     
    10361130bool ScmSvnIsDirInWorkingCopy(const char *pszDir)
    10371131{
    1038     scmSvnFindSvnBinary(NULL);
    1039 
    10401132#ifdef SCM_WITH_DYNAMIC_LIB_SVN
    10411133    if (g_fSvnFunctionPointersValid)
     
    10841176static int scmSvnQueryPropertyUsingApi(const char *pszPath, const char *pszProperty, char **ppszValue)
    10851177{
    1086     int rc = VERR_NOT_SUPPORTED;
    1087 
    10881178    /* svn_client_propget4 and later requires absolute target path. */
    10891179    char szAbsPath[RTPATH_MAX];
    1090     int  rc2 = scmSvnAbsPath(pszPath, szAbsPath, sizeof(szAbsPath));
    1091     if (RT_SUCCESS(rc2))
    1092     {
    1093 # if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
    1094         /* To avoid: svn: E235000: In file '..\..\..\subversion\libsvn_client\prop_commands.c' line 796: assertion failed (svn_dirent_is_absolute(target)) */
    1095         if (szAbsPath[1] == ':')
    1096             szAbsPath[0] = RT_C_TO_UPPER(szAbsPath[0]);
    1097 # endif
    1098 
    1099         /* Create calling context. */
    1100         apr_pool_t *pPool = g_pfnSvnPoolCreateEx(NULL, NULL);
    1101         if (pPool)
    1102         {
    1103             svn_client_ctx_t *pCtx = NULL;
    1104             svn_error_t *pErr = g_pfnSvnClientCreateContext(&pCtx, pPool);
     1180    int  rc = scmSvnAbsPath(pszPath, szAbsPath, sizeof(szAbsPath));
     1181    if (RT_SUCCESS(rc))
     1182    {
     1183        apr_pool_t *pPool;
     1184        svn_client_ctx_t *pCtx = NULL;
     1185        rc = scmSvnGetClientContextAndPool(&pCtx, &pPool);
     1186        if (RT_SUCCESS(rc))
     1187        {
     1188            /* Make the call. */
     1189            apr_hash_t         *pHash = NULL;
     1190            svn_opt_revision_t  Rev;
     1191            RT_ZERO(Rev);
     1192            Rev.kind          = svn_opt_revision_working;
     1193            Rev.value.number  = -1L;
     1194            svn_error_t *pErr = g_pfnSvnClientPropGet4(&pHash, pszProperty, szAbsPath, &Rev, &Rev,
     1195                                                       NULL /*pActualRev*/, svn_depth_empty, NULL /*pChangeList*/,
     1196                                                       pCtx, pPool, pPool);
    11051197            if (!pErr)
    11061198            {
    1107                 /* Make the call. */
    1108                 apr_hash_t         *pHash = NULL;
    1109                 svn_opt_revision_t  Rev;
    1110                 RT_ZERO(Rev);
    1111                 Rev.kind          = svn_opt_revision_working;
    1112                 Rev.value.number  = -1L;
    1113                 pErr = g_pfnSvnClientPropGet4(&pHash, pszProperty, szAbsPath, &Rev, &Rev,
    1114                                               NULL /*pActualRev*/, svn_depth_empty, NULL /*pChangeList*/, pCtx, pPool, pPool);
    1115                 if (!pErr)
     1199                /* Get the first value, if any. */
     1200                rc = VERR_NOT_FOUND;
     1201                apr_hash_index_t *pHashIdx = g_pfnAprHashFirst(pPool, pHash);
     1202                if (pHashIdx)
    11161203                {
    1117                     /* Get the first value, if any. */
    1118                     rc = VERR_NOT_FOUND;
    1119                     apr_hash_index_t *pHashIdx = g_pfnAprHashFirst(pPool, pHash);
    1120                     if (pHashIdx)
     1204                    const char **ppszFirst = (const char **)g_pfnAprHashThisVal(pHashIdx);
     1205                    if (ppszFirst && *ppszFirst)
    11211206                    {
    1122                         const char **ppszFirst = (const char **)g_pfnAprHashThisVal(pHashIdx);
    1123                         if (ppszFirst && *ppszFirst)
    1124                         {
    1125                             if (ppszValue)
    1126                                 rc = RTStrDupEx(ppszValue, *ppszFirst);
    1127                             else
    1128                                 rc = VINF_SUCCESS;
    1129                         }
     1207                        if (ppszValue)
     1208                            rc = RTStrDupEx(ppszValue, *ppszFirst);
     1209                        else
     1210                            rc = VINF_SUCCESS;
    11301211                    }
    11311212                }
    1132                 else if (pErr->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
    1133                     rc = VERR_INVALID_STATE;
    1134                 else
    1135                     rc = VERR_GENERAL_FAILURE;
    11361213            }
    1137             g_pfnAprPoolDestroy(pPool);
     1214            else if (pErr->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
     1215                rc = VERR_INVALID_STATE;
     1216            else
     1217                rc = VERR_GENERAL_FAILURE;
     1218
     1219            scmSvnPutClientContextAndPool(pCtx, pPool, false);
    11381220        }
    11391221    }
     
    11741256            return VINF_SUCCESS;
    11751257        }
    1176 
    1177     scmSvnFindSvnBinary(pState);
    11781258
    11791259#ifdef SCM_WITH_DYNAMIC_LIB_SVN
     
    14441524int ScmSvnApplyChanges(PSCMRWSTATE pState)
    14451525{
    1446     scmSvnFindSvnBinary(pState);
    1447 
    14481526#ifdef SCM_WITH_LATER
    14491527    if (0)
     
    14781556}
    14791557
     1558
     1559/**
     1560 * Initializes the subversion interface.
     1561 */
     1562void ScmSvnInit(void)
     1563{
     1564    scmSvnFindSvnBinary(NULL);
     1565}
     1566
     1567
     1568void ScmSvnTerm(void)
     1569{
     1570#ifdef SCM_WITH_DYNAMIC_LIB_SVN
     1571    scmSvnFlushClientContextAndPool();
     1572#endif
     1573}
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