remote: improve map/unmap of io area

Make sure we map and unmap the io area for controls.
Handle reset of io area
This commit is contained in:
Wim Taymans 2018-02-12 11:44:37 +01:00
parent f37f8ce70d
commit df57656615

View file

@ -51,14 +51,16 @@ struct mem_id {
int fd; int fd;
uint32_t flags; uint32_t flags;
uint32_t ref; uint32_t ref;
struct pw_map_range map;
void *ptr;
}; };
struct buffer_id { struct buffer_id {
struct spa_list link; struct spa_list link;
uint32_t id; uint32_t id;
struct spa_buffer *buf; struct spa_buffer *buf;
void *ptr;
struct pw_map_range map; struct pw_map_range map;
void *ptr;
uint32_t n_mem; uint32_t n_mem;
struct mem_id **mem; struct mem_id **mem;
}; };
@ -564,6 +566,30 @@ static struct mem_id *find_mem(struct pw_array *mem_ids, uint32_t id)
return NULL; return NULL;
} }
static void *mem_map(struct node_data *data, struct mem_id *mid, uint32_t offset, uint32_t size)
{
if (mid->ptr == NULL) {
pw_map_range_init(&mid->map, offset, size, data->core->sc_pagesize);
mid->ptr = mmap(NULL, mid->map.size, PROT_READ|PROT_WRITE,
MAP_SHARED, mid->fd, mid->map.offset);
if (mid->ptr == MAP_FAILED) {
pw_log_error("Failed to mmap memory %d %p: %m", size, mid);
mid->ptr = NULL;
return NULL;
}
}
return SPA_MEMBER(mid->ptr, mid->map.start, void);
}
static void mem_unmap(struct node_data *data, struct mem_id *mid)
{
if (mid->ptr) {
if (munmap(mid->ptr, mid->map.size) < 0)
pw_log_warn("failed to unmap: %m");
}
}
static void clear_memid(struct node_data *data, struct mem_id *mid) static void clear_memid(struct node_data *data, struct mem_id *mid)
{ {
if (mid->fd != -1) { if (mid->fd != -1) {
@ -579,8 +605,10 @@ static void clear_memid(struct node_data *data, struct mem_id *mid)
break; break;
} }
} }
if (!has_ref) if (!has_ref) {
mem_unmap(data, mid);
close(fd); close(fd);
}
} }
} }
@ -659,6 +687,7 @@ static void client_node_add_mem(void *object,
m->fd = memfd; m->fd = memfd;
m->flags = flags; m->flags = flags;
m->ref = 0; m->ref = 0;
m->ptr = NULL;
} }
static void client_node_transport(void *object, uint32_t node_id, static void client_node_transport(void *object, uint32_t node_id,
@ -1123,32 +1152,34 @@ client_node_port_set_io(void *object,
struct pw_core *core = proxy->remote->core; struct pw_core *core = proxy->remote->core;
struct port *port; struct port *port;
struct mem_id *mid; struct mem_id *mid;
struct pw_map_range r;
void *ptr; void *ptr;
port = find_port(data, direction, port_id); port = find_port(data, direction, port_id);
if (port == NULL) if (port == NULL)
return; return;
mid = find_mem(&data->mem_ids, memid); if (memid == SPA_ID_INVALID) {
if (mid == NULL) { ptr = NULL;
pw_log_warn("unknown memory id %u", memid); size = 0;
return;
} }
pw_map_range_init(&r, offset, size, core->sc_pagesize); else {
mid = find_mem(&data->mem_ids, memid);
if (mid == NULL) {
pw_log_warn("unknown memory id %u", memid);
return;
}
ptr = mmap(NULL, r.size, PROT_READ|PROT_WRITE, MAP_SHARED, mid->fd, r.offset); if ((ptr = mem_map(data, mid, offset, size)) == NULL)
if (ptr == MAP_FAILED) { return;
pw_log_warn("Failed to mmap memory %d %p: %s", size, mid,
strerror(errno));
return;
} }
pw_log_debug("port %p: set io %s", port, spa_type_map_get_type(core->type.map, id));
pw_log_debug("port %p: set io %s %p", port, spa_type_map_get_type(core->type.map, id), ptr);
spa_node_port_set_io(port->port->node->node, spa_node_port_set_io(port->port->node->node,
direction, port_id, direction, port_id,
id, id,
SPA_MEMBER(ptr, r.start, void), ptr,
size); size);
} }