Bugfix: IPC: Correctly handle the case when multiple messages get received at once via the socket

When the sending application was so fast (*cough*) that the messages
could get queued by the kernel, it may happen that we receive multiple
messages at once.
This commit is contained in:
Michael Stapelberg 2009-10-07 21:49:24 +02:00
parent acb07b95c0
commit 3779f9292f
1 changed files with 29 additions and 13 deletions

View File

@ -77,10 +77,16 @@ static void ipc_handle_message(uint8_t *message, int size,
LOG("payload as a string = %s\n", message);
switch (message_type) {
case I3_IPC_MESSAGE_TYPE_COMMAND:
parse_command(global_conn, (const char*)message);
case I3_IPC_MESSAGE_TYPE_COMMAND: {
/* To get a properly terminated buffer, we copy
* message_size bytes out of the buffer */
char *command = scalloc(message_size);
strncpy(command, (const char*)message, message_size);
parse_command(global_conn, (const char*)command);
free(command);
break;
}
default:
LOG("unhandled ipc message\n");
break;
@ -148,6 +154,8 @@ static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
}
uint8_t *message = (uint8_t*)buf;
while (n > 0) {
LOG("IPC: n = %d\n", n);
message += strlen(I3_IPC_MAGIC);
n -= strlen(I3_IPC_MAGIC);
@ -156,12 +164,20 @@ static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
message += sizeof(uint32_t);
n -= sizeof(uint32_t);
if (message_size > n) {
LOG("IPC: Either the message size was wrong or the message was not read completely, dropping\n");
return;
}
/* The last 32 bits of the header are the message type */
uint32_t message_type = *((uint32_t*)message);
message += sizeof(uint32_t);
n -= sizeof(uint32_t);
ipc_handle_message(message, n, message_size, message_type);
n -= message_size;
message += message_size;
}
}
/*