Changeset 4884


Ignore:
Timestamp:
Oct 31, 2014, 11:48:46 AM (5 years ago)
Author:
Sam Hocevar
Message:

core: add a lightweight spinlock to protect the list of file descriptors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/src/common/fd.c

    r4836 r4884  
    7070static int maxfd, nfiles;
    7171
     72/* Spinlock. This variable protects the fds variable. */
     73static volatile int fd_spinlock = 0;
     74
     75static void fd_lock()
     76{
     77    while (__sync_lock_test_and_set(&fd_spinlock, 1))
     78        ;
     79}
     80
     81static void fd_unlock()
     82{
     83    __sync_synchronize();
     84    fd_spinlock = 0;
     85}
     86
    7287/* Create lock. This lock variable is used to disable file descriptor
    7388 * creation wrappers. For instance on Mac OS X, fopen() calls open()
     
    8499{
    85100#if defined HAVE_REGEX_H
    86     if(regcomp(&re_include, regex, REG_EXTENDED) == 0)
     101    if (regcomp(&re_include, regex, REG_EXTENDED) == 0)
    87102        has_include = 1;
    88103#else
     
    94109{
    95110#if defined HAVE_REGEX_H
    96     if(regcomp(&re_exclude, regex, REG_EXTENDED) == 0)
     111    if (regcomp(&re_exclude, regex, REG_EXTENDED) == 0)
    97112        has_exclude = 1;
    98113#else
     
    113128void _zz_setratio(double r0, double r1)
    114129{
    115     if(r0 == 0.0 && r1 == 0.0)
     130    if (r0 == 0.0 && r1 == 0.0)
    116131    {
    117132        maxratio = minratio = 0.0;
     
    121136    minratio = r0 < MIN_RATIO ? MIN_RATIO : r0 > MAX_RATIO ? MAX_RATIO : r0;
    122137    maxratio = r1 < MIN_RATIO ? MIN_RATIO : r1 > MAX_RATIO ? MAX_RATIO : r1;
    123     if(maxratio < minratio)
     138    if (maxratio < minratio)
    124139        maxratio = minratio;
    125140}
     
    135150    double min, max, cur;
    136151
    137     if(minratio == maxratio)
     152    if (minratio == maxratio)
    138153        return minratio; /* this also takes care of 0.0 */
    139154
     
    162177     * corruption errors are reproducible */
    163178    files = static_files;
    164     for(nfiles = 0; nfiles < 32; nfiles++)
     179    for (nfiles = 0; nfiles < 32; nfiles++)
    165180        files[nfiles].managed = 0;
    166181
    167182    fds = static_fds;
    168     for(maxfd = 0; maxfd < 32; maxfd++)
     183    for (maxfd = 0; maxfd < 32; maxfd++)
    169184        fds[maxfd] = -1;
    170185}
     
    174189    int i;
    175190
    176     for(i = 0; i < maxfd; i++)
     191    for (i = 0; i < maxfd; i++)
    177192    {
    178         if(!files[fds[i]].managed)
     193        if (!files[fds[i]].managed)
    179194            continue;
    180195
     
    184199
    185200#if defined HAVE_REGEX_H
    186     if(has_include)
     201    if (has_include)
    187202        regfree(&re_include);
    188     if(has_exclude)
     203    if (has_exclude)
    189204        regfree(&re_exclude);
    190205#endif
    191206
    192     if(files != static_files)
     207    if (files != static_files)
    193208       free(files);
    194     if(fds != static_fds)
     209    if (fds != static_fds)
    195210        free(fds);
    196     if(list != static_list)
     211    if (list != static_list)
    197212        free(list);
    198213}
     
    201216{
    202217#if defined HAVE_REGEXEC
    203     if(has_include && regexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
     218    if (has_include && regexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
    204219        return 0; /* not included: ignore */
    205220
    206     if(has_exclude && regexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
     221    if (has_exclude && regexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
    207222        return 0; /* excluded: ignore */
    208223#else
     
    216231{
    217232#if defined HAVE_REGWEXEC
    218     if(has_include && regwexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
     233    if (has_include && regwexec(&re_include, file, 0, NULL, 0) == REG_NOMATCH)
    219234        return 0; /* not included: ignore */
    220235
    221     if(has_exclude && regwexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
     236    if (has_exclude && regwexec(&re_exclude, file, 0, NULL, 0) != REG_NOMATCH)
    222237        return 0; /* excluded: ignore */
    223238#else
     
    230245int _zz_iswatched(int fd)
    231246{
    232     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    233         return 0;
    234 
    235     return 1;
     247    int ret = 0;
     248    fd_lock();
     249
     250    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     251        goto early_exit;
     252
     253    ret = 1;
     254
     255early_exit:
     256    fd_unlock();
     257    return ret;
    236258}
    237259
     
    240262    int i;
    241263
    242     if(fd < 0 || fd > 65535 || (fd < maxfd && fds[fd] != -1))
    243         return;
     264    fd_lock();
     265
     266    if (fd < 0 || fd > 65535 || (fd < maxfd && fds[fd] != -1))
     267        goto early_exit;
    244268
    245269#if defined LIBZZUF
    246     if(autoinc)
     270    if (autoinc)
    247271        debug2("using seed %li", (long int)seed);
    248272#endif
    249273
    250274    /* If filedescriptor is outside our bounds */
    251     while(fd >= maxfd)
     275    while (fd >= maxfd)
    252276    {
    253         if(fds == static_fds)
     277        if (fds == static_fds)
    254278        {
    255279            fds = malloc(2 * maxfd * sizeof(*fds));
     
    258282        else
    259283            fds = realloc(fds, 2 * maxfd * sizeof(*fds));
    260         for(i = maxfd; i < maxfd * 2; i++)
     284        for (i = maxfd; i < maxfd * 2; i++)
    261285            fds[i] = -1;
    262286        maxfd *= 2;
     
    264288
    265289    /* Find an empty slot */
    266     for(i = 0; i < nfiles; i++)
    267         if(files[i].managed == 0)
     290    for (i = 0; i < nfiles; i++)
     291        if (files[i].managed == 0)
    268292            break;
    269293
    270294    /* No slot found, allocate memory */
    271     if(i == nfiles)
     295    if (i == nfiles)
    272296    {
    273297        nfiles++;
    274         if(files == static_files)
     298        if (files == static_files)
    275299        {
    276300            files = malloc(nfiles * sizeof(*files));
     
    293317
    294318    /* Check whether we should ignore the fd */
    295     if(list)
     319    if (list)
    296320    {
    297321        static int idx = 0;
     
    302326        files[i].active = 1;
    303327
    304     if(autoinc)
     328    if (autoinc)
    305329        seed++;
    306330
    307331    fds[fd] = i;
     332
     333early_exit:
     334    fd_unlock();
    308335}
    309336
    310337void _zz_unregister(int fd)
    311338{
    312     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    313         return;
     339    fd_lock();
     340
     341    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     342        goto early_exit;
    314343
    315344    files[fds[fd]].managed = 0;
    316345#if defined HAVE_FGETLN
    317     if(files[fds[fd]].fuzz.tmp)
     346    if (files[fds[fd]].fuzz.tmp)
    318347        free(files[fds[fd]].fuzz.tmp);
    319348#endif
    320349
    321350    fds[fd] = -1;
     351
     352early_exit:
     353    fd_unlock();
    322354}
    323355
    324356void _zz_lock(int fd)
    325357{
    326     if(fd < -1 || fd >= maxfd || fds[fd] == -1)
    327         return;
    328 
    329     if(fd == -1)
     358    fd_lock();
     359
     360    if (fd < -1 || fd >= maxfd || fds[fd] == -1)
     361        goto early_exit;
     362
     363    if (fd == -1)
    330364        create_lock++;
    331365    else
    332366        files[fds[fd]].locked++;
     367
     368early_exit:
     369    fd_unlock();
    333370}
    334371
    335372void _zz_unlock(int fd)
    336373{
    337     if(fd < -1 || fd >= maxfd || fds[fd] == -1)
    338         return;
    339 
    340     if(fd == -1)
     374    fd_lock();
     375
     376    if (fd < -1 || fd >= maxfd || fds[fd] == -1)
     377        goto early_exit;
     378
     379    if (fd == -1)
    341380        create_lock--;
    342381    else
    343382        files[fds[fd]].locked--;
     383
     384early_exit:
     385    fd_unlock();
    344386}
    345387
    346388int _zz_islocked(int fd)
    347389{
    348     if(fd < -1 || fd >= maxfd || fds[fd] == -1)
    349         return 0;
    350 
    351     if(fd == -1)
    352         return create_lock;
     390    int ret = 0;
     391    fd_lock();
     392
     393    if (fd < -1 || fd >= maxfd || fds[fd] == -1)
     394        goto early_exit;
     395
     396    if (fd == -1)
     397        ret = create_lock;
    353398    else
    354         return files[fds[fd]].locked;
     399        ret = files[fds[fd]].locked;
     400
     401early_exit:
     402    fd_unlock();
     403    return ret;
    355404}
    356405
    357406int _zz_isactive(int fd)
    358407{
    359     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    360         return 1;
    361 
    362     return files[fds[fd]].active;
     408    int ret = 1;
     409    fd_lock();
     410
     411    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     412        goto early_exit;
     413
     414    ret = files[fds[fd]].active;
     415
     416early_exit:
     417    fd_unlock();
     418    return ret;
    363419}
    364420
    365421int64_t _zz_getpos(int fd)
    366422{
    367     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    368         return 0;
    369 
    370     return files[fds[fd]].pos;
     423    int ret = 0;
     424    fd_lock();
     425
     426    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     427        goto early_exit;
     428
     429    ret = files[fds[fd]].pos;
     430
     431early_exit:
     432    fd_unlock();
     433    return ret;
    371434}
    372435
    373436void _zz_setpos(int fd, int64_t pos)
    374437{
    375     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    376         return;
     438    fd_lock();
     439
     440    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     441        goto early_exit;
    377442
    378443    files[fds[fd]].pos = pos;
     444
     445early_exit:
     446    fd_unlock();
    379447}
    380448
    381449void _zz_addpos(int fd, int64_t off)
    382450{
    383     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    384         return;
     451    fd_lock();
     452
     453    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     454        goto early_exit;
    385455
    386456    files[fds[fd]].pos += off;
     457
     458early_exit:
     459    fd_unlock();
    387460}
    388461
    389462void _zz_setfuzzed(int fd, int count)
    390463{
    391     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    392         return;
     464    fd_lock();
     465
     466    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     467        goto early_exit;
    393468
    394469    /* FIXME: what if we just slightly advanced? */
    395     if(files[fds[fd]].pos == files[fds[fd]].already_pos
     470    if (files[fds[fd]].pos == files[fds[fd]].already_pos
    396471        && count <= files[fds[fd]].already_fuzzed)
    397         return;
     472        goto early_exit;
    398473
    399474#if defined LIBZZUF
     
    403478    files[fds[fd]].already_pos = files[fds[fd]].pos;
    404479    files[fds[fd]].already_fuzzed = count;
     480
     481early_exit:
     482    fd_unlock();
    405483}
    406484
    407485int _zz_getfuzzed(int fd)
    408486{
    409     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    410         return 0;
    411 
    412     if(files[fds[fd]].pos < files[fds[fd]].already_pos)
    413         return 0;
    414 
    415     if(files[fds[fd]].pos >= files[fds[fd]].already_pos
     487    int ret = 0;
     488    fd_lock();
     489
     490    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     491        goto early_exit;
     492
     493    if (files[fds[fd]].pos < files[fds[fd]].already_pos)
     494        goto early_exit;
     495
     496    if (files[fds[fd]].pos >= files[fds[fd]].already_pos
    416497                               + files[fds[fd]].already_fuzzed)
    417         return 0;
    418 
    419     return (int)(files[fds[fd]].already_fuzzed + files[fds[fd]].already_pos
    420                                                - files[fds[fd]].pos);
     498        goto early_exit;
     499
     500    ret = (int)(files[fds[fd]].already_fuzzed + files[fds[fd]].already_pos
     501                                              - files[fds[fd]].pos);
     502
     503early_exit:
     504    fd_unlock();
     505    return ret;
    421506}
    422507
    423508struct fuzz *_zz_getfuzz(int fd)
    424509{
    425     if(fd < 0 || fd >= maxfd || fds[fd] == -1)
    426         return NULL;
    427 
    428     return &files[fds[fd]].fuzz;
    429 }
    430 
     510    struct fuzz *ret = NULL;
     511    fd_lock();
     512
     513    if (fd < 0 || fd >= maxfd || fds[fd] == -1)
     514        goto early_exit;
     515
     516    ret = &files[fds[fd]].fuzz;
     517
     518early_exit:
     519    fd_unlock();
     520    return ret;
     521}
     522
Note: See TracChangeset for help on using the changeset viewer.