if (table->allocated_len >= table->size)
return NULL;
- obj = &table->objects[table->allocated_len++];
+ obj = &table->objects[table->allocated_len];
/* wait_fd: create pipe */
ret = pipe(waitfd);
PERROR("fcntl");
goto error_fcntl;
}
- *obj->wait_fd = *waitfd;
+ memcpy(obj->wait_fd, waitfd, sizeof(waitfd));
/* shm_fd: create shm */
* We specifically do _not_ use the / at the beginning of the
* pathname so that some OS implementations can keep it local to
* the process (POSIX leaves this implementation-defined).
+ * Ignore the shm_unlink errors, because we handle leaks that
+ * could occur by applications crashing between shm_open and
+ * shm_unlink by unlinking the shm before every open. Therefore,
+ * we can only leak one single shm (and only if the application
+ * crashes between shm_open and the following shm_unlink).
*/
do {
+ ret = shm_unlink("ust-shm-tmp");
+ if (ret < 0 && errno != ENOENT) {
+ PERROR("shm_unlink");
+ goto error_shm_unlink;
+ }
shmfd = shm_open("ust-shm-tmp",
O_CREAT | O_EXCL | O_RDWR, 0700);
} while (shmfd < 0 && errno == EEXIST);
goto error_shm_open;
}
ret = shm_unlink("ust-shm-tmp");
- if (ret) {
+ if (ret < 0 && errno != ENOENT) {
PERROR("shm_unlink");
- goto error_unlink;
+ goto error_shm_release;
}
ret = ftruncate(shmfd, memory_map_size);
if (ret) {
obj->memory_map = memory_map;
obj->memory_map_size = memory_map_size;
obj->allocated_len = 0;
+ obj->index = table->allocated_len++;
+
return obj;
error_mmap:
error_ftruncate:
-error_unlink:
+error_shm_release:
ret = close(shmfd);
if (ret) {
PERROR("close");
assert(0);
}
+error_shm_unlink:
error_shm_open:
error_fcntl:
for (i = 0; i < 2; i++) {
}
}
error_pipe:
- free(obj);
return NULL;
}