diff options
Diffstat (limited to 'gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc')
-rw-r--r-- | gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc | 197 |
1 files changed, 98 insertions, 99 deletions
diff --git a/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc b/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc index 919986c608..3eef159d73 100644 --- a/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc +++ b/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc @@ -42,9 +42,8 @@ namespace gr { - vmcircbuf_mmap_shm_open::vmcircbuf_mmap_shm_open(int size) - : gr::vmcircbuf(size) - { +vmcircbuf_mmap_shm_open::vmcircbuf_mmap_shm_open(int size) : gr::vmcircbuf(size) +{ #if !defined(HAVE_MMAP) || !defined(HAVE_SHM_OPEN) fprintf(stderr, "gr::vmcircbuf_mmap_shm_open: mmap or shm_open is not available\n"); throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); @@ -53,9 +52,9 @@ namespace gr { static int s_seg_counter = 0; - if(size <= 0 || (size % gr::pagesize ()) != 0) { - fprintf(stderr, "gr::vmcircbuf_mmap_shm_open: invalid size = %d\n", size); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + if (size <= 0 || (size % gr::pagesize()) != 0) { + fprintf(stderr, "gr::vmcircbuf_mmap_shm_open: invalid size = %d\n", size); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); } int shm_fd = -1; @@ -63,82 +62,89 @@ namespace gr { static bool portable_format = true; // open a new named shared memory segment - while(1) { - if(portable_format) { - - // This is the POSIX recommended "portable format". - // Of course the "portable format" doesn't work on some systems... - - snprintf(seg_name, sizeof(seg_name), - "/gnuradio-%d-%d", getpid(), s_seg_counter); - } - else { - - // Where the "portable format" doesn't work, we try building - // a full filesystem pathname pointing into a suitable temporary directory. - - snprintf(seg_name, sizeof(seg_name), - "%s/gnuradio-%d-%d", gr::tmp_path(), getpid(), s_seg_counter); - } - - shm_fd = shm_open(seg_name, O_RDWR | O_CREAT | O_EXCL, 0600); - if(shm_fd == -1 && errno == EACCES && portable_format) { - portable_format = false; - continue; // try again using "non-portable format" - } - - s_seg_counter++; - - if(shm_fd == -1) { - if(errno == EEXIST) // Named segment already exists (shouldn't happen). Try again - continue; - - char msg[1024]; - snprintf(msg, sizeof(msg), "gr::vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name); - perror(msg); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); - } - break; + while (1) { + if (portable_format) { + + // This is the POSIX recommended "portable format". + // Of course the "portable format" doesn't work on some systems... + + snprintf( + seg_name, sizeof(seg_name), "/gnuradio-%d-%d", getpid(), s_seg_counter); + } else { + + // Where the "portable format" doesn't work, we try building + // a full filesystem pathname pointing into a suitable temporary directory. + + snprintf(seg_name, + sizeof(seg_name), + "%s/gnuradio-%d-%d", + gr::tmp_path(), + getpid(), + s_seg_counter); + } + + shm_fd = shm_open(seg_name, O_RDWR | O_CREAT | O_EXCL, 0600); + if (shm_fd == -1 && errno == EACCES && portable_format) { + portable_format = false; + continue; // try again using "non-portable format" + } + + s_seg_counter++; + + if (shm_fd == -1) { + if (errno == + EEXIST) // Named segment already exists (shouldn't happen). Try again + continue; + + char msg[1024]; + snprintf( + msg, sizeof(msg), "gr::vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name); + perror(msg); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + } + break; } // We've got a new shared memory segment fd open. // Now set it's length to 2x what we really want and mmap it in. - if(ftruncate(shm_fd, (off_t)2 * size) == -1) { - close(shm_fd); // cleanup - perror("gr::vmcircbuf_mmap_shm_open: ftruncate (1)"); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + if (ftruncate(shm_fd, (off_t)2 * size) == -1) { + close(shm_fd); // cleanup + perror("gr::vmcircbuf_mmap_shm_open: ftruncate (1)"); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); } - void *first_copy = mmap(0, 2 * size, - PROT_READ | PROT_WRITE, MAP_SHARED, - shm_fd, (off_t) 0); + void* first_copy = + mmap(0, 2 * size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, (off_t)0); - if(first_copy == MAP_FAILED) { - close(shm_fd); // cleanup - perror("gr::vmcircbuf_mmap_shm_open: mmap (1)"); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + if (first_copy == MAP_FAILED) { + close(shm_fd); // cleanup + perror("gr::vmcircbuf_mmap_shm_open: mmap (1)"); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); } // unmap the 2nd half - if(munmap ((char *) first_copy + size, size) == -1) { - close(shm_fd); // cleanup - perror("gr::vmcircbuf_mmap_shm_open: munmap (1)"); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + if (munmap((char*)first_copy + size, size) == -1) { + close(shm_fd); // cleanup + perror("gr::vmcircbuf_mmap_shm_open: munmap (1)"); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); } // map the first half into the now available hole where the // second half used to be. - void *second_copy = mmap((char*)first_copy + size, size, - PROT_READ | PROT_WRITE, MAP_SHARED, - shm_fd, (off_t)0); - - if(second_copy == MAP_FAILED) { - close(shm_fd); // cleanup - perror("gr::vmcircbuf_mmap_shm_open: mmap (2)"); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + void* second_copy = mmap((char*)first_copy + size, + size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + shm_fd, + (off_t)0); + + if (second_copy == MAP_FAILED) { + close(shm_fd); // cleanup + perror("gr::vmcircbuf_mmap_shm_open: mmap (2)"); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); } -#if 0 // OS/X doesn't allow you to resize the segment +#if 0 // OS/X doesn't allow you to resize the segment // cut the shared memory segment down to size if(ftruncate(shm_fd, (off_t)size) == -1) { @@ -148,61 +154,54 @@ namespace gr { } #endif - close(shm_fd); // fd no longer needed. The mapping is retained. + close(shm_fd); // fd no longer needed. The mapping is retained. - if(shm_unlink(seg_name) == -1) { // unlink the seg_name. - perror("gr::vmcircbuf_mmap_shm_open: shm_unlink"); - throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); + if (shm_unlink(seg_name) == -1) { // unlink the seg_name. + perror("gr::vmcircbuf_mmap_shm_open: shm_unlink"); + throw std::runtime_error("gr::vmcircbuf_mmap_shm_open"); } // Now remember the important stuff d_base = (char*)first_copy; d_size = size; #endif - } +} - vmcircbuf_mmap_shm_open::~vmcircbuf_mmap_shm_open() - { +vmcircbuf_mmap_shm_open::~vmcircbuf_mmap_shm_open() +{ #if defined(HAVE_MMAP) gr::thread::scoped_lock guard(s_vm_mutex); - if(munmap (d_base, 2 * d_size) == -1) { - perror("gr::vmcircbuf_mmap_shm_open: munmap (2)"); + if (munmap(d_base, 2 * d_size) == -1) { + perror("gr::vmcircbuf_mmap_shm_open: munmap (2)"); } #endif - } +} - // ---------------------------------------------------------------- - // The factory interface - // ---------------------------------------------------------------- +// ---------------------------------------------------------------- +// The factory interface +// ---------------------------------------------------------------- - gr::vmcircbuf_factory *vmcircbuf_mmap_shm_open_factory::s_the_factory = 0; +gr::vmcircbuf_factory* vmcircbuf_mmap_shm_open_factory::s_the_factory = 0; - gr::vmcircbuf_factory * - vmcircbuf_mmap_shm_open_factory::singleton() - { - if(s_the_factory) - return s_the_factory; +gr::vmcircbuf_factory* vmcircbuf_mmap_shm_open_factory::singleton() +{ + if (s_the_factory) + return s_the_factory; s_the_factory = new gr::vmcircbuf_mmap_shm_open_factory(); return s_the_factory; - } +} - int - vmcircbuf_mmap_shm_open_factory::granularity() - { - return gr::pagesize(); - } +int vmcircbuf_mmap_shm_open_factory::granularity() { return gr::pagesize(); } - gr::vmcircbuf * - vmcircbuf_mmap_shm_open_factory::make(int size) - { +gr::vmcircbuf* vmcircbuf_mmap_shm_open_factory::make(int size) +{ try { - return new vmcircbuf_mmap_shm_open(size); - } - catch (...) { - return 0; + return new vmcircbuf_mmap_shm_open(size); + } catch (...) { + return 0; } - } +} } /* namespace gr */ |