aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dwyer <ryandwyer1@gmail.com>2018-06-27 19:07:48 +1000
committerRyan Dwyer <ryandwyer1@gmail.com>2018-06-27 19:07:48 +1000
commit9652529cc161e943241d946dac93ab16d5e30ee5 (patch)
treead1b0c728dd970449e7033f3b3eda4b549bd3fab
parente6829c5991cac1bd164f800c14fccd522d702783 (diff)
Allow views to skip configures
To do this properly, the transaction queue will only be processed if it can be completely processed.
-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) {
}
}
+void list_empty(list_t *list) {
+ list->capacity = 10;
+ list->length = 0;
+ free(list->items);
+ list->items = malloc(sizeof(void*) * list->capacity);
+}
+
void list_qsort(list_t *list, int compare(const void *left, const void *right)) {
qsort(list->items, list->length, sizeof(void *), compare);
}
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);
void list_insert(list_t *list, int index, void *item);
void list_del(list_t *list, int index);
void list_cat(list_t *list, list_t *source);
+void list_empty(list_t *list);
// See qsort. Remember to use *_qsort functions as compare functions,
// because they dereference the left and right arguments first!
void 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 {
bool debug_txn_timings;
- struct sway_transaction *head_transaction; // singly linked list
+ list_t *transactions;
// When a view is being destroyed and is waiting for a transaction to
// 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 {
list_t *instructions; // struct sway_transaction_instruction *
size_t num_waiting;
size_t num_configures;
- struct sway_transaction *next;
struct timespec create_time;
struct timespec commit_time;
};
@@ -225,16 +224,24 @@ static void transaction_apply(struct sway_transaction *transaction) {
}
}
+/**
+ * For simplicity, we only progress the queue if it can be completely flushed.
+ */
static void transaction_progress_queue() {
- struct sway_transaction *transaction = server.head_transaction;
- struct sway_transaction *next = NULL;
- while (transaction && !transaction->num_waiting) {
- next = transaction->next;
+ // We iterate this list in reverse because we're more likely to find a
+ // waiting transactions at the end of the list.
+ for (int i = server.transactions->length - 1; i >= 0; --i) {
+ struct sway_transaction *transaction = server.transactions->items[i];
+ if (transaction->num_waiting) {
+ return;
+ }
+ }
+ for (int i = 0; i < server.transactions->length; ++i) {
+ struct sway_transaction *transaction = server.transactions->items[i];
transaction_apply(transaction);
transaction_destroy(transaction);
- transaction = next;
}
- server.head_transaction = transaction;
+ list_empty(server.transactions);
}
static int handle_timeout(void *data) {
@@ -295,18 +302,8 @@ void transaction_commit(struct sway_transaction *transaction) {
if (server.debug_txn_timings) {
clock_gettime(CLOCK_MONOTONIC, &transaction->commit_time);
}
- if (server.head_transaction) {
- // There is another transaction in progress - we must add this one to
- // the queue so we complete after it.
- struct sway_transaction *tail = server.head_transaction;
- while (tail->next) {
- tail = tail->next;
- }
- tail->next = transaction;
- } else if (transaction->num_waiting) {
- // There are no other transactions, but we're not applying immediately
- // so we must jump in the queue so others will queue behind us.
- server.head_transaction = transaction;
+ if (server.transactions->length || transaction->num_waiting) {
+ list_add(server.transactions, transaction);
} else {
// There are no other transactions in progress, and this one has nothing
// to wait for, so we can skip the queue.
@@ -359,12 +356,24 @@ static void set_instruction_ready(
}
}
+/**
+ * Mark all of the view's instructions as ready up to and including the
+ * instruction at the given index. This allows the view to skip a configure.
+ */
+static void set_instructions_ready(struct sway_view *view, int index) {
+ for (int i = 0; i <= index; ++i) {
+ struct sway_transaction_instruction *instruction =
+ view->swayc->instructions->items[i];
+ set_instruction_ready(instruction);
+ }
+}
+
void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) {
for (int i = 0; i < view->swayc->instructions->length; ++i) {
struct sway_transaction_instruction *instruction =
view->swayc->instructions->items[i];
if (instruction->serial == serial && !instruction->ready) {
- set_instruction_ready(instruction);
+ set_instructions_ready(view, i);
return;
}
}
@@ -377,7 +386,7 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
view->swayc->instructions->items[i];
if (!instruction->ready && instruction->state.view_width == width &&
instruction->state.view_height == height) {
- set_instruction_ready(instruction);
+ set_instructions_ready(view, i);
return;
}
}
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) {
}
server->destroying_containers = create_list();
+ server->transactions = create_list();
+
input_manager = input_manager_create(server);
return true;
}
@@ -127,6 +129,7 @@ void server_fini(struct sway_server *server) {
// TODO: free sway-specific resources
wl_display_destroy(server->wl_display);
list_free(server->destroying_containers);
+ list_free(server->transactions);
}
void server_run(struct sway_server *server) {