Skip to content

Commit

Permalink
Merge branch 'docs-default-ipcshm'
Browse files Browse the repository at this point in the history
  • Loading branch information
jbendes committed Feb 16, 2024
2 parents c4572da + 75232db commit c8e91bf
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 30 deletions.
5 changes: 5 additions & 0 deletions docs/transports.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ be used to *summon* the transport:
<td><code> can://&lt;interface&gt;?msgid=&lt;id&gt; </code></td>
<td><code> zcm_create("can://can0?msgid=65536") </code></td>
</tr>
<tr>
<td> Inter-process via Shared Memory (IPCSHM) </td>
<td><code> ipcshm://&lt;shm-region-name&gt;?mtu=&lt;mtu&gt;&amp;depth=&lt;depth&gt; </code></td>
<td><code> zcm_create("ipcshm"), zcm_create("ipcshm://myregion?mtu=100000&depth=128") </code></td>
</tr>
</table>

When no url is provided (i.e. `zcm_create(NULL)`), the `ZCM_DEFAULT_URL` environment variable is
Expand Down
65 changes: 43 additions & 22 deletions zcm/transport/lockfree/lf_shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,64 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <libgen.h>

// like mkdir -p but skips the trailing component
static void mkdir_with_parents(const char *path, mode_t mode)
{
int len = strlen(path);
for (int i = 0; i < len; i++) {
if (path[i]=='/') {
char *dirpath = (char *) malloc(i+1);
strncpy(dirpath, path, i);
dirpath[i]=0;

mkdir(dirpath, mode);
free(dirpath);

i++; // skip the '/'
}
}
}

bool lf_shm_create(const char *name, size_t size)
bool lf_shm_create(const char *path, size_t size)
{
int shm_fd = shm_open(name, O_CREAT|O_RDWR|O_EXCL, 0644);
if (shm_fd < 0) return false;
if (ftruncate(shm_fd, size) < 0) {
mkdir_with_parents(path, 0775);

int shm_fd = open(path, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, 0644);
if (shm_fd < 0) return false;

if (ftruncate(shm_fd, size) < 0) {
close(shm_fd);
return false;
}
close(shm_fd);
return false;
}
close(shm_fd);
return true;
return true;
}

void lf_shm_remove(const char *name)
void lf_shm_remove(const char *path)
{
shm_unlink(name);
unlink(path);
}

void * lf_shm_open(const char *name, size_t * _opt_size)
void * lf_shm_open(const char *path, size_t * _opt_size)
{
int shm_fd = shm_open(name, O_CREAT|O_RDWR, 0755);
if (shm_fd < 0) return NULL;
int shm_fd = open(path, O_RDWR|O_CLOEXEC);
if (shm_fd < 0) return NULL;

struct stat st[1];
if (0 != fstat(shm_fd, st)) return NULL;
size_t size = st->st_size;
struct stat st[1];
if (0 != fstat(shm_fd, st)) return NULL;
size_t size = st->st_size;

void *mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (mem == MAP_FAILED) return NULL;
void *mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (mem == MAP_FAILED) return NULL;

close(shm_fd);
if (_opt_size) *_opt_size = size;
return mem;
close(shm_fd);
if (_opt_size) *_opt_size = size;
return mem;
}

void lf_shm_close(void *shm, size_t size)
{
munmap(shm, size);
munmap(shm, size);
}
6 changes: 3 additions & 3 deletions zcm/transport/lockfree/lf_shm.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
extern "C" {
#endif

bool lf_shm_create(const char *name, size_t size);
void lf_shm_remove(const char *name);
void * lf_shm_open(const char *name, size_t * _opt_size);
bool lf_shm_create(const char *path, size_t size);
void lf_shm_remove(const char *path);
void * lf_shm_open(const char *path, size_t * _opt_size);
void lf_shm_close(void *shm, size_t size);

#ifdef __cplusplus
Expand Down
16 changes: 11 additions & 5 deletions zcm/transport/transport_ipcshm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ struct ZCM_TRANS_CLASSNAME : public zcm_trans_t
ZCM_DEBUG("Init ipcshm:");

const char *region_name = zcm_url_address(url);
if (!region_name[0]) region_name = "default";

ZCM_DEBUG(" address='%s'", region_name);

// Process any url options
Expand Down Expand Up @@ -120,10 +122,14 @@ struct ZCM_TRANS_CLASSNAME : public zcm_trans_t
assert(LF_IS_POW2(page_size)); // Sanity or paranoia..
region_size = LF_ALIGN_UP(region_size, page_size);

bool created = lf_shm_create(region_name, region_size);
ZCM_DEBUG("Shm region created: %d", (int)created);
char region_path[PATH_MAX+1];
snprintf(region_path, sizeof(region_path), "/dev/shm/zcm/ipcshm/%s", region_name);
region_path[PATH_MAX] = 0;

bool created = lf_shm_create(region_path, region_size);
ZCM_DEBUG("Shm region created: %s", created ? "true" : "false");

mem = lf_shm_open(region_name, &shm_size);
mem = lf_shm_open(region_path, &shm_size);
if (shm_size != region_size) {
char *err = sprintf_alloc("IPCSHM Region size mismatch for '%s': "
"expected %zu, got %zu\n"
Expand All @@ -132,8 +138,8 @@ struct ZCM_TRANS_CLASSNAME : public zcm_trans_t
"If you have recently changed the URL parameters "
"and you're certain the\n old segment "
"is unused, then you can simply remove it "
"with 'rm /dev/shm/%s'",
region_name, region_size, shm_size, region_name);
"with 'rm %s'",
region_name, region_size, shm_size, region_path);
ZCM_DEBUG("%s", err);
lf_shm_close(mem, shm_size);
*errmsg = err;
Expand Down

0 comments on commit c8e91bf

Please sign in to comment.