Changeset 6519d6f in mainline


Ignore:
Timestamp:
2009-03-02T17:35:46Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8dc72b64
Parents:
1fcfc94
Message:

support for pending (blocking) device lookups
cleanup & cstyle

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devmap/devmap.c

    r1fcfc94 r6519d6f  
    2929/**
    3030 * @defgroup devmap Device mapper.
    31  * @brief       HelenOS device mapper.
     31 * @brief HelenOS device mapper.
    3232 * @{
    33  */ 
     33 */
    3434
    3535/** @file
     
    4747#include <ipc/devmap.h>
    4848
    49 #define NAME "devmap"
    50 
     49#define NAME  "devmap"
     50
     51/** Pending lookup structure. */
     52typedef struct {
     53        link_t link;
     54        char *name;              /**< Device name */
     55        ipc_callid_t callid;     /**< Call ID waiting for the lookup */
     56} pending_req_t;
    5157
    5258LIST_INITIALIZE(devices_list);
    5359LIST_INITIALIZE(drivers_list);
    54 
    55 /* order of locking:
    56  * drivers_list_futex
    57  * devices_list_futex
    58  * (devmap_driver_t *)->devices_futex
    59  * create_handle_futex
     60LIST_INITIALIZE(pending_req);
     61
     62/* Locking order:
     63 *  drivers_list_futex
     64 *  devices_list_futex
     65 *  (devmap_driver_t *)->devices_futex
     66 *  create_handle_futex
    6067 **/
    6168
     
    6471static atomic_t create_handle_futex = FUTEX_INITIALIZER;
    6572
    66 
    6773static int devmap_create_handle(void)
    6874{
    6975        static int last_handle = 0;
    7076        int handle;
    71 
     77       
    7278        /* TODO: allow reusing old handles after their unregistration
    73                 and implement some version of LRU algorithm */
     79         * and implement some version of LRU algorithm
     80         */
     81       
    7482        /* FIXME: overflow */
    75         futex_down(&create_handle_futex);       
    76 
     83        futex_down(&create_handle_futex);
     84       
    7785        last_handle += 1;
    7886        handle = last_handle;
    79 
    80         futex_up(&create_handle_futex); 
    81 
     87       
     88        futex_up(&create_handle_futex);
     89       
    8290        return handle;
    8391}
    8492
    8593
    86 /** Initialize device mapper. 
     94/** Initialize device mapper.
    8795 *
    8896 *
     
    9199{
    92100        /* TODO: */
    93 
     101       
    94102        return EOK;
    95103}
     
    100108static devmap_device_t *devmap_device_find_name(const char *name)
    101109{
    102         link_t *item;
     110        link_t *item = devices_list.next;
    103111        devmap_device_t *device = NULL;
    104 
    105         item = devices_list.next;
    106 
     112       
    107113        while (item != &devices_list) {
    108 
    109114                device = list_get_instance(item, devmap_device_t, devices);
    110                 if (0 == strcmp(device->name, name)) {
    111                         break;
    112                 }
     115                if (0 == strcmp(device->name, name))
     116                        break;
    113117                item = item->next;
    114118        }
    115 
     119       
    116120        if (item == &devices_list)
    117121                return NULL;
    118 
     122       
    119123        device = list_get_instance(item, devmap_device_t, devices);
    120124        return device;
     
    122126
    123127/** Find device with given handle.
     128 *
    124129 * @todo: use hash table
     130 *
    125131 */
    126132static devmap_device_t *devmap_device_find_handle(int handle)
    127133{
    128         link_t *item;
     134        futex_down(&devices_list_futex);
     135       
     136        link_t *item = (&devices_list)->next;
    129137        devmap_device_t *device = NULL;
    130138       
    131         futex_down(&devices_list_futex);
    132 
    133         item = (&devices_list)->next;
    134 
    135139        while (item != &devices_list) {
    136 
    137140                device = list_get_instance(item, devmap_device_t, devices);
    138                 if (device->handle == handle) {
    139                         break;
    140                 }
     141                if (device->handle == handle)
     142                        break;
    141143                item = item->next;
    142144        }
    143 
     145       
    144146        if (item == &devices_list) {
    145147                futex_up(&devices_list_futex);
    146148                return NULL;
    147149        }
    148 
     150       
    149151        device = list_get_instance(item, devmap_device_t, devices);
    150152       
    151153        futex_up(&devices_list_futex);
    152 
     154       
    153155        return device;
    154156}
    155157
    156158/**
     159 *
    157160 * Unregister device and free it. It's assumed that driver's device list is
    158161 * already locked.
     162 *
    159163 */
    160164static int devmap_device_unregister_core(devmap_device_t *device)
    161165{
    162 
    163166        list_remove(&(device->devices));
    164167        list_remove(&(device->driver_devices));
    165 
    166         free(device->name);     
     168       
     169        free(device->name);
    167170        free(device);
    168 
    169 
     171       
    170172        return EOK;
    171173}
    172174
    173175/**
     176 *
    174177 * Read info about new driver and add it into linked list of registered
    175178 * drivers.
     179 *
    176180 */
    177181static void devmap_driver_register(devmap_driver_t **odriver)
    178182{
     183        *odriver = NULL;
     184       
     185        ipc_call_t icall;
     186        ipc_callid_t iid = async_get_call(&icall);
     187       
     188        if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) {
     189                ipc_answer_0(iid, EREFUSED);
     190                return;
     191        }
     192       
     193        devmap_driver_t *driver = (devmap_driver_t *) malloc(sizeof(devmap_driver_t));
     194       
     195        if (driver == NULL) {
     196                ipc_answer_0(iid, ENOMEM);
     197                return;
     198        }
     199       
     200        /*
     201         * Get driver name
     202         */
     203        ipc_callid_t callid;
    179204        size_t name_size;
    180         ipc_callid_t callid;
    181         ipc_call_t call;
    182         devmap_driver_t *driver;
    183         ipc_callid_t iid;
    184         ipc_call_t icall;
    185 
    186         *odriver = NULL;
    187        
    188         iid = async_get_call(&icall);
    189 
    190         if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) {
    191                 ipc_answer_0(iid, EREFUSED);
    192                 return;
    193         }
    194 
    195         if (NULL ==
    196             (driver = (devmap_driver_t *)malloc(sizeof(devmap_driver_t)))) {
    197                 ipc_answer_0(iid, ENOMEM);
    198                 return;
    199         }
    200 
    201         /*
    202          * Get driver name
    203          */
    204205        if (!ipc_data_write_receive(&callid, &name_size)) {
    205206                free(driver);
     
    208209                return;
    209210        }
    210 
     211       
    211212        if (name_size > DEVMAP_NAME_MAXLEN) {
    212213                free(driver);
     
    215216                return;
    216217        }
    217 
     218       
    218219        /*
    219220         * Allocate buffer for device name.
    220221         */
    221         if (NULL == (driver->name = (char *)malloc(name_size + 1))) {
     222        driver->name = (char *) malloc(name_size + 1);
     223        if (driver->name == NULL) {
    222224                free(driver);
    223225                ipc_answer_0(callid, ENOMEM);
    224226                ipc_answer_0(iid, EREFUSED);
    225227                return;
    226         }       
    227 
     228        }
     229       
    228230        /*
    229231         * Send confirmation to sender and get data into buffer.
     
    235237                return;
    236238        }
    237 
     239       
    238240        driver->name[name_size] = 0;
    239 
     241       
    240242        /* Initialize futex for list of devices owned by this driver */
    241243        futex_initialize(&(driver->devices_futex), 1);
    242 
    243         /* 
     244       
     245        /*
    244246         * Initialize list of asociated devices
    245247         */
    246248        list_initialize(&(driver->devices));
    247 
    248         /* 
     249       
     250        /*
    249251         * Create connection to the driver
    250252         */
     253        ipc_call_t call;
    251254        callid = async_get_call(&call);
    252 
     255       
    253256        if (IPC_M_CONNECT_TO_ME != IPC_GET_METHOD(call)) {
    254257                ipc_answer_0(callid, ENOTSUP);
     
    259262                return;
    260263        }
    261 
     264       
    262265        driver->phone = IPC_GET_ARG5(call);
    263266       
     
    265268       
    266269        list_initialize(&(driver->drivers));
    267 
    268         futex_down(&drivers_list_futex);       
     270       
     271        futex_down(&drivers_list_futex);
    269272       
    270273        /* TODO:
    271274         * check that no driver with name equal to driver->name is registered
    272275         */
    273 
    274         /* 
     276       
     277        /*
    275278         * Insert new driver into list of registered drivers
    276279         */
    277280        list_append(&(driver->drivers), &drivers_list);
    278         futex_up(&drivers_list_futex); 
     281        futex_up(&drivers_list_futex);
    279282       
    280283        ipc_answer_0(iid, EOK);
    281 
     284       
    282285        *odriver = driver;
    283286}
    284287
    285 /** Unregister device driver, unregister all its devices and free driver
     288/**
     289 * Unregister device driver, unregister all its devices and free driver
    286290 * structure.
     291 *
    287292 */
    288293static int devmap_driver_unregister(devmap_driver_t *driver)
    289294{
    290         devmap_device_t *device;
    291 
    292         if (NULL == driver)
     295        if (driver == NULL)
    293296                return EEXISTS;
    294297       
    295         futex_down(&drivers_list_futex);       
    296 
     298        futex_down(&drivers_list_futex);
     299       
    297300        ipc_hangup(driver->phone);
    298301       
    299302        /* remove it from list of drivers */
    300303        list_remove(&(driver->drivers));
    301 
     304       
    302305        /* unregister all its devices */
    303306       
    304         futex_down(&devices_list_futex);       
     307        futex_down(&devices_list_futex);
    305308        futex_down(&(driver->devices_futex));
    306 
     309       
    307310        while (!list_empty(&(driver->devices))) {
    308                 device = list_get_instance(driver->devices.next,
     311                devmap_device_t *device = list_get_instance(driver->devices.next,
    309312                    devmap_device_t, driver_devices);
    310313                devmap_device_unregister_core(device);
     
    312315       
    313316        futex_up(&(driver->devices_futex));
    314         futex_up(&devices_list_futex); 
    315         futex_up(&drivers_list_futex); 
    316 
     317        futex_up(&devices_list_futex);
     318        futex_up(&drivers_list_futex);
     319       
    317320        /* free name and driver */
    318         if (NULL != driver->name) {
     321        if (NULL != driver->name)
    319322                free(driver->name);
    320         }
    321 
     323       
    322324        free(driver);
    323 
     325       
    324326        return EOK;
     327}
     328
     329
     330/** Process pending lookup requests */
     331static void process_pending_lookup()
     332{
     333        link_t *cur;
     334       
     335loop:
     336        for (cur = pending_req.next; cur != &pending_req; cur = cur->next) {
     337                pending_req_t *pr = list_get_instance(cur, pending_req_t, link);
     338               
     339                const devmap_device_t *dev = devmap_device_find_name(pr->name);
     340                if (!dev)
     341                        continue;
     342               
     343                ipc_answer_1(pr->callid, EOK, dev->handle);
     344               
     345                free(pr->name);
     346                list_remove(cur);
     347                free(pr);
     348                goto loop;
     349        }
    325350}
    326351
     
    332357    devmap_driver_t *driver)
    333358{
     359        if (driver == NULL) {
     360                ipc_answer_0(iid, EREFUSED);
     361                return;
     362        }
     363       
     364        /* Create new device entry */
     365        devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
     366        if (device == NULL) {
     367                ipc_answer_0(iid, ENOMEM);
     368                return;
     369        }
     370       
     371        /* Get device name */
    334372        ipc_callid_t callid;
    335373        size_t size;
    336         devmap_device_t *device;
    337 
    338         if (NULL == driver) {
    339                 ipc_answer_0(iid, EREFUSED);
    340                 return;
    341         }
    342        
    343         /* Create new device entry */
    344         if (NULL ==
    345             (device = (devmap_device_t *) malloc(sizeof(devmap_device_t)))) {
    346                 ipc_answer_0(iid, ENOMEM);
    347                 return;
    348         }
    349        
    350         /* Get device name */
    351374        if (!ipc_data_write_receive(&callid, &size)) {
    352375                free(device);
     
    354377                return;
    355378        }
    356 
     379       
    357380        if (size > DEVMAP_NAME_MAXLEN) {
    358381                free(device);
     
    364387        /* +1 for terminating \0 */
    365388        device->name = (char *) malloc(size + 1);
    366 
    367         if (NULL == device->name) {
     389       
     390        if (device->name == NULL) {
    368391                free(device);
    369392                ipc_answer_0(callid, ENOMEM);
     
    374397        ipc_data_write_finalize(callid, device->name, size);
    375398        device->name[size] = 0;
    376 
     399       
    377400        list_initialize(&(device->devices));
    378401        list_initialize(&(device->driver_devices));
    379 
    380         futex_down(&devices_list_futex);       
    381 
     402       
     403        futex_down(&devices_list_futex);
     404       
    382405        /* Check that device with such name is not already registered */
    383406        if (NULL != devmap_device_find_name(device->name)) {
     
    389412                return;
    390413        }
    391 
     414       
    392415        /* Get unique device handle */
    393         device->handle = devmap_create_handle(); 
    394 
     416        device->handle = devmap_create_handle();
     417       
    395418        device->driver = driver;
    396419       
    397420        /* Insert device into list of all devices  */
    398421        list_append(&device->devices, &devices_list);
    399 
     422       
    400423        /* Insert device into list of devices that belog to one driver */
    401424        futex_down(&device->driver->devices_futex);     
     
    403426        list_append(&device->driver_devices, &device->driver->devices);
    404427       
    405         futex_up(&device->driver->devices_futex);       
    406         futex_up(&devices_list_futex); 
    407 
     428        futex_up(&device->driver->devices_futex);
     429        futex_up(&devices_list_futex);
     430       
    408431        ipc_answer_1(iid, EOK, device->handle);
     432       
     433        process_pending_lookup();
    409434}
    410435
     
    416441{
    417442        /* TODO */
    418 
    419443        return EOK;
    420444}
    421445
    422446/** Connect client to the device.
     447 *
    423448 * Find device driver owning requested device and forward
    424449 * the message to it.
     450 *
    425451 */
    426452static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
    427453{
    428         devmap_device_t *dev;
    429         int handle;
    430 
    431454        /*
    432455         * Get handle from request
    433456         */
    434         handle = IPC_GET_ARG2(*call);
    435         dev = devmap_device_find_handle(handle);
    436 
     457        int handle = IPC_GET_ARG2(*call);
     458        devmap_device_t *dev = devmap_device_find_handle(handle);
     459       
    437460        if (NULL == dev) {
    438461                ipc_answer_0(callid, ENOENT);
    439462                return;
    440         } 
    441 
     463        }
     464       
    442465        ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle),
    443466            IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
     
    445468
    446469/** Find handle for device instance identified by name.
     470 *
    447471 * In answer will be send EOK and device handle in arg1 or a error
    448  * code from errno.h.
     472 * code from errno.h.
     473 *
    449474 */
    450475static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall)
    451476{
    452         char *name = NULL;
    453         size_t name_size;
    454         const devmap_device_t *dev;
    455         ipc_callid_t callid;
    456         ipcarg_t retval;
    457        
    458         /*
     477        /*
    459478         * Wait for incoming message with device name (but do not
    460479         * read the name itself until the buffer is allocated).
    461480         */
    462         if (!ipc_data_write_receive(&callid, &name_size)) {
     481        ipc_callid_t callid;
     482        size_t size;
     483        if (!ipc_data_write_receive(&callid, &size)) {
    463484                ipc_answer_0(callid, EREFUSED);
    464485                ipc_answer_0(iid, EREFUSED);
    465486                return;
    466487        }
    467 
    468         if (name_size > DEVMAP_NAME_MAXLEN) {
     488       
     489        if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) {
    469490                ipc_answer_0(callid, EINVAL);
    470491                ipc_answer_0(iid, EREFUSED);
    471492                return;
    472493        }
    473 
     494       
    474495        /*
    475496         * Allocate buffer for device name.
    476497         */
    477         if (NULL == (name = (char *)malloc(name_size))) {
     498        char *name = (char *) malloc(size);
     499        if (name == NULL) {
    478500                ipc_answer_0(callid, ENOMEM);
    479501                ipc_answer_0(iid, EREFUSED);
    480502                return;
    481         }       
    482 
     503        }
     504       
    483505        /*
    484506         * Send confirmation to sender and get data into buffer.
    485507         */
    486         if (EOK != (retval = ipc_data_write_finalize(callid, name,
    487             name_size))) {
    488                 ipc_answer_0(iid, EREFUSED);
    489                 return;
    490         }
    491 
     508        ipcarg_t retval = ipc_data_write_finalize(callid, name, size);
     509        if (retval != EOK) {
     510                ipc_answer_0(iid, EREFUSED);
     511                free(name);
     512                return;
     513        }
     514        name[size] = '\0';
     515       
    492516        /*
    493517         * Find device name in linked list of known devices.
    494518         */
    495         dev = devmap_device_find_name(name);
    496 
     519        const devmap_device_t *dev = devmap_device_find_name(name);
     520       
    497521        /*
    498522         * Device was not found.
    499523         */
    500         if (NULL == dev) {
     524        if (dev == NULL) {
     525                if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
     526                        /* Blocking lookup, add to pending list */
     527                        pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t));
     528                        if (!pr) {
     529                                ipc_answer_0(iid, ENOMEM);
     530                                free(name);
     531                                return;
     532                        }
     533                       
     534                        pr->name = name;
     535                        pr->callid = iid;
     536                        list_append(&pr->link, &pending_req);
     537                        return;
     538                }
     539               
    501540                ipc_answer_0(iid, ENOENT);
    502                 return;
    503         }
    504 
     541                free(name);
     542                return;
     543        }
     544       
    505545        ipc_answer_1(iid, EOK, dev->handle);
    506 }
    507 
    508 /** Find name of device identified by id and send it to caller.
     546        free(name);
     547}
     548
     549/** Find name of device identified by id and send it to caller.
    509550 *
    510551 */
    511552static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall)
    512553{
    513         const devmap_device_t *device;
    514         size_t name_size;
    515 
    516         device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
    517 
     554        const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
     555       
    518556        /*
    519557         * Device not found.
    520558         */
    521         if (NULL == device) {
     559        if (device == NULL) {
    522560                ipc_answer_0(iid, ENOENT);
    523561                return;
    524         }       
    525 
     562        }
     563       
    526564        ipc_answer_0(iid, EOK);
    527 
    528         name_size = strlen(device->name);
    529 
    530 
    531 /*      FIXME:
    532         we have no channel from DEVMAP to client ->
    533         sending must be initiated by client
    534 
    535         int rc = ipc_data_write_send(phone, device->name, name_size);
    536         if (rc != EOK) {
    537                 async_wait_for(req, NULL);
    538                 return rc;
    539         }
    540 */     
     565       
     566        size_t name_size = strlen(device->name);
     567       
     568        /* FIXME:
     569         * We have no channel from DEVMAP to client, therefore
     570         * sending must be initiated by client.
     571         *
     572         * int rc = ipc_data_write_send(phone, device->name, name_size);
     573         * if (rc != EOK) {
     574         *     async_wait_for(req, NULL);
     575         *     return rc;
     576         * }
     577         */
     578       
    541579        /* TODO: send name in response */
    542580}
     
    547585static void devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
    548586{
    549         ipc_callid_t callid;
    550         ipc_call_t call;
     587        /* Accept connection */
     588        ipc_answer_0(iid, EOK);
     589       
     590        devmap_driver_t *driver = NULL;
     591        devmap_driver_register(&driver);
     592       
     593        if (NULL == driver)
     594                return;
     595       
    551596        bool cont = true;
    552         devmap_driver_t *driver = NULL;
    553 
    554         ipc_answer_0(iid, EOK);
    555 
    556         devmap_driver_register(&driver);
    557 
    558         if (NULL == driver)
    559                 return;
    560        
    561597        while (cont) {
    562                 callid = async_get_call(&call);
    563 
    564                 switch (IPC_GET_METHOD(call)) {
     598                ipc_call_t call;
     599                ipc_callid_t callid = async_get_call(&call);
     600               
     601                switch (IPC_GET_METHOD(call)) {
    565602                case IPC_M_PHONE_HUNGUP:
    566603                        cont = false;
    567                         continue; /* Exit thread */
     604                        /* Exit thread */
     605                        continue;
    568606                case DEVMAP_DRIVER_UNREGISTER:
    569                         if (NULL == driver) {
     607                        if (NULL == driver)
    570608                                ipc_answer_0(callid, ENOENT);
    571                         } else {
     609                        else
    572610                                ipc_answer_0(callid, EOK);
    573                         }
    574611                        break;
    575612                case DEVMAP_DEVICE_REGISTER:
     
    588625                        break;
    589626                default:
    590                         if (!(callid & IPC_CALLID_NOTIFICATION)) {
     627                        if (!(callid & IPC_CALLID_NOTIFICATION))
    591628                                ipc_answer_0(callid, ENOENT);
    592                         }
    593629                }
    594630        }
    595631       
    596632        if (NULL != driver) {
    597                 /* 
     633                /*
    598634                 * Unregister the device driver and all its devices.
    599635                 */
     
    601637                driver = NULL;
    602638        }
    603        
    604639}
    605640
     
    609644static void devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall)
    610645{
    611         ipc_callid_t callid;
    612         ipc_call_t call;
     646        /* Accept connection */
     647        ipc_answer_0(iid, EOK);
     648       
    613649        bool cont = true;
    614 
    615         ipc_answer_0(iid, EOK); /* Accept connection */
    616 
    617650        while (cont) {
    618                 callid = async_get_call(&call);
    619 
    620                 switch (IPC_GET_METHOD(call)) {
     651                ipc_call_t call;
     652                ipc_callid_t callid = async_get_call(&call);
     653               
     654                switch (IPC_GET_METHOD(call)) {
    621655                case IPC_M_PHONE_HUNGUP:
    622656                        cont = false;
    623                         continue; /* Exit thread */
    624 
     657                        /* Exit thread */
     658                        continue;
    625659                case DEVMAP_DEVICE_GET_HANDLE:
    626                         devmap_get_handle(callid, &call);
    627 
     660                        devmap_get_handle(callid, &call);
    628661                        break;
    629662                case DEVMAP_DEVICE_GET_NAME:
     
    632665                        break;
    633666                default:
    634                         if (!(callid & IPC_CALLID_NOTIFICATION)) {
     667                        if (!(callid & IPC_CALLID_NOTIFICATION))
    635668                                ipc_answer_0(callid, ENOENT);
    636                         }
    637669                }
    638670        }
    639671}
    640672
    641 /** Function for handling connections to devmap 
     673/** Function for handling connections to devmap
    642674 *
    643675 */
     
    657689                break;
    658690        default:
    659                 ipc_answer_0(iid, ENOENT); /* No such interface */
    660         }
    661 
    662         /* Cleanup */
     691                /* No such interface */
     692                ipc_answer_0(iid, ENOENT);
     693        }
    663694}
    664695
     
    670701        printf(NAME ": HelenOS Device Mapper\n");
    671702       
    672         ipcarg_t phonead;
    673 
    674703        if (devmap_init() != 0) {
    675704                printf(NAME ": Error while initializing service\n");
     
    679708        /* Set a handler of incomming connections */
    680709        async_set_client_connection(devmap_connection);
    681 
     710       
    682711        /* Register device mapper at naming service */
     712        ipcarg_t phonead;
    683713        if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
    684714                return -1;
     
    686716        printf(NAME ": Accepting connections\n");
    687717        async_manager();
     718       
    688719        /* Never reached */
    689720        return 0;
Note: See TracChangeset for help on using the changeset viewer.