aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/list.c7
-rw-r--r--include/list.h1
-rw-r--r--include/sway/server.h2
-rw-r--r--sway/desktop/transaction.c51
-rw-r--r--sway/server.c3
5 files changed, 42 insertions, 22 deletions
diff --git a/common/list.c b/common/list.c
index 39cc10e1..cab10c1e 100644
--- a/common/list.c
+++ b/common/list.c
@@ -62,6 +62,13 @@ void list_cat(list_t *list, list_t *source) {
62 } 62 }
63} 63}
64 64
65void list_empty(list_t *list) {
66 list->capacity = 10;
67 list->length = 0;
68 free(list->items);
69 list->items = malloc(sizeof(void*) * list->capacity);
70}
71
65void list_qsort(list_t *list, int compare(const void *left, const void *right)) { 72void list_qsort(list_t *list, int compare(const void *left, const void *right)) {
66 qsort(list->items, list->length, sizeof(void *), compare); 73 qsort(list->items, list->length, sizeof(void *), compare);
67} 74}
diff --git a/include/list.h b/include/list.h
index 7eead4ac..d352dbd5 100644
--- a/include/list.h
+++ b/include/list.h
@@ -14,6 +14,7 @@ void list_add(list_t *list, void *item);
14void list_insert(list_t *list, int index, void *item); 14void list_insert(list_t *list, int index, void *item);
15void list_del(list_t *list, int index); 15void list_del(list_t *list, int index);
16void list_cat(list_t *list, list_t *source); 16void list_cat(list_t *list, list_t *source);
17void list_empty(list_t *list);
17// See qsort. Remember to use *_qsort functions as compare functions, 18// See qsort. Remember to use *_qsort functions as compare functions,
18// because they dereference the left and right arguments first! 19// because they dereference the left and right arguments first!
19void list_qsort(list_t *list, int compare(const void *left, const void *right)); 20void list_qsort(list_t *list, int compare(const void *left, const void *right));
diff --git a/include/sway/server.h b/include/sway/server.h
index bd96b085..0efc6baa 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -47,7 +47,7 @@ struct sway_server {
47 47
48 bool debug_txn_timings; 48 bool debug_txn_timings;
49 49
50 struct sway_transaction *head_transaction; // singly linked list 50 list_t *transactions;
51 51
52 // When a view is being destroyed and is waiting for a transaction to 52 // When a view is being destroyed and is waiting for a transaction to
53 // complete it will be stored here. 53 // complete it will be stored here.
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index c29b6661..7a2e78e5 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -32,7 +32,6 @@ struct sway_transaction {
32 list_t *instructions; // struct sway_transaction_instruction * 32 list_t *instructions; // struct sway_transaction_instruction *
33 size_t num_waiting; 33 size_t num_waiting;
34 size_t num_configures; 34 size_t num_configures;
35 struct sway_transaction *next;
36 struct timespec create_time; 35 struct timespec create_time;
37 struct timespec commit_time; 36 struct timespec commit_time;
38}; 37};
@@ -225,16 +224,24 @@ static void transaction_apply(struct sway_transaction *transaction) {
225 } 224 }
226} 225}
227 226
227/**
228 * For simplicity, we only progress the queue if it can be completely flushed.
229 */
228static void transaction_progress_queue() { 230static void transaction_progress_queue() {
229 struct sway_transaction *transaction = server.head_transaction; 231 // We iterate this list in reverse because we're more likely to find a
230 struct sway_transaction *next = NULL; 232 // waiting transactions at the end of the list.
231 while (transaction && !transaction->num_waiting) { 233 for (int i = server.transactions->length - 1; i >= 0; --i) {
232 next = transaction->next; 234 struct sway_transaction *transaction = server.transactions->items[i];
235 if (transaction->num_waiting) {
236 return;
237 }
238 }
239 for (int i = 0; i < server.transactions->length; ++i) {
240 struct sway_transaction *transaction = server.transactions->items[i];
233 transaction_apply(transaction); 241 transaction_apply(transaction);
234 transaction_destroy(transaction); 242 transaction_destroy(transaction);
235 transaction = next;
236 } 243 }
237 server.head_transaction = transaction; 244 list_empty(server.transactions);
238} 245}
239 246
240static int handle_timeout(void *data) { 247static int handle_timeout(void *data) {
@@ -295,18 +302,8 @@ void transaction_commit(struct sway_transaction *transaction) {
295 if (server.debug_txn_timings) { 302 if (server.debug_txn_timings) {
296 clock_gettime(CLOCK_MONOTONIC, &transaction->commit_time); 303 clock_gettime(CLOCK_MONOTONIC, &transaction->commit_time);
297 } 304 }
298 if (server.head_transaction) { 305 if (server.transactions->length || transaction->num_waiting) {
299 // There is another transaction in progress - we must add this one to 306 list_add(server.transactions, transaction);
300 // the queue so we complete after it.
301 struct sway_transaction *tail = server.head_transaction;
302 while (tail->next) {
303 tail = tail->next;
304 }
305 tail->next = transaction;
306 } else if (transaction->num_waiting) {
307 // There are no other transactions, but we're not applying immediately
308 // so we must jump in the queue so others will queue behind us.
309 server.head_transaction = transaction;
310 } else { 307 } else {
311 // There are no other transactions in progress, and this one has nothing 308 // There are no other transactions in progress, and this one has nothing
312 // to wait for, so we can skip the queue. 309 // to wait for, so we can skip the queue.
@@ -359,12 +356,24 @@ static void set_instruction_ready(
359 } 356 }
360} 357}
361 358
359/**
360 * Mark all of the view's instructions as ready up to and including the
361 * instruction at the given index. This allows the view to skip a configure.
362 */
363static void set_instructions_ready(struct sway_view *view, int index) {
364 for (int i = 0; i <= index; ++i) {
365 struct sway_transaction_instruction *instruction =
366 view->swayc->instructions->items[i];
367 set_instruction_ready(instruction);
368 }
369}
370
362void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) { 371void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) {
363 for (int i = 0; i < view->swayc->instructions->length; ++i) { 372 for (int i = 0; i < view->swayc->instructions->length; ++i) {
364 struct sway_transaction_instruction *instruction = 373 struct sway_transaction_instruction *instruction =
365 view->swayc->instructions->items[i]; 374 view->swayc->instructions->items[i];
366 if (instruction->serial == serial && !instruction->ready) { 375 if (instruction->serial == serial && !instruction->ready) {
367 set_instruction_ready(instruction); 376 set_instructions_ready(view, i);
368 return; 377 return;
369 } 378 }
370 } 379 }
@@ -377,7 +386,7 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
377 view->swayc->instructions->items[i]; 386 view->swayc->instructions->items[i];
378 if (!instruction->ready && instruction->state.view_width == width && 387 if (!instruction->ready && instruction->state.view_width == width &&
379 instruction->state.view_height == height) { 388 instruction->state.view_height == height) {
380 set_instruction_ready(instruction); 389 set_instructions_ready(view, i);
381 return; 390 return;
382 } 391 }
383 } 392 }
diff --git a/sway/server.c b/sway/server.c
index a2bc5702..884d971e 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -119,6 +119,8 @@ bool server_init(struct sway_server *server) {
119 } 119 }
120 server->destroying_containers = create_list(); 120 server->destroying_containers = create_list();
121 121
122 server->transactions = create_list();
123
122 input_manager = input_manager_create(server); 124 input_manager = input_manager_create(server);
123 return true; 125 return true;
124} 126}
@@ -127,6 +129,7 @@ void server_fini(struct sway_server *server) {
127 // TODO: free sway-specific resources 129 // TODO: free sway-specific resources
128 wl_display_destroy(server->wl_display); 130 wl_display_destroy(server->wl_display);
129 list_free(server->destroying_containers); 131 list_free(server->destroying_containers);
132 list_free(server->transactions);
130} 133}
131 134
132void server_run(struct sway_server *server) { 135void server_run(struct sway_server *server) {