Removed additional event socket to reduce synchronisation problems
and limited workspace update requests count.
This commit is contained in:
Ilya Lukyanov 2017-08-04 15:16:05 +03:00
parent f8d0e1f946
commit 8dec814bb4
No known key found for this signature in database
GPG key ID: 382C32164F3D37D4
5 changed files with 49 additions and 19 deletions

View file

@ -88,7 +88,7 @@ void free_ipc_response(struct ipc_response *response) {
free(response); free(response);
} }
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) { void ipc_single_command_no_response(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
char data[ipc_header_size]; char data[ipc_header_size];
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
memcpy(data, ipc_magic, sizeof(ipc_magic)); memcpy(data, ipc_magic, sizeof(ipc_magic));
@ -102,6 +102,10 @@ char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint3
if (write(socketfd, payload, *len) == -1) { if (write(socketfd, payload, *len) == -1) {
sway_abort("Unable to send IPC payload"); sway_abort("Unable to send IPC payload");
} }
}
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
ipc_single_command_no_response(socketfd, type, payload, len);
struct ipc_response *resp = ipc_recv_response(socketfd); struct ipc_response *resp = ipc_recv_response(socketfd);
char *response = resp->payload; char *response = resp->payload;

View file

@ -23,6 +23,10 @@ char *get_socketpath(void);
* Opens the sway socket. * Opens the sway socket.
*/ */
int ipc_open_socket(const char *socket_path); int ipc_open_socket(const char *socket_path);
/**
* Issues a single IPC command without reading response.
*/
void ipc_single_command_no_response(int socketfd, uint32_t type, const char *payload, uint32_t *len);
/** /**
* Issues a single IPC command and returns the buffer. len will be updated with * Issues a single IPC command and returns the buffer. len will be updated with
* the length of the buffer returned from sway. * the length of the buffer returned from sway.

View file

@ -15,6 +15,8 @@ struct bar {
int ipc_socketfd; int ipc_socketfd;
int status_read_fd; int status_read_fd;
pid_t status_command_pid; pid_t status_command_pid;
int pending_ipc_requests;
}; };
struct output { struct output {

View file

@ -155,7 +155,6 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) {
/* connect to sway ipc */ /* connect to sway ipc */
bar->ipc_socketfd = ipc_open_socket(socket_path); bar->ipc_socketfd = ipc_open_socket(socket_path);
bar->ipc_event_socketfd = ipc_open_socket(socket_path);
ipc_bar_init(bar, bar_id); ipc_bar_init(bar, bar_id);
@ -205,7 +204,7 @@ bool dirty = true;
static void respond_ipc(int fd, short mask, void *_bar) { static void respond_ipc(int fd, short mask, void *_bar) {
struct bar *bar = (struct bar *)_bar; struct bar *bar = (struct bar *)_bar;
sway_log(L_DEBUG, "Got IPC event."); sway_log(L_DEBUG, "Got IPC event or reply.");
dirty = handle_ipc_event(bar); dirty = handle_ipc_event(bar);
} }
@ -222,7 +221,7 @@ static void respond_output(int fd, short mask, void *_output) {
} }
void bar_run(struct bar *bar) { void bar_run(struct bar *bar) {
add_event(bar->ipc_event_socketfd, POLLIN, respond_ipc, bar); add_event(bar->ipc_socketfd, POLLIN, respond_ipc, bar);
add_event(bar->status_read_fd, POLLIN, respond_command, bar); add_event(bar->status_read_fd, POLLIN, respond_command, bar);
int i; int i;
@ -322,10 +321,6 @@ void bar_teardown(struct bar *bar) {
close(bar->ipc_socketfd); close(bar->ipc_socketfd);
} }
if (bar->ipc_event_socketfd) {
close(bar->ipc_event_socketfd);
}
/* terminate status command process */ /* terminate status command process */
terminate_status_command(bar->status_command_pid); terminate_status_command(bar->status_command_pid);
} }

View file

@ -14,7 +14,7 @@ void ipc_send_workspace_command(const char *workspace_name) {
char command[size]; char command[size];
sprintf(command, "workspace \"%s\"", workspace_name); sprintf(command, "workspace \"%s\"", workspace_name);
ipc_single_command(swaybar.ipc_socketfd, IPC_COMMAND, command, &size); ipc_single_command_no_response(swaybar.ipc_socketfd, IPC_COMMAND, command, &size);
} }
static void ipc_parse_config(struct config *config, const char *payload) { static void ipc_parse_config(struct config *config, const char *payload) {
@ -249,7 +249,27 @@ static void ipc_parse_config(struct config *config, const char *payload) {
json_object_put(bar_config); json_object_put(bar_config);
} }
static void ipc_update_workspaces(struct bar *bar) { static void ipc_update_workspaces_request(struct bar *bar) {
uint32_t len = 0;
if (bar->pending_ipc_requests >= 10) {
sway_log(L_DEBUG, "Ignoring update request");
return;
}
bar->pending_ipc_requests++;
sway_log(L_DEBUG, "Sending update request, %d pending", bar->pending_ipc_requests);
ipc_single_command_no_response(bar->ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len);
}
static void ipc_update_workspaces_response(struct bar *bar, char *res) {
bar->pending_ipc_requests--;
sway_log(L_DEBUG, "Got update response, %d pending", bar->pending_ipc_requests);
if (bar->pending_ipc_requests < 0) {
sway_log(L_DEBUG, "Unexpected update response");
bar->pending_ipc_requests = 0;
}
int i; int i;
for (i = 0; i < bar->outputs->length; ++i) { for (i = 0; i < bar->outputs->length; ++i) {
struct output *output = bar->outputs->items[i]; struct output *output = bar->outputs->items[i];
@ -259,11 +279,8 @@ static void ipc_update_workspaces(struct bar *bar) {
output->workspaces = create_list(); output->workspaces = create_list();
} }
uint32_t len = 0;
char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len);
json_object *results = json_tokener_parse(res); json_object *results = json_tokener_parse(res);
if (!results) { if (!results) {
free(res);
return; return;
} }
@ -303,7 +320,6 @@ static void ipc_update_workspaces(struct bar *bar) {
} }
json_object_put(results); json_object_put(results);
free(res);
} }
void ipc_bar_init(struct bar *bar, const char *bar_id) { void ipc_bar_init(struct bar *bar, const char *bar_id) {
@ -359,22 +375,27 @@ void ipc_bar_init(struct bar *bar, const char *bar_id) {
free(res); free(res);
json_object_put(outputs); json_object_put(outputs);
ipc_update_workspaces_request(bar);
// This will handle update response, since we haven't subscribed yet
handle_ipc_event(bar);
const char *subscribe_json = "[ \"workspace\", \"mode\" ]"; const char *subscribe_json = "[ \"workspace\", \"mode\" ]";
len = strlen(subscribe_json); len = strlen(subscribe_json);
res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); res = ipc_single_command(bar->ipc_socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
free(res); free(res);
ipc_update_workspaces(bar);
} }
bool handle_ipc_event(struct bar *bar) { bool handle_ipc_event(struct bar *bar) {
struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); struct ipc_response *resp = ipc_recv_response(bar->ipc_socketfd);
if (!resp) { if (!resp) {
return false; return false;
} }
switch (resp->type) { switch (resp->type) {
case IPC_EVENT_WORKSPACE: case IPC_EVENT_WORKSPACE:
ipc_update_workspaces(bar); ipc_update_workspaces_request(bar);
// This should read update response, but if there are events
// in socket, there shouldn't be problems.
handle_ipc_event(bar);
break; break;
case IPC_EVENT_MODE: { case IPC_EVENT_MODE: {
json_object *result = json_tokener_parse(resp->payload); json_object *result = json_tokener_parse(resp->payload);
@ -400,7 +421,11 @@ bool handle_ipc_event(struct bar *bar) {
json_object_put(result); json_object_put(result);
break; break;
} }
case IPC_GET_WORKSPACES:
ipc_update_workspaces_response(bar, resp->payload);
break;
default: default:
sway_log(L_DEBUG, "Unknown message type: 0x%x", resp->type);
free_ipc_response(resp); free_ipc_response(resp);
return false; return false;
} }