diff options
| -rw-r--r-- | common/linked_list.c | 14 | ||||
| -rw-r--r-- | include/linked_list.h | 1 | ||||
| -rw-r--r-- | libseat/backend/seatd.c | 10 | ||||
| -rw-r--r-- | tests/linked_list.c | 44 | 
4 files changed, 61 insertions, 8 deletions
diff --git a/common/linked_list.c b/common/linked_list.c index cb3e0a8..3d2ee7d 100644 --- a/common/linked_list.c +++ b/common/linked_list.c @@ -32,3 +32,17 @@ bool linked_list_empty(struct linked_list *list) {  	assert(list->prev != NULL && list->next != NULL);  	return list->next == list;  } + +void linked_list_take(struct linked_list *target, struct linked_list *source) { +	if (linked_list_empty(source)) { +		linked_list_init(target); +		return; +	} + +	target->next = source->next; +	target->prev = source->prev; +	target->next->prev = target; +	target->prev->next = target; + +	linked_list_init(source); +} diff --git a/include/linked_list.h b/include/linked_list.h index 47cf09b..7a20985 100644 --- a/include/linked_list.h +++ b/include/linked_list.h @@ -12,5 +12,6 @@ void linked_list_init(struct linked_list *list);  void linked_list_insert(struct linked_list *list, struct linked_list *elem);  void linked_list_remove(struct linked_list *elem);  bool linked_list_empty(struct linked_list *list); +void linked_list_take(struct linked_list *target, struct linked_list *source);  #endif diff --git a/libseat/backend/seatd.c b/libseat/backend/seatd.c index afeab7f..1a187b1 100644 --- a/libseat/backend/seatd.c +++ b/libseat/backend/seatd.c @@ -204,14 +204,8 @@ static int queue_event(struct backend_seatd *backend, int opcode) {  }  static void execute_events(struct backend_seatd *backend) { -	struct linked_list list = { -		.next = backend->pending_events.next, -		.prev = backend->pending_events.prev, -	}; -	list.next->prev = &list; -	list.prev->next = &list; - -	linked_list_init(&backend->pending_events); +	struct linked_list list; +	linked_list_take(&list, &backend->pending_events);  	while (!linked_list_empty(&list)) {  		struct pending_event *ev = (struct pending_event *)list.next;  		int opcode = ev->opcode; diff --git a/tests/linked_list.c b/tests/linked_list.c index a5704a3..a29cff6 100644 --- a/tests/linked_list.c +++ b/tests/linked_list.c @@ -201,6 +201,47 @@ static void test_linked_list_loop_iterate(void) {  	assert(cnt == 3);  } +static void test_linked_list_take_empty(void) { +	struct linked_list list1, list2; +	linked_list_init(&list1); + +	linked_list_take(&list2, &list1); + +	assert(linked_list_empty(&list1)); +	assert(linked_list_empty(&list2)); +} + +static void test_linked_list_take_single(void) { +	struct linked_list list1, list2; +	linked_list_init(&list1); + +	struct list_elem elem1 = {{0}, NULL}; +	linked_list_insert(&list1, &elem1.link); + +	linked_list_take(&list2, &list1); + +	assert(linked_list_empty(&list1)); +	assert(list2.next == &elem1.link && list2.prev == &elem1.link); +	assert(elem1.link.next == &list2 && elem1.link.prev == &list2); +} + +static void test_linked_list_take_many(void) { +	struct linked_list list1, list2; +	linked_list_init(&list1); + +	struct list_elem elem1 = {{0}, NULL}; +	struct list_elem elem2 = {{0}, NULL}; +	linked_list_insert(&list1, &elem2.link); +	linked_list_insert(&list1, &elem1.link); + +	linked_list_take(&list2, &list1); + +	assert(linked_list_empty(&list1)); +	assert(list2.next == &elem1.link && list2.prev == &elem2.link); +	assert(elem1.link.next == &elem2.link && elem1.link.prev == &list2); +	assert(elem2.link.next == &list2 && elem2.link.prev == &elem1.link); +} +  int main(int argc, char *argv[]) {  	(void)argc;  	(void)argv; @@ -214,6 +255,9 @@ int main(int argc, char *argv[]) {  	test_linked_list_remove_loop();  	test_linked_list_manual_iterate();  	test_linked_list_loop_iterate(); +	test_linked_list_take_empty(); +	test_linked_list_take_single(); +	test_linked_list_take_many();  	return 0;  }  | 
