Changeset 3005 for trunk/src


Ignore:
Timestamp:
Nov 6, 2016, 1:07:37 AM (9 years ago)
Author:
bird
Message:

fts-nt.c: Wide char support, part 4.

Location:
trunk/src/lib/nt
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/nt/fts-nt.c

    r3004 r3005  
    118118#define MAX(a, b)  ( (a) >= (b) ? (a) : (b) )
    119119
     120/** Enables BirdDir_T reuse. (Saves malloc and free calls.) */
     121#define FTS_WITH_DIRHANDLE_REUSE
     122/** Enables allocation statistics. */
     123//#define FTS_WITH_STATISTICS
     124/** Enables FTSENT allocation cache. */
    120125#define FTS_WITH_ALLOC_CACHE
    121126/** Number of size buckets for the FTSENT allocation cache. */
    122 #define FTS_NUM_FREE_BUCKETS    64
     127#define FTS_NUM_FREE_BUCKETS    64
    123128/** Shift for converting size to free bucket index. */
    124129#define FTS_FREE_BUCKET_SHIFT   4
    125130/** The FTSENT allocation alignment. */
    126 #define FTS_ALIGN_FTSENT        (1U << FTS_FREE_BUCKET_SHIFT)
    127 /** Enables allocation statistics. */
    128 //#define FTS_WITH_STATISTICS
     131#define FTS_ALIGN_FTSENT        (1U << FTS_FREE_BUCKET_SHIFT)
    129132
    130133/*
     
    135138struct _fts_private {
    136139        FTS             ftsp_fts;
     140#ifdef FTS_WITH_DIRHANDLE_REUSE
     141        /** Statically allocate directory handle. */
     142        BirdDir_T       dirhandle;
     143#endif
    137144#ifdef FTS_WITH_ALLOC_CACHE
    138145        /** Number of free entries in the above buckets. */
     
    403410#endif
    404411        nt_fts_free_alloc_cache(sp);
     412#ifdef FTS_WITH_DIRHANDLE_REUSE
     413        birdDirClose(&((struct _fts_private *)sp)->dirhandle);
     414#endif
    405415
    406416        /* Free up the stream pointer. */
     
    461471        wchar_t *pwc;
    462472
    463         /* If finished or unrecoverable error, return NULL. */
    464         if (sp->fts_cur == NULL || ISSET(FTS_STOP))
    465                 return (NULL);
    466 
    467473        /* Set current node pointer. */
    468474        p = sp->fts_cur;
     475
     476        /* If finished or unrecoverable error, return NULL. */
     477        if (p != NULL && !ISSET(FTS_STOP)) {
     478                /* likely */
     479        } else {
     480                return (NULL);
     481        }
    469482
    470483        /* Save and zero out user instructions. */
     
    473486
    474487        /* Any type of file may be re-visited; re-stat and re-turn. */
    475         if (instr == FTS_AGAIN) {
     488        if (instr != FTS_AGAIN) {
     489                /* likely */
     490        } else {
    476491                p->fts_info = fts_stat(sp, p, 0, INVALID_HANDLE_VALUE);
    477492                return (p);
     
    487502         *     here in case a API client checks it.
    488503         */
    489         if (instr == FTS_FOLLOW &&
    490             (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
     504        if (   instr != FTS_FOLLOW
     505            || (p->fts_info != FTS_SL && p->fts_info != FTS_SLNONE)) {
     506            /* likely */
     507        } else {
    491508                p->fts_info = fts_stat(sp, p, 1, INVALID_HANDLE_VALUE);
    492509                if (p->fts_info == FTS_D /*&& !ISSET(FTS_NOCHDIR)*/) {
     
    499516        if (p->fts_info == FTS_D) {
    500517                /* If skipped or crossed mount point, do post-order visit. */
    501                 if (instr == FTS_SKIP ||
    502                     (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
     518                if (  instr == FTS_SKIP
     519                    || (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
    503520                        if (sp->fts_child) {
    504521                                fts_lfree(sp->fts_child);
     
    528545                 * FTS_STOP or the fts_info field of the node.
    529546                 */
    530                 if (sp->fts_child != NULL) {
    531                         /* nothing to do */
    532                 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
    533                         if (ISSET(FTS_STOP))
    534                                 return (NULL);
    535                         return (p);
    536                 }
    537                 p = sp->fts_child;
    538                 sp->fts_child = NULL;
     547                if (sp->fts_child == NULL) {
     548                        p = fts_build(sp, BREAD);
     549                        if (p != NULL) {
     550                            /* likely */
     551                        } else {
     552                            if (ISSET(FTS_STOP))
     553                                    return (NULL);
     554                            return sp->fts_cur;
     555                        }
     556
     557                } else {
     558                        p = sp->fts_child;
     559                        sp->fts_child = NULL;
     560                }
    539561                goto name;
    540562        }
     
    547569                 * the root of the tree), and load the paths for the next root.
    548570                 */
    549                 if (p->fts_level == FTS_ROOTLEVEL) {
     571                if (p->fts_level != FTS_ROOTLEVEL) {
     572                        /* likely */
     573                } else {
    550574                        fts_free_entry(sp, tmp);
    551575                        fts_load(sp, p);
     
    558582                 * get back if necessary.
    559583                 */
    560                 if (p->fts_instr == FTS_SKIP) {
     584                if (p->fts_instr != FTS_SKIP) {
     585                        /* likely */
     586                } else {
    561587                        fts_free_entry(sp, tmp);
    562588                        goto next;
    563589                }
    564                 if (p->fts_instr == FTS_FOLLOW) {
     590                if (p->fts_instr != FTS_FOLLOW) {
     591                        /* likely */
     592                } else {
    565593                        p->fts_info = fts_stat(sp, p, 1, INVALID_HANDLE_VALUE);
    566594                        /* NT: See above regarding fts_flags. */
     
    588616        p = tmp->fts_parent;
    589617
    590         if (p->fts_level == FTS_ROOTPARENTLEVEL) {
     618        if (p->fts_level != FTS_ROOTPARENTLEVEL) {
     619                /* likely */
     620        } else {
    591621                /*
    592622                 * Done; free everything up and set errno to 0 so the user
     
    787817                fDirOpenFlags |= BIRDDIR_F_RESTART_SCAN;
    788818        }
     819#ifdef FTS_WITH_DIRHANDLE_REUSE
     820        dirp = birdDirOpenFromHandleWithReuse(&((struct _fts_private *)sp)->dirhandle, cur->fts_dirfd, NULL,
     821                                              fDirOpenFlags | BIRDDIR_F_STATIC_ALLOC);
     822#else
    789823        dirp = birdDirOpenFromHandle(cur->fts_dirfd, NULL, fDirOpenFlags);
     824#endif
    790825        if (dirp == NULL) {
    791826l_open_err:
     
    856891                                        free(p);
    857892                                fts_lfree(head);
     893#ifndef FTS_WITH_DIRHANDLE_REUSE
    858894                                birdDirClose(dirp);
     895#endif
    859896                                birdCloseFile(cur->fts_dirfd);
    860897                                cur->fts_dirfd = INVALID_HANDLE_VALUE;
     
    887924        }
    888925
     926#ifndef FTS_WITH_DIRHANDLE_REUSE
    889927        birdDirClose(dirp);
     928#endif
    890929
    891930        /*
  • trunk/src/lib/nt/kFsCache.c

    r2985 r3005  
    13291329        MY_FILE_ID_BOTH_DIR_INFORMATION     WithId;
    13301330        MY_FILE_ID_FULL_DIR_INFORMATION     NoId;
    1331         /* Buffer padding. We're using a 56KB buffer here to avoid size troubles with CIFS and such. */
     1331        /** Buffer padding. We're using a 56KB buffer here to avoid size troubles
     1332         * with CIFS and such that starts at 64KB. */
    13321333        KU8                                 abBuf[56*1024];
    13331334    } uBuf;
  • trunk/src/lib/nt/ntdir.c

    r3004 r3005  
    115115BirdDir_T *birdDirOpenFromHandle(void *pvHandle, const void *pvReserved, unsigned fFlags)
    116116{
    117     if (!pvReserved)
     117    if (!pvReserved && !(fFlags & BIRDDIR_F_STATIC_ALLOC))
    118118    {
    119119        /*
     
    138138    }
    139139    else
     140    {
     141        assert(!(fFlags & BIRDDIR_F_STATIC_ALLOC));
    140142        assert(pvReserved == NULL);
    141     birdSetErrnoToNoMem();
     143    }
     144    birdSetErrnoToInvalidArg();
     145    return NULL;
     146}
     147
     148
     149/**
     150 * Special API that takes a preallocated BirdDir_T and can be called again
     151 * without involving birdDirClose.
     152 *
     153 *
     154 */
     155BirdDir_T *birdDirOpenFromHandleWithReuse(BirdDir_T *pDir, void *pvHandle, const void *pvReserved, unsigned fFlags)
     156{
     157    if (!pvReserved)
     158    {
     159        /*
     160         * Allocate and initialize the directory enum handle.
     161         */
     162        if (pDir)
     163        {
     164            if (pDir->uMagic == BIRD_DIR_MAGIC)
     165            {
     166                if (   (pDir->fFlags & BIRDDIR_F_CLOSE_HANDLE)
     167                    && pDir->pvHandle != INVALID_HANDLE_VALUE)
     168                    birdCloseFile((HANDLE)pDir->pvHandle);
     169            }
     170            else
     171            {
     172                pDir->cbBuf     = 0;
     173                pDir->pabBuf    = NULL;
     174                pDir->uMagic    = BIRD_DIR_MAGIC;
     175            }
     176            pDir->pvHandle      = pvHandle;
     177            pDir->fFlags        = fFlags;
     178            pDir->uDev          = 0;
     179            pDir->offPos        = 0;
     180            pDir->fHaveData     = 0;
     181            pDir->fFirst        = 1;
     182            pDir->iInfoClass    = fFlags & BIRDDIR_F_EXTRA_INFO ? MyFileIdFullDirectoryInformation : MyFileNamesInformation;
     183            pDir->offBuf        = 0;
     184            return pDir;
     185        }
     186    }
     187    else
     188        assert(pvReserved == NULL);
     189    birdSetErrnoToInvalidArg();
    142190    return NULL;
    143191}
     
    174222            pDir->uDev = 0;
    175223
    176         /*
    177          * Allocate a buffer.
    178          */
    179         pDir->cbBuf = 0x20000;
    180         pDir->pabBuf = birdMemAlloc(pDir->cbBuf);
    181224        if (!pDir->pabBuf)
    182             return birdSetErrnoToNoMem();
     225        {
     226            /*
     227             * Allocate a buffer.
     228             *
     229             * Better not exceed 64KB or CIFS may throw a fit.  Also, on win10/64
     230             * here there is a noticable speedup when going one byte below 64KB.
     231             */
     232            pDir->cbBuf = 0xffe0;
     233            pDir->pabBuf = birdMemAlloc(pDir->cbBuf);
     234            if (!pDir->pabBuf)
     235                return birdSetErrnoToNoMem();
     236        }
    183237
    184238        pDir->fFirst = 0;
     
    548602 * Implements closedir().
    549603 */
    550 int             birdDirClose(BirdDir_T *pDir)
     604int birdDirClose(BirdDir_T *pDir)
    551605{
    552606    if (!pDir || pDir->uMagic != BIRD_DIR_MAGIC)
     
    559613    birdMemFree(pDir->pabBuf);
    560614    pDir->pabBuf = NULL;
    561     birdMemFree(pDir);
     615    if (!(pDir->fFlags & BIRDDIR_F_STATIC_ALLOC))
     616        birdMemFree(pDir);
    562617
    563618    return 0;
  • trunk/src/lib/nt/ntdir.h

    r3004 r3005  
    9090/** Whether to restart the scan. */
    9191#define BIRDDIR_F_RESTART_SCAN  4U
     92/** Set if the BirdDir_T structure is statically allocated. */
     93#define BIRDDIR_F_STATIC_ALLOC  8U
    9294/** @} */
    9395
     
    133135BirdDir_T      *birdDirOpenExW(void *hRoot, const wchar_t *pwszPath, const wchar_t *pwszFilter, unsigned fFlags);
    134136BirdDir_T      *birdDirOpenFromHandle(void *hDir, const void *pvReserved, unsigned fFlags);
     137BirdDir_T      *birdDirOpenFromHandleWithReuse(BirdDir_T *pDir, void *pvHandle, const void *pvReserved, unsigned fFlags);
    135138BirdDirEntry_T *birdDirRead(BirdDir_T *pDir);
    136139BirdDirEntryW_T *birdDirReadW(BirdDir_T *pDir);
Note: See TracChangeset for help on using the changeset viewer.