Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4569 → Rev 4570

/trunk/uspace/srv/devmap/devmap.c
45,7 → 45,6
#include <stdlib.h>
#include <string.h>
#include <ipc/devmap.h>
#include <assert.h>
 
#define NAME "devmap"
 
84,20 → 83,9
devmap_driver_t *driver;
} devmap_device_t;
 
/** Pending lookup structure. */
typedef struct {
link_t link;
char *name; /**< Device name */
ipc_callid_t callid; /**< Call ID waiting for the lookup */
} pending_req_t;
 
LIST_INITIALIZE(devices_list);
LIST_INITIALIZE(drivers_list);
LIST_INITIALIZE(pending_req);
 
static bool pending_new_dev = false;
static FIBRIL_CONDVAR_INITIALIZE(pending_cv);
 
/* Locking order:
* drivers_list_mutex
* devices_list_mutex
106,6 → 94,7
**/
 
static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex);
static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv);
static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex);
static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex);
 
344,38 → 333,6
return EOK;
}
 
 
/** Process pending lookup requests */
static void process_pending_lookup(void)
{
link_t *cur;
 
loop:
fibril_mutex_lock(&devices_list_mutex);
while (!pending_new_dev)
fibril_condvar_wait(&pending_cv, &devices_list_mutex);
rescan:
for (cur = pending_req.next; cur != &pending_req; cur = cur->next) {
pending_req_t *pr = list_get_instance(cur, pending_req_t, link);
const devmap_device_t *dev = devmap_device_find_name(pr->name);
if (!dev)
continue;
ipc_answer_1(pr->callid, EOK, dev->handle);
free(pr->name);
list_remove(cur);
free(pr);
goto rescan;
}
pending_new_dev = false;
fibril_mutex_unlock(&devices_list_mutex);
goto loop;
}
 
 
/** Register instance of device
*
*/
452,8 → 409,7
list_append(&device->driver_devices, &device->driver->devices);
fibril_mutex_unlock(&device->driver->devices_mutex);
pending_new_dev = true;
fibril_condvar_signal(&pending_cv);
fibril_condvar_broadcast(&devices_list_cv);
fibril_mutex_unlock(&devices_list_mutex);
ipc_answer_1(iid, EOK, device->handle);
540,11 → 496,13
name[size] = '\0';
fibril_mutex_lock(&devices_list_mutex);
const devmap_device_t *dev;
recheck:
 
/*
* Find device name in linked list of known devices.
* Find device name in the list of known devices.
*/
const devmap_device_t *dev = devmap_device_find_name(name);
dev = devmap_device_find_name(name);
/*
* Device was not found.
551,20 → 509,10
*/
if (dev == NULL) {
if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
/* Blocking lookup, add to pending list */
pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t));
if (!pr) {
fibril_mutex_unlock(&devices_list_mutex);
ipc_answer_0(iid, ENOMEM);
free(name);
return;
}
pr->name = name;
pr->callid = iid;
list_append(&pr->link, &pending_req);
fibril_mutex_unlock(&devices_list_mutex);
return;
/* Blocking lookup */
fibril_condvar_wait(&devices_list_cv,
&devices_list_mutex);
goto recheck;
}
ipc_answer_0(iid, ENOENT);
836,11 → 784,6
/* Set a handler of incomming connections */
async_set_client_connection(devmap_connection);
 
/* Create a fibril for handling pending device lookups */
fid_t fid = fibril_create(process_pending_lookup, NULL);
assert(fid);
fibril_add_ready(fid);
/* Register device mapper at naming service */
ipcarg_t phonead;
if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)