mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-01-06 18:50:12 +01:00
libei: fix source removal on ei_disconnect
The sink dispatch() loop gets the source from the epollfd data pointer, so unref'ing the source would cause it to be destroyed when we may try to access it later. Fix the whole source ownership properly, the first ref is owned by the epollfd and moves to the list of removed sources, the caller gets the second ref. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
15cf73ad11
commit
8a0bec7b87
3 changed files with 9 additions and 2 deletions
|
|
@ -357,6 +357,7 @@ ei_disconnect(struct ei *ei)
|
|||
/* FIXME: unroll the devices here */
|
||||
ei_queue_disconnect_event(ei);
|
||||
ei->state = EI_STATE_DISCONNECTED;
|
||||
source_remove(ei->source);
|
||||
ei->source = source_unref(ei->source);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct source {
|
|||
int fd;
|
||||
};
|
||||
|
||||
OBJECT_IMPLEMENT_REF(source);
|
||||
OBJECT_IMPLEMENT_UNREF(source);
|
||||
OBJECT_IMPLEMENT_GETTER(source, fd, int);
|
||||
OBJECT_IMPLEMENT_GETTER(source, user_data, void*);
|
||||
|
|
@ -72,6 +73,8 @@ source_remove(struct source *source)
|
|||
if (source->close_behavior == SOURCE_CLOSE_ON_REMOVE)
|
||||
source->fd = xclose(source->fd);
|
||||
}
|
||||
/* Note: epollfd was the owner of the source, new owner is the removed
|
||||
list */
|
||||
list_remove(&source->link);
|
||||
list_append(&source->sink->sources_removed, &source->link);
|
||||
}
|
||||
|
|
@ -105,7 +108,7 @@ source_add(struct sink *sink, int sourcefd,
|
|||
|
||||
struct epoll_event e = {
|
||||
.events = EPOLLIN,
|
||||
.data.ptr = source,
|
||||
.data.ptr = source, /* epollfd is the owner of this source */
|
||||
};
|
||||
|
||||
if (epoll_ctl(sink->epollfd, EPOLL_CTL_ADD, sourcefd, &e) < 0) {
|
||||
|
|
@ -115,7 +118,7 @@ source_add(struct sink *sink, int sourcefd,
|
|||
|
||||
list_append(&sink->sources, &source->link);
|
||||
|
||||
return source;
|
||||
return source_ref(source);
|
||||
}
|
||||
|
||||
struct source *
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ typedef void (*source_dispatch_t)(struct source *source, void *user_data);
|
|||
*/
|
||||
void source_remove(struct source *source);
|
||||
|
||||
struct source *
|
||||
source_ref(struct source *source);
|
||||
|
||||
/**
|
||||
* Unref source. When the last reference is dropped, the source is removed
|
||||
* from the sink and resources are released.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue