Changeset a7e04d16 in mainline


Ignore:
Timestamp:
2010-12-23T00:19:59Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
23cdcc6f
Parents:
9476f4f
git-author:
Vojtech Horky <> (2010-12-23 00:19:59)
git-committer:
Jakub Jermar <jakub@…> (2010-12-23 00:19:59)
Message:

Do not hold the devices_mutex while connecting to the device in
devfs_node_open().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/devfs/devfs_ops.c

    r9476f4f ra7e04d16  
    6060typedef struct {
    6161        devmap_handle_t handle;
    62         int phone;
     62        int phone;              /**< When < 0, the structure is incomplete. */
    6363        size_t refcount;
    6464        link_t link;
     65        fibril_condvar_t cv;    /**< Broadcast when completed. */
    6566} device_t;
    6667
     
    227228                        [DEVICES_KEY_HANDLE] = (unsigned long) node->handle
    228229                };
    229                
     230                link_t *lnk;
     231
    230232                fibril_mutex_lock(&devices_mutex);
    231                 link_t *lnk = hash_table_find(&devices, key);
     233restart:
     234                lnk = hash_table_find(&devices, key);
    232235                if (lnk == NULL) {
    233236                        device_t *dev = (device_t *) malloc(sizeof(device_t));
     
    237240                        }
    238241                       
     242                        dev->handle = node->handle;
     243                        dev->phone = -1;        /* mark as incomplete */
     244                        dev->refcount = 1;
     245                        fibril_condvar_initialize(&dev->cv);
     246
     247                        /*
     248                         * Insert the incomplete device structure so that other
     249                         * fibrils will not race with us when we drop the mutex
     250                         * below.
     251                         */
     252                        hash_table_insert(&devices, key, &dev->link);
     253
     254                        /*
     255                         * Drop the mutex to allow recursive devfs requests.
     256                         */
     257                        fibril_mutex_unlock(&devices_mutex);
     258
    239259                        int phone = devmap_device_connect(node->handle, 0);
     260
     261                        fibril_mutex_lock(&devices_mutex);
     262
     263                        /*
     264                         * Notify possible waiters about this device structure
     265                         * being completed (or destroyed).
     266                         */
     267                        fibril_condvar_broadcast(&dev->cv);
     268
    240269                        if (phone < 0) {
     270                                /*
     271                                 * Connecting failed, need to remove the
     272                                 * entry and free the device structure.
     273                                 */
     274                                hash_table_remove(&devices, key, DEVICES_KEYS);
    241275                                fibril_mutex_unlock(&devices_mutex);
     276
    242277                                free(dev);
    243278                                return ENOENT;
    244279                        }
    245280                       
    246                         dev->handle = node->handle;
     281                        /* Set the correct phone. */
    247282                        dev->phone = phone;
    248                         dev->refcount = 1;
    249                        
    250                         hash_table_insert(&devices, key, &dev->link);
    251283                } else {
    252284                        device_t *dev = hash_table_get_instance(lnk, device_t, link);
     285
     286                        if (dev->phone < 0) {
     287                                /*
     288                                 * Wait until the device structure is completed
     289                                 * and start from the beginning as the device
     290                                 * structure might have entirely disappeared
     291                                 * while we were not holding the mutex in
     292                                 * fibril_condvar_wait().
     293                                 */
     294                                fibril_condvar_wait(&dev->cv, &devices_mutex);
     295                                goto restart;
     296                        }
     297
    253298                        dev->refcount++;
    254299                }
     
    564609               
    565610                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     611                assert(dev->phone >= 0);
    566612               
    567613                ipc_callid_t callid;
     
    627673               
    628674                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     675                assert(dev->phone >= 0);
    629676               
    630677                ipc_callid_t callid;
     
    696743               
    697744                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     745                assert(dev->phone >= 0);
    698746                dev->refcount--;
    699747               
     
    743791               
    744792                device_t *dev = hash_table_get_instance(lnk, device_t, link);
     793                assert(dev->phone >= 0);
    745794               
    746795                /* Make a request at the driver */
Note: See TracChangeset for help on using the changeset viewer.