Changeset 1329

Show
Ignore:
Timestamp:
12/03/08 10:46:09 (10 months ago)
Author:
spa1
Message:
  • Made our locks more coarse-grained to avoid race conditions
  • Changed linked list of dag devices to be doubly-linked so we can remove devices without needing to search the entire list
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/format_dag25.c

    r1328 r1329  
    7373        int fd; 
    7474        uint16_t ref_count; 
     75        struct dag_dev_t *prev; 
    7576        struct dag_dev_t *next; 
    7677};       
     
    99100        struct dag_dev_t *dag_dev; 
    100101         
    101         pthread_mutex_lock(&open_dag_mutex); 
    102102        dag_dev = open_dags; 
    103103 
     
    106106        while (dag_dev != NULL) { 
    107107                if (strcmp(dag_dev->dev_name, dev_name) == 0) { 
    108                         pthread_mutex_unlock(&open_dag_mutex)
     108                        dag_dev->ref_count ++
    109109                        return dag_dev; 
    110110                         
     
    112112                dag_dev = dag_dev->next; 
    113113        } 
    114         pthread_mutex_unlock(&open_dag_mutex); 
    115114        return NULL; 
    116115                 
     
    120119static void dag_close_device(struct dag_dev_t *dev) { 
    121120        /* Need to remove from the device list */ 
    122         struct dag_dev_t *prev, *d; 
    123  
    124         prev = NULL; 
    125         pthread_mutex_lock(&open_dag_mutex); 
    126  
    127         d = open_dags; 
    128  
    129         while (d != NULL) { 
    130                 if (strcmp(dev->dev_name, d->dev_name) == 0) { 
    131                         /* Found it! */ 
    132                         if (prev == NULL) { 
    133                                 open_dags = d->next; 
    134                         } else { 
    135                                 prev->next = d->next; 
    136                         } 
    137                         assert(d->ref_count == 0); 
    138                         dag_close(d->fd); 
    139                         free(d->dev_name); 
    140                         free(d); 
    141                         return; 
    142                 } 
    143                 prev = d; 
    144                 d = d->next; 
    145         } 
    146  
    147         /* Not sure what we do here - we've been asked to close a 
    148          * device that isn't in our linked list - probably safest to 
    149          * just return. Is there anything else we can really do? */ 
    150         return; 
     121         
     122        assert(dev->ref_count == 0); 
     123         
     124        if (dev->prev == NULL) { 
     125                open_dags = dev->next; 
     126                if (dev->next) 
     127                        dev->next->prev = NULL; 
     128        } else { 
     129                dev->prev->next = dev->next; 
     130                if (dev->next) 
     131                        dev->next->prev = dev->prev; 
     132        } 
     133 
     134        dag_close(dev->fd); 
     135        free(dev->dev_name); 
     136        free(dev); 
     137                 
    151138} 
    152139 
     
    176163        new_dev->fd = fd; 
    177164        new_dev->dev_name = dev_name; 
    178         new_dev->ref_count = 0
    179          
    180         pthread_mutex_lock(&open_dag_mutex)
     165        new_dev->ref_count = 1
     166         
     167        new_dev->prev = NULL
    181168        new_dev->next = open_dags; 
     169        if (open_dags) 
     170                open_dags->prev = new_dev; 
     171         
    182172        open_dags = new_dev; 
    183         pthread_mutex_unlock(&open_dag_mutex); 
    184173         
    185174        return new_dev; 
     
    193182        struct dag_dev_t *dag_device = NULL; 
    194183         
     184        pthread_mutex_lock(&open_dag_mutex); 
    195185        if ((scan = strchr(libtrace->uridata,',')) == NULL) { 
    196186                dag_dev_name = strdup(libtrace->uridata); 
     
    225215 
    226216 
    227         dag_device->ref_count ++; 
    228217 
    229218        DUCK.last_duck = 0; 
     
    235224        FORMAT_DATA->drops = 0; 
    236225         
     226        pthread_mutex_unlock(&open_dag_mutex); 
    237227        return 0; 
    238228} 
     
    327317 
    328318static int dag_fin_input(libtrace_t *libtrace) { 
     319        pthread_mutex_lock(&open_dag_mutex); 
    329320        if (FORMAT_DATA->stream_attached) 
    330321                dag_pause_input(libtrace); 
     
    336327                trace_destroy_dead(DUCK.dummy_duck); 
    337328        free(libtrace->format_data); 
     329        pthread_mutex_unlock(&open_dag_mutex); 
    338330        return 0; /* success */ 
    339331}