Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 398c4d7 in mainline


Ignore:
Timestamp:
2010-12-01T23:51:29Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
c245f16e
Parents:
2edcb63
Message:

More conservative locking in devman

Add mutex guard when accessing driver_t structure during driver assigning.

Added missing async_wait_for and removed extra mutex_unlock.

To speed-up answer time, driver start is done in separate fibril to avoid
blocking IPC connection fibril.

Location:
uspace
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/devman.c

    r2edcb63 r398c4d7  
    116116{
    117117        ipc_call_t answer;
    118         async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
     118        aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
    119119        int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
    120         return retval; 
     120        async_wait_for(req, NULL);
     121        return retval;
    121122}
    122123
  • uspace/srv/devman/devman.c

    r2edcb63 r398c4d7  
    520520        fibril_mutex_lock(&driver->driver_mutex);
    521521
    522         phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
     522        phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
    523523
    524524        if (phone < 0) {
     
    583583         * immediately and possibly started here as well.
    584584         */
     585        printf(NAME ": driver %s goes into running state.\n", driver->name);
    585586        driver->state = DRIVER_RUNNING;
    586587
     
    712713                /* TODO handle error */
    713714        }
    714        
     715
    715716        /* Wait for answer from the driver. */
    716717        async_wait_for(req, &rc);
     
    755756        attach_driver(node, drv);
    756757       
     758        fibril_mutex_lock(&drv->driver_mutex);
    757759        if (drv->state == DRIVER_NOT_STARTED) {
    758760                /* Start the driver. */
    759761                start_driver(drv);
    760762        }
    761        
    762         if (drv->state == DRIVER_RUNNING) {
     763        fibril_mutex_unlock(&drv->driver_mutex);
     764       
     765        fibril_mutex_lock(&drv->driver_mutex);
     766        bool is_running = drv->state == DRIVER_RUNNING;
     767        fibril_mutex_unlock(&drv->driver_mutex);
     768
     769        if (is_running) {
    763770                /* Notify the driver about the new device. */
    764                 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
     771                int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
    765772                if (phone > 0) {
    766773                        add_device(phone, drv, node, tree);
     
    924931        node->name = dev_name;
    925932        if (!set_dev_path(node, parent)) {
    926                 fibril_rwlock_write_unlock(&tree->rwlock);
    927933                return false;
    928934        }
  • uspace/srv/devman/main.c

    r2edcb63 r398c4d7  
    197197}
    198198
     199static int assign_driver_fibril(void *arg)
     200{
     201        node_t *node = (node_t *) arg;
     202        assign_driver(node, &drivers_list, &device_tree);
     203        return EOK;
     204}
     205
    199206/** Handle child device registration.
    200207 *
     
    237244       
    238245        devman_receive_match_ids(match_count, &node->match_ids);
    239        
     246
     247        /*
     248         * Try to find suitable driver and assign it to the device.
     249         * We do not want to block current fibril that is used to processing
     250         * incoming calls: we will launch a separate fibril to handle
     251         * the driver assigning. That is because assign_driver can actually
     252         * include task spawning which could take some time.
     253         */
     254        fid_t assign_fibril = fibril_create(assign_driver_fibril, node);
     255        if (assign_fibril == 0) {
     256                /*
     257                 * Fallback in case we are out of memory.
     258                 * Probably not needed as we will die soon anyway ;-).
     259                 */
     260                (void) assign_driver_fibril(node);
     261        } else {
     262                fibril_add_ready(assign_fibril);
     263        }
     264
    240265        /* Return device handle to parent's driver. */
    241266        ipc_answer_1(callid, EOK, node->handle);
    242        
    243         /* Try to find suitable driver and assign it to the device. */
    244         assign_driver(node, &drivers_list, &device_tree);
    245267}
    246268
     
    297319        printf(NAME ": device '%s' added to class '%s', class name '%s' was "
    298320            "asigned to it\n", dev->pathname, class_name, class_info->dev_name);
    299        
     321
    300322        ipc_answer_0(callid, EOK);
    301323}
Note: See TracChangeset for help on using the changeset viewer.