mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
ipc: Make send_and_get_reply thread safe
When multiple threads call OpenXR functions, make sure one thread can not read the reply meant for another thread. Unfortunately this also blocks other OpenXR functions from being called while xrWaitFrame() is blocking.
This commit is contained in:
parent
d491f59b55
commit
7ab1ca727f
|
@ -13,6 +13,8 @@
|
|||
#include "xrt/xrt_compiler.h"
|
||||
#include "ipc_protocol.h"
|
||||
|
||||
#include "util/u_threading.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
@ -77,6 +79,8 @@ typedef struct ipc_connection
|
|||
struct ipc_shared_memory *ism;
|
||||
int ism_fd;
|
||||
|
||||
struct os_mutex mutex;
|
||||
|
||||
bool print_debug; // TODO: link to settings
|
||||
bool print_spew; // TODO: link to settings
|
||||
|
||||
|
|
|
@ -149,6 +149,8 @@ ipc_client_instance_destroy(struct xrt_instance *xinst)
|
|||
if (ii->ipc_c.socket_fd >= 0)
|
||||
close(ii->ipc_c.socket_fd);
|
||||
|
||||
os_mutex_destroy(&ii->ipc_c.mutex);
|
||||
|
||||
free(ii);
|
||||
}
|
||||
|
||||
|
@ -230,6 +232,8 @@ ipc_instance_create(struct xrt_instance **out_xinst)
|
|||
|
||||
*out_xinst = &ii->base;
|
||||
|
||||
os_mutex_init(&ii->ipc_c.mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
ipc_result_t
|
||||
ipc_client_send_and_get_reply(struct ipc_connection *ipc_c,
|
||||
void *msg_ptr,
|
||||
|
@ -25,14 +24,19 @@ ipc_client_send_and_get_reply(struct ipc_connection *ipc_c,
|
|||
void *reply_ptr,
|
||||
size_t reply_size)
|
||||
{
|
||||
// Other threads must not read/write the fd while we wait for reply
|
||||
os_mutex_lock(&ipc_c->mutex);
|
||||
|
||||
if (ipc_c->socket_fd < 0) {
|
||||
IPC_ERROR(ipc_c, "Error sending - not connected!");
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return IPC_FAILURE;
|
||||
}
|
||||
|
||||
ssize_t len = send(ipc_c->socket_fd, msg_ptr, msg_size, 0);
|
||||
if ((size_t)len != msg_size) {
|
||||
IPC_ERROR(ipc_c, "Error sending - cannot continue!");
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return IPC_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -51,17 +55,21 @@ ipc_client_send_and_get_reply(struct ipc_connection *ipc_c,
|
|||
msg.msg_flags = 0;
|
||||
|
||||
len = recvmsg(ipc_c->socket_fd, &msg, 0);
|
||||
|
||||
if (len < 0) {
|
||||
IPC_ERROR(ipc_c, "recvmsg failed with error: %s",
|
||||
strerror(errno));
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return IPC_FAILURE;
|
||||
}
|
||||
|
||||
if ((size_t)len != reply_size) {
|
||||
IPC_ERROR(ipc_c, "recvmsg failed with error: wrong size");
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return IPC_FAILURE;
|
||||
}
|
||||
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -74,8 +82,11 @@ ipc_client_send_and_get_reply_fds(ipc_connection_t *ipc_c,
|
|||
int *fds,
|
||||
size_t num_fds)
|
||||
{
|
||||
os_mutex_lock(&ipc_c->mutex);
|
||||
|
||||
if (send(ipc_c->socket_fd, msg_ptr, msg_size, 0) == -1) {
|
||||
IPC_ERROR(ipc_c, "Error sending - cannot continue!");
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return IPC_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -98,17 +109,21 @@ ipc_client_send_and_get_reply_fds(ipc_connection_t *ipc_c,
|
|||
if (len < 0) {
|
||||
IPC_ERROR(ipc_c, "recvmsg failed with error: %s",
|
||||
strerror(errno));
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
IPC_ERROR(ipc_c, "recvmsg failed with error: no data");
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
memcpy(fds, (int *)CMSG_DATA(cmsg), fds_size);
|
||||
|
||||
os_mutex_unlock(&ipc_c->mutex);
|
||||
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue