port: set shm size with ftruncate before writing
authorMichael Jeanson <mjeanson@efficios.com>
Wed, 4 Nov 2020 15:00:31 +0000 (10:00 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 13 Nov 2020 20:21:12 +0000 (15:21 -0500)
According to POSIX, the size of shared memory object must be set with
ftruncate before writing to it. This happenen to work on Linux because
the implementation simply creates files on a tmpfs but on FreeBSD it is
implemented using actual shared memory objects and as such requires the
size to be set first.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I048f65104d7c34142025337ec1f6777650bfd62f

libringbuffer/shm.c

index 9160c2184f9874841e30802bab2288be30f36894..566ed467fe2f715bc60f56449b222964c8b51acd 100644 (file)
@@ -128,19 +128,27 @@ struct shm_object *_shm_object_table_alloc_shm(struct shm_object_table *table,
        }
        memcpy(obj->wait_fd, waitfd, sizeof(waitfd));
 
-       /* create shm */
+       /*
+        * Set POSIX shared memory object size
+        *
+        * First, use ftruncate() to set its size, some implementations won't
+        * allow writes past the size set by ftruncate.
+        * Then, use write() to fill it with zeros, this allows us to fully
+        * allocate it and detect a shortage of shm space without dealing with
+        * a SIGBUS.
+        */
 
        shmfd = stream_fd;
-       ret = zero_file(shmfd, memory_map_size);
-       if (ret) {
-               PERROR("zero_file");
-               goto error_zero_file;
-       }
        ret = ftruncate(shmfd, memory_map_size);
        if (ret) {
                PERROR("ftruncate");
                goto error_ftruncate;
        }
+       ret = zero_file(shmfd, memory_map_size);
+       if (ret) {
+               PERROR("zero_file");
+               goto error_zero_file;
+       }
        /*
         * Also ensure the file metadata is synced with the storage by using
         * fsync(2).
This page took 0.029697 seconds and 5 git commands to generate.