Skip to content

Commit 7e81e7e

Browse files
committed
open_ipc_handle should use shm from handle
1 parent e6ff45e commit 7e81e7e

File tree

4 files changed

+84
-32
lines changed

4 files changed

+84
-32
lines changed

examples/ipc_ipcapi/ipc_ipcapi_shm.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
2020
rm -f /dev/shm/${SHM_NAME}
2121

2222
echo "Starting ipc_ipcapi_shm CONSUMER on port $PORT ..."
23-
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_ipcapi_consumer $PORT $SHM_NAME &
23+
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_ipcapi_consumer $PORT &
2424

2525
echo "Waiting 1 sec ..."
2626
sleep 1

src/provider/provider_os_memory.c

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,10 @@ typedef struct os_ipc_data_t {
11461146
int fd;
11471147
size_t fd_offset;
11481148
size_t size;
1149-
char shm_name[NAME_MAX]; // optional - can be used or not (see below)
1149+
// shm_name is a Flexible Array Member because it is optional and its size
1150+
// varies on the Shared Memory object name
1151+
size_t shm_name_len;
1152+
char shm_name[];
11501153
} os_ipc_data_t;
11511154

11521155
static umf_result_t os_get_ipc_handle_size(void *provider, size_t *size) {
@@ -1160,13 +1163,8 @@ static umf_result_t os_get_ipc_handle_size(void *provider, size_t *size) {
11601163
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
11611164
}
11621165

1163-
if (os_provider->shm_name[0]) {
1164-
// os_ipc_data_t->shm_name will be used
1165-
*size = sizeof(os_ipc_data_t);
1166-
} else {
1167-
// os_ipc_data_t->shm_name will NOT be used
1168-
*size = sizeof(os_ipc_data_t) - NAME_MAX;
1169-
}
1166+
// NOTE: +1 for '\0' at the end of the string
1167+
*size = sizeof(os_ipc_data_t) + strlen(os_provider->shm_name) + 1;
11701168

11711169
return UMF_RESULT_SUCCESS;
11721170
}
@@ -1195,9 +1193,10 @@ static umf_result_t os_get_ipc_handle(void *provider, const void *ptr,
11951193
os_ipc_data->pid = utils_getpid();
11961194
os_ipc_data->fd_offset = (size_t)value - 1;
11971195
os_ipc_data->size = size;
1198-
if (os_provider->shm_name[0]) {
1199-
strncpy(os_ipc_data->shm_name, os_provider->shm_name, NAME_MAX - 1);
1200-
os_ipc_data->shm_name[NAME_MAX - 1] = '\0';
1196+
os_ipc_data->shm_name_len = strlen(os_provider->shm_name);
1197+
if (os_ipc_data->shm_name_len > 0) {
1198+
strncpy(os_ipc_data->shm_name, os_provider->shm_name,
1199+
os_ipc_data->shm_name_len);
12011200
} else {
12021201
os_ipc_data->fd = os_provider->fd;
12031202
}
@@ -1222,8 +1221,12 @@ static umf_result_t os_put_ipc_handle(void *provider, void *providerIpcData) {
12221221
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
12231222
}
12241223

1225-
if (os_provider->shm_name[0]) {
1226-
if (strncmp(os_ipc_data->shm_name, os_provider->shm_name, NAME_MAX)) {
1224+
size_t shm_name_len = strlen(os_provider->shm_name);
1225+
if (shm_name_len > 0) {
1226+
if (os_ipc_data->shm_name_len != shm_name_len) {
1227+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
1228+
} else if (strncmp(os_ipc_data->shm_name, os_provider->shm_name,
1229+
shm_name_len)) {
12271230
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
12281231
}
12291232
} else {
@@ -1251,14 +1254,14 @@ static umf_result_t os_open_ipc_handle(void *provider, void *providerIpcData,
12511254
umf_result_t ret = UMF_RESULT_SUCCESS;
12521255
int fd;
12531256

1254-
if (os_provider->shm_name[0]) {
1255-
fd = utils_shm_open(os_provider->shm_name);
1257+
if (os_ipc_data->shm_name_len) {
1258+
fd = utils_shm_open(os_ipc_data->shm_name);
12561259
if (fd <= 0) {
12571260
LOG_PERR("opening a shared memory file (%s) failed",
1258-
os_provider->shm_name);
1261+
os_ipc_data->shm_name);
12591262
return UMF_RESULT_ERROR_UNKNOWN;
12601263
}
1261-
(void)utils_shm_unlink(os_provider->shm_name);
1264+
(void)utils_shm_unlink(os_ipc_data->shm_name);
12621265
} else {
12631266
umf_result_t umf_result =
12641267
utils_duplicate_fd(os_ipc_data->pid, os_ipc_data->fd, &fd);

test/common/ipc_common.c

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "ipc_common.h"
1616

1717
#define INET_ADDR "127.0.0.1"
18-
#define MSG_SIZE 1024
18+
#define MSG_SIZE 1024 * 8
1919

2020
// consumer's response message
2121
#define CONSUMER_MSG \
@@ -33,6 +33,10 @@ Generally communication between the producer and the consumer looks like:
3333
- Producer creates a socket
3434
- Producer connects to the consumer
3535
- Consumer connects at IP 127.0.0.1 and a port to the producer
36+
- Producer sends the IPC handle size to the consumer
37+
- Consumer receives the IPC handle size from the producer
38+
- Consumer sends the confirmation (IPC handle size) to the producer
39+
- Producer receives the confirmation (IPC handle size) from the consumer
3640
- Producer sends the IPC handle to the consumer
3741
- Consumer receives the IPC handle from the producer
3842
- Consumer opens the IPC handle received from the producer
@@ -127,29 +131,36 @@ int run_consumer(int port, umf_memory_provider_ops_t *provider_ops,
127131
return -1;
128132
}
129133

130-
// get the size of the IPC handle
131-
size_t IPC_handle_size;
132-
umf_result = umfMemoryProviderGetIPCHandleSize(provider, &IPC_handle_size);
133-
if (umf_result != UMF_RESULT_SUCCESS) {
134-
fprintf(stderr,
135-
"[consumer] ERROR: getting size of the IPC handle failed\n");
134+
producer_socket = consumer_connect(port);
135+
if (producer_socket < 0) {
136136
goto err_umfMemoryProviderDestroy;
137137
}
138138

139139
// allocate the zeroed receive buffer
140-
char *recv_buffer = calloc(1, IPC_handle_size);
140+
char *recv_buffer = calloc(1, MSG_SIZE);
141141
if (!recv_buffer) {
142142
fprintf(stderr, "[consumer] ERROR: out of memory\n");
143143
goto err_umfMemoryProviderDestroy;
144144
}
145145

146-
producer_socket = consumer_connect(port);
147-
if (producer_socket < 0) {
148-
goto err_umfMemoryProviderDestroy;
146+
// get the size of the IPC handle from the producer
147+
size_t IPC_handle_size;
148+
ssize_t recv_len = recv(producer_socket, recv_buffer, MSG_SIZE, 0);
149+
if (recv_len < 0) {
150+
fprintf(stderr, "[consumer] ERROR: recv() failed\n");
151+
goto err_close_producer_socket;
149152
}
153+
IPC_handle_size = *(size_t *)recv_buffer;
154+
fprintf(stderr, "[consumer] Got the size of the IPC handle: %zu\n",
155+
IPC_handle_size);
156+
157+
// send confirmation to the producer (IPC handle size)
158+
send(producer_socket, &IPC_handle_size, sizeof(IPC_handle_size), 0);
159+
fprintf(stderr,
160+
"[consumer] Send the confirmation (IPC handle size) to producer\n");
150161

151-
// receive a producer's message
152-
ssize_t recv_len = recv(producer_socket, recv_buffer, IPC_handle_size, 0);
162+
// receive IPC handle from the producer
163+
recv_len = recv(producer_socket, recv_buffer, MSG_SIZE, 0);
153164
if (recv_len < 0) {
154165
fprintf(stderr, "[consumer] ERROR: recv() failed\n");
155166
goto err_close_producer_socket;
@@ -388,6 +399,44 @@ int run_producer(int port, umf_memory_provider_ops_t *provider_ops,
388399
goto err_PutIPCHandle;
389400
}
390401

402+
// send the IPC_handle_size to the consumer
403+
ssize_t len =
404+
send(producer_socket, &IPC_handle_size, sizeof(IPC_handle_size), 0);
405+
if (len < 0) {
406+
fprintf(stderr, "[producer] ERROR: unable to send the message\n");
407+
goto err_close_producer_socket;
408+
}
409+
410+
fprintf(stderr,
411+
"[producer] Sent the size of the IPC handle (%zu) to the consumer "
412+
"(sent %zu bytes)\n",
413+
IPC_handle_size, len);
414+
415+
// zero the consumer_message buffer
416+
memset(consumer_message, 0, sizeof(consumer_message));
417+
418+
// receive the consumer's confirmation - IPC handle size
419+
len = recv(producer_socket, consumer_message, sizeof(consumer_message), 0);
420+
if (len < 0) {
421+
fprintf(stderr, "[producer] ERROR: error while receiving the "
422+
"confirmation from the consumer\n");
423+
goto err_close_producer_socket;
424+
}
425+
426+
size_t conf_IPC_handle_size = *(size_t *)consumer_message;
427+
if (conf_IPC_handle_size == IPC_handle_size) {
428+
fprintf(stderr,
429+
"[producer] Received the correct confirmation (%zu) from the "
430+
"consumer (%zu bytes)\n",
431+
conf_IPC_handle_size, len);
432+
} else {
433+
fprintf(stderr,
434+
"[producer] Received an INCORRECT confirmation (%zu) from the "
435+
"consumer (%zu bytes)\n",
436+
conf_IPC_handle_size, len);
437+
goto err_close_producer_socket;
438+
}
439+
391440
// send the IPC_handle of IPC_handle_size to the consumer
392441
if (send(producer_socket, IPC_handle, IPC_handle_size, 0) < 0) {
393442
fprintf(stderr, "[producer] ERROR: unable to send the message\n");

test/ipc_os_prov_shm.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
2020
rm -f /dev/shm/${SHM_NAME}
2121

2222
echo "Starting ipc_os_prov_shm CONSUMER on port $PORT ..."
23-
UMF_LOG=$UMF_LOG_VAL ./umf_test-ipc_os_prov_consumer $PORT $SHM_NAME &
23+
UMF_LOG=$UMF_LOG_VAL ./umf_test-ipc_os_prov_consumer $PORT &
2424

2525
echo "Waiting 1 sec ..."
2626
sleep 1

0 commit comments

Comments
 (0)