Data-Queue-Shared
view release on metacpan or search on metacpan
struct timespec *remaining) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
remaining->tv_sec = deadline->tv_sec - now.tv_sec;
remaining->tv_nsec = deadline->tv_nsec - now.tv_nsec;
if (remaining->tv_nsec < 0) {
remaining->tv_sec--;
remaining->tv_nsec += 1000000000L;
}
return remaining->tv_sec >= 0;
}
/* Convert timeout in seconds (double) to absolute deadline */
static inline void queue_make_deadline(double timeout, struct timespec *deadline) {
clock_gettime(CLOCK_MONOTONIC, deadline);
deadline->tv_sec += (time_t)timeout;
deadline->tv_nsec += (long)((timeout - (double)(time_t)timeout) * 1e9);
if (deadline->tv_nsec >= 1000000000L) {
deadline->tv_sec++;
deadline->tv_nsec -= 1000000000L;
}
}
/* ================================================================
* Create / Open / Close
* ================================================================ */
#define QUEUE_ERR(fmt, ...) do { if (errbuf) snprintf(errbuf, QUEUE_ERR_BUFLEN, fmt, ##__VA_ARGS__); } while(0)
static inline void queue_init_new_header(void *base, uint32_t cap, uint64_t arena_cap,
uint32_t slots_off, uint32_t arena_off,
uint32_t mode, uint64_t total_size) {
QueueHeader *hdr = (QueueHeader *)base;
memset(hdr, 0, sizeof(QueueHeader));
hdr->magic = QUEUE_MAGIC;
hdr->version = QUEUE_VERSION;
hdr->mode = mode;
hdr->capacity = cap;
hdr->total_size = total_size;
hdr->slots_off = slots_off;
hdr->arena_off = arena_off;
hdr->arena_cap = arena_cap;
#define INIT_SEQ(STYPE, C) do { \
STYPE *s = (STYPE *)((char *)base + slots_off); \
for (uint32_t _i = 0; _i < (C); _i++) s[_i].sequence = _i; \
} while(0)
if (mode == QUEUE_MODE_INT) INIT_SEQ(QueueIntSlot, cap);
else if (mode == QUEUE_MODE_INT32) INIT_SEQ(QueueInt32Slot, cap);
else if (mode == QUEUE_MODE_INT16) INIT_SEQ(QueueInt16Slot, cap);
#undef INIT_SEQ
__atomic_thread_fence(__ATOMIC_SEQ_CST);
}
/* Securely obtain a fd: create exclusively (O_CREAT|O_EXCL|O_NOFOLLOW at
* file_mode, default 0600 = owner-only), or attach an existing file
* (O_RDWR|O_NOFOLLOW, no O_CREAT). Blocks a symlink swap or a pre-seeded/
* hard-linked backing file; cross-user sharing is opt-in via a wider file_mode. */
static int queue_secure_open(const char *path, mode_t file_mode, char *errbuf) {
for (int attempt = 0; attempt < 100; attempt++) {
int fd = open(path, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, file_mode);
if (fd >= 0) { (void)fchmod(fd, file_mode); return fd; } /* exact mode: umask narrowed the O_EXCL create */
if (errno != EEXIST) { QUEUE_ERR("create(%s): %s", path, strerror(errno)); return -1; }
fd = open(path, O_RDWR|O_NOFOLLOW|O_CLOEXEC);
if (fd >= 0) return fd;
if (errno == ENOENT) continue;
QUEUE_ERR("open(%s): %s", path, strerror(errno));
return -1;
}
QUEUE_ERR("open(%s): create/attach kept racing", path);
return -1;
}
static QueueHandle *queue_create(const char *path, uint32_t capacity,
uint32_t mode, uint64_t arena_cap_hint,
mode_t file_mode, char *errbuf) {
if (errbuf) errbuf[0] = '\0';
uint32_t cap = queue_next_pow2(capacity);
if (cap == 0) { QUEUE_ERR("invalid capacity"); return NULL; }
if (mode > QUEUE_MODE_INT16) { QUEUE_ERR("unknown mode %u", mode); return NULL; }
uint64_t slots_off = sizeof(QueueHeader);
uint64_t slot_size = (mode == QUEUE_MODE_INT) ? sizeof(QueueIntSlot)
: (mode == QUEUE_MODE_INT32) ? sizeof(QueueInt32Slot)
: (mode == QUEUE_MODE_INT16) ? sizeof(QueueInt16Slot)
: sizeof(QueueStrSlot);
uint64_t arena_off = 0, arena_cap = 0;
uint64_t total_size;
if (mode == QUEUE_MODE_STR) {
uint64_t slots_end = slots_off + (uint64_t)cap * slot_size;
arena_off = (slots_end + 7) & ~(uint64_t)7;
arena_cap = arena_cap_hint;
if (arena_cap < 4096) arena_cap = 4096;
if (arena_cap > UINT32_MAX) arena_cap = UINT32_MAX;
total_size = arena_off + arena_cap;
} else {
total_size = slots_off + (uint64_t)cap * slot_size;
}
int anonymous = (path == NULL);
size_t map_size;
void *base;
if (anonymous) {
/* Anonymous shared mmap â fork-inherited, no filesystem */
map_size = (size_t)total_size;
base = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (base == MAP_FAILED) {
QUEUE_ERR("mmap(anonymous): %s", strerror(errno));
return NULL;
}
queue_init_new_header(base, cap, arena_cap, slots_off, arena_off, mode, total_size);
} else {
/* File-backed shared mmap */
int fd = queue_secure_open(path, file_mode, errbuf);
if (fd < 0) return NULL;
if (flock(fd, LOCK_EX) < 0) {
QUEUE_ERR("flock(%s): %s", path, strerror(errno));
( run in 1.561 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )