source: lib/data-struct/simple_circular_buffer.c @ 1ed69dc

cachetimestampsdeveloprc-4.0.4ringdecrementfixringperformance
Last change on this file since 1ed69dc was 1ed69dc, checked in by Shane Alcock <salcock@…>, 3 years ago

Be less casual with error checking in SCB data structure

  • ftruncate can fail, so actually check for that during init.
  • If this does happen, return an error from libtrace_scb_init() -- this means that libtrace_scb_init() now returns an int rather than void.
  • Update other API functions to make sure that they don't die horribly if the error returned by init is ignored.
  • Property mode set to 100644
File size: 2.9 KB
Line 
1#define _GNU_SOURCE
2
3#include <sys/mman.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <stdint.h>
7#include <stdio.h>
8#include <sys/syscall.h>
9#include <sys/stat.h>
10#include <fcntl.h>
11#include <sys/socket.h>
12#include <errno.h>
13
14#include "simple_circular_buffer.h"
15
16DLLEXPORT int libtrace_scb_init(libtrace_scb_t *buf, uint32_t size,
17                uint16_t id) {
18
19        char anonname[32];
20
21        if (size % getpagesize() != 0) {
22                size = ((size / getpagesize()) + 1) * getpagesize();
23        }
24
25        snprintf(anonname, 32, "lt_scb_%u", id);
26#ifdef HAVE_MEMFD_CREATE
27        buf->fd = syscall(__NR_memfd_create, anonname, 0);
28#else
29        buf->fd = shm_open(anonname, O_RDWR | O_CREAT, 0600);
30#endif
31        if (ftruncate(buf->fd, size) < 0) {
32                perror("ftruncate in libtrace_scb_init");
33                close(buf->fd);
34                buf->fd = -1;
35                buf->address = NULL;
36        } else {
37                buf->address = mmap(NULL, 2 * size, PROT_NONE,
38                                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
39                mmap(buf->address, size, PROT_READ | PROT_WRITE,
40                                MAP_SHARED | MAP_FIXED, buf->fd, 0);
41                mmap(buf->address + size, size, PROT_READ | PROT_WRITE,
42                                MAP_SHARED | MAP_FIXED, buf->fd, 0);
43        }
44        buf->read_offset = 0;
45        buf->write_offset = 0;
46        buf->count_bytes = size;
47
48        if (buf->address) {
49                return 0;
50        }
51        return -1;
52}
53
54DLLEXPORT void libtrace_scb_destroy(libtrace_scb_t *buf) {
55        /* TODO shm_unlink the file name if we used shm_open? */
56
57        if (buf->address) {
58                munmap(buf->address, buf->count_bytes * 2);
59        }
60        if (buf->fd != -1) {
61                close(buf->fd);
62        }
63}
64
65DLLEXPORT int libtrace_scb_recv_sock(libtrace_scb_t *buf, int sock,
66                int recvflags) {
67        int space = buf->count_bytes - (buf->write_offset - buf->read_offset);
68        int ret;
69
70        if (buf->address == NULL) {
71                return -1;
72        }
73
74        if (space == 0) {
75                return buf->count_bytes;
76        }
77
78        ret = recv(sock, buf->address + buf->write_offset, space, recvflags);
79        if (ret < 0) {
80                return ret;
81        }
82        buf->write_offset += ret;
83        return (buf->write_offset - buf->read_offset);
84}
85
86DLLEXPORT uint8_t *libtrace_scb_get_read(libtrace_scb_t *buf,
87                uint32_t *available) {
88
89        if (buf->address == NULL) {
90                return NULL;
91        }
92        *available = buf->write_offset - buf->read_offset;
93        return buf->address + buf->read_offset;
94}
95
96DLLEXPORT void libtrace_scb_advance_read(libtrace_scb_t *buf,
97                uint32_t forward) {
98
99        buf->read_offset += forward;
100        if (buf->read_offset >= buf->count_bytes) {
101                buf->read_offset -= buf->count_bytes;
102                buf->write_offset -= buf->count_bytes;
103        }
104}
Note: See TracBrowser for help on using the repository browser.