📄 gr_vmcircbuf_sysv_shm.cc
字号:
/* -*- c++ -*- *//* * Copyright 2003 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GNU Radio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <gr_vmcircbuf_sysv_shm.h>#include <stdexcept>#include <assert.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#ifdef HAVE_SYS_IPC_H#include <sys/ipc.h>#endif#ifdef HAVE_SYS_SHM_H#include <sys/shm.h>#endif#include <errno.h>#include <stdio.h>#include <gr_pagesize.h>gr_vmcircbuf_sysv_shm::gr_vmcircbuf_sysv_shm (int size) : gr_vmcircbuf (size){#if !defined(HAVE_SYS_SHM_H) fprintf (stderr, "gr_vmcircbuf_sysv_shm: sysv shared memory is not available\n"); throw std::runtime_error ("gr_vmcircbuf_sysv_shm");#else if (size <= 0 || (size % gr_pagesize ()) != 0){ fprintf (stderr, "gr_vmcircbuf_sysv_shm: invalid size = %d\n", size); throw std::runtime_error ("gr_vmcircbuf_sysv_shm"); } int shmid1 = -1; int shmid2 = -1; if ((shmid2 = shmget (IPC_PRIVATE, 2 * size, IPC_CREAT | 0700)) == -1){ perror ("gr_vmcircbuf_sysv_shm: shmget (1)"); throw std::runtime_error ("gr_vmcircbuf_sysv_shm"); } if ((shmid1 = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700)) == -1){ perror ("gr_vmcircbuf_sysv_shm: shmget (2)"); shmctl (shmid2, IPC_RMID, 0); throw std::runtime_error ("gr_vmcircbuf_sysv_shm"); } void *first_copy = shmat (shmid2, 0, 0); if (first_copy == (void *) -1){ perror ("gr_vmcircbuf_sysv_shm: shmat (1)"); shmctl (shmid2, IPC_RMID, 0); shmctl (shmid1, IPC_RMID, 0); throw std::runtime_error ("gr_vmcircbuf_sysv_shm"); } shmctl (shmid2, IPC_RMID, 0); // There may be a race between our detach and attach. // // If the system allocates all shared memory segments at the same // virtual addresses in all processes and if the system allocates // some other segment to first_copy or first_copoy + size between // our detach and attach, the attaches below could fail [I've never // seen it fail for this reason]. shmdt (first_copy); if (shmat (shmid1, first_copy, 0) == (void *) -1){ perror ("gr_vmcircbuf_sysv_shm: shmat (2)"); shmctl (shmid1, IPC_RMID, 0); throw std::runtime_error ("gr_vmcircbuf_sysv_shm"); } if (shmat (shmid1, (char *) first_copy + size, 0) == (void *) -1){ perror ("gr_vmcircbuf_sysv_shm: shmat (3)"); shmctl (shmid1, IPC_RMID, 0); shmdt (first_copy); throw std::runtime_error ("gr_vmcircbuf_sysv_shm"); } shmctl (shmid1, IPC_RMID, 0); // Now remember the important stuff d_base = (char *) first_copy; d_size = size;#endif}gr_vmcircbuf_sysv_shm::~gr_vmcircbuf_sysv_shm (){#if defined(HAVE_SYS_SHM_H) if (shmdt (d_base) == -1 || shmdt (d_base + d_size) == -1){ perror ("gr_vmcircbuf_sysv_shm: shmdt (2)"); }#endif}// ----------------------------------------------------------------// The factory interface// ----------------------------------------------------------------gr_vmcircbuf_factory *gr_vmcircbuf_sysv_shm_factory::s_the_factory = 0;gr_vmcircbuf_factory *gr_vmcircbuf_sysv_shm_factory::singleton (){ if (s_the_factory) return s_the_factory; s_the_factory = new gr_vmcircbuf_sysv_shm_factory (); return s_the_factory;}intgr_vmcircbuf_sysv_shm_factory::granularity (){ return gr_pagesize ();}gr_vmcircbuf *gr_vmcircbuf_sysv_shm_factory::make (int size){ try { return new gr_vmcircbuf_sysv_shm (size); } catch (...){ return 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -