zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 15573ea56057f8220fe694d25d07690af00e1562
parent 2a655e26a6eb8a2685cbc41edfebdf9dbab4347a
Author: Johannes Lorenz <johannes89@ist-einmalig.de>
Date:   Sun,  9 Aug 2015 04:28:58 +0200

Merge.

Diffstat:
MTODO.txt | 2+-
Msrc/Misc/Allocator.cpp | 10+++++-----
Msrc/Misc/Allocator.h | 39+++++++++++++++++++++++++++++++++------
Msrc/Misc/CMakeLists.txt | 1+
Msrc/Misc/Master.cpp | 2+-
Msrc/Misc/MiddleWare.cpp | 112+++----------------------------------------------------------------------------
Asrc/Misc/TmpFileMgr.cpp | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Misc/TmpFileMgr.h | 18++++++++++++++++++
8 files changed, 176 insertions(+), 122 deletions(-)

diff --git a/TODO.txt b/TODO.txt @@ -14,7 +14,7 @@ Status: (1) will be fixed by fundamental (2) will be fixed with fftw3 (?), until then maybe use separate mutex? (3) will be fixed by fundamental -(4) +(4) fixed + tested (5) fixed + tested (6) fixed + tested (only basic testing) (7) -> will not be fixed (should stay random) diff --git a/src/Misc/Allocator.cpp b/src/Misc/Allocator.cpp @@ -7,7 +7,7 @@ #include "Allocator.h" //Used for dummy allocations -Allocator DummyAlloc; +DummyAllocator DummyAlloc; //recursive type class to avoid void *v = *(void**)v style casting struct next_t @@ -57,7 +57,7 @@ Allocator::~Allocator(void) delete impl; } -void *Allocator::alloc_mem(size_t mem_size) +void *AllocatorClass::alloc_mem(size_t mem_size) { impl->totalAlloced += mem_size; void *mem = tlsf_malloc(impl->tlsf, mem_size); @@ -66,14 +66,14 @@ void *Allocator::alloc_mem(size_t mem_size) //printf("Allocator result = %p\n", mem); return mem; } -void Allocator::dealloc_mem(void *memory) +void AllocatorClass::dealloc_mem(void *memory) { //printf("dealloc_mem(%d)\n", tlsf_block_size(memory)); tlsf_free(impl->tlsf, memory); //free(memory); } -bool Allocator::lowMemory(unsigned n, size_t chunk_size) +bool AllocatorClass::lowMemory(unsigned n, size_t chunk_size) const { //This should stay on the stack void *buf[n]; @@ -90,7 +90,7 @@ bool Allocator::lowMemory(unsigned n, size_t chunk_size) } -void Allocator::addMemory(void *v, size_t mem_size) +void AllocatorClass::addMemory(void *v, size_t mem_size) { next_t *n = impl->pools; while(n->next) n = n->next; diff --git a/src/Misc/Allocator.h b/src/Misc/Allocator.h @@ -2,14 +2,17 @@ #include <cstdlib> #include <utility> +//! Allocator Base class +//! subclasses must specify allocation and deallocation class Allocator { public: Allocator(void); Allocator(const Allocator&) = delete; - ~Allocator(void); - void *alloc_mem(size_t mem_size); - void dealloc_mem(void *memory); + virtual ~Allocator(void); + + virtual void *alloc_mem(size_t mem_size) = 0; + virtual void dealloc_mem(void *memory) = 0; template <typename T, typename... Ts> T *alloc(Ts&&... ts) @@ -64,10 +67,10 @@ class Allocator } } - void addMemory(void *, size_t mem_size); + virtual void addMemory(void *, size_t mem_size) = 0; //Return true if the current pool cannot allocate n chunks of chunk_size - bool lowMemory(unsigned n, size_t chunk_size); + virtual bool lowMemory(unsigned n, size_t chunk_size) const = 0; bool memFree(void *pool) const; //returns number of pools @@ -80,7 +83,31 @@ class Allocator struct AllocatorImpl *impl; }; -extern Allocator DummyAlloc; +//! the allocator for normal use +class AllocatorClass : public Allocator +{ + void *alloc_mem(size_t mem_size); + void dealloc_mem(void *memory); + void addMemory(void *, size_t mem_size); + bool lowMemory(unsigned n, size_t chunk_size) const; + using Allocator::Allocator; +}; + +//! the dummy allocator, which does not allow any allocation +class DummyAllocator : public Allocator +{ + void not_allowed() const { + throw "(de)allocation forbidden"; // TODO: std exception + } +public: + void *alloc_mem(size_t ) { return not_allowed(), nullptr; } + void dealloc_mem(void* ) { not_allowed(); } // TODO: more functions? + void addMemory(void *, size_t ) { not_allowed(); } + bool lowMemory(unsigned , size_t ) const { return not_allowed(), true; } + using Allocator::Allocator; +}; + +extern DummyAllocator DummyAlloc; /** * General notes on Memory Allocation Within ZynAddSubFX diff --git a/src/Misc/CMakeLists.txt b/src/Misc/CMakeLists.txt @@ -14,6 +14,7 @@ set(zynaddsubfx_misc_SRCS Misc/MiddleWare.cpp Misc/PresetExtractor.cpp Misc/Allocator.cpp + Misc/TmpFileMgr.cpp ) diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp @@ -296,7 +296,7 @@ Master::Master(const SYNTH_T &synth_, Config* config) { bToU = NULL; uToB = NULL; - memory = new Allocator(); + memory = new AllocatorClass(); swaplr = 0; off = 0; smps = 0; diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp @@ -12,7 +12,6 @@ #include <lo/lo.h> #include <unistd.h> -#include <dirent.h> #include "../UI/Connection.h" #include "../UI/Fl_Osc_Interface.h" @@ -20,6 +19,7 @@ #include <map> #include "Util.h" +#include "TmpFileMgr.h" #include "Master.h" #include "Part.h" #include "PresetExtractor.h" @@ -459,13 +459,12 @@ namespace Nio } /* Implementation */ -class MiddleWareImpl +class MiddleWareImpl : TmpFileMgr { - static constexpr const char* tmp_nam_prefix = "/tmp/zynaddsubfx_"; MiddleWare *parent; //Detect if the name of the process is 'zynaddsubfx' - bool isPlugin() + bool isPlugin() const { std::string proc_file = "/proc/" + to_s(getpid()) + "/comm"; std::ifstream ifs(proc_file); @@ -477,111 +476,6 @@ class MiddleWareImpl return true; } - //! returns file name to where UDP port is saved - std::string get_tmp_nam() const - { - return tmp_nam_prefix + to_s(getpid()); - } - - void create_tmp_file(unsigned server_port) - { - std::string tmp_nam = get_tmp_nam(); - if(0 == access(tmp_nam.c_str(), F_OK)) { - fprintf(stderr, "Error: Cannot overwrite file %s. " - "You should probably remove it.", tmp_nam.c_str()); - exit(EXIT_FAILURE); - } - FILE* tmp_fp = fopen(tmp_nam.c_str(), "w"); - if(!tmp_fp) - fprintf(stderr, "Warning: could not create new file %s.\n", - tmp_nam.c_str()); - else - fprintf(tmp_fp, "%u", server_port); - fclose(tmp_fp); - } - - void clean_up_tmp_nams() const - { - DIR *dir; - struct dirent *entry; - if ((dir = opendir ("/tmp/")) != nullptr) - { - while ((entry = readdir (dir)) != nullptr) - { - std::string name = std::string("/tmp/") + entry->d_name; - if(!name.compare(0, strlen(tmp_nam_prefix),tmp_nam_prefix)) - { - std::string pid = name.substr(strlen(tmp_nam_prefix)); - std::string proc_file = "/proc/" + std::move(pid) + - "/comm"; - - std::ifstream ifs(proc_file); - bool remove = false; - - if(!ifs.good()) - { - fprintf(stderr, "Note: trying to remove %s - the " - "process does not exist anymore.\n", - name.c_str()); - remove = true; - } - else - { - std::string comm_name; - ifs >> comm_name; - if(comm_name == "zynaddsubfx") - fprintf(stderr, "Note: detected running " - "zynaddsubfx with PID %s.\n", - name.c_str() + strlen(tmp_nam_prefix)); - else { - fprintf(stderr, "Note: trying to remove %s - the " - "PID is owned by\n another " - "process: %s\n", - name.c_str(), comm_name.c_str()); - remove = true; - } - } - - - if(remove) - { - // make sure this file contains only one unsigned - unsigned udp_port; - std::ifstream ifs2(name); - if(!ifs2.good()) - fprintf(stderr, "Warning: could not open %s.\n", - name.c_str()); - else - { - ifs2 >> udp_port; - if(ifs.good()) - fprintf(stderr, "Warning: could not remove " - "%s, \n it has not been " - "written by zynaddsubfx\n", - name.c_str()); - else - { - if(std::remove(name.c_str()) != 0) - fprintf(stderr, "Warning: can not remove " - "%s.\n", name.c_str()); - } - } - } - - /* one might want to connect to zyn here, - but it is not necessary: - lo_address la = lo_address_new(nullptr, udp_port.c_str()); - if(lo_send(la, "/echo", nullptr) <= 0) - fputs("Note: found crashed file %s\n", stderr); - lo_address_free(la);*/ - } - } - closedir (dir); - } else { - fputs("Warning: can not read /tmp.\n", stderr); - } - } - Config* const config; public: diff --git a/src/Misc/TmpFileMgr.cpp b/src/Misc/TmpFileMgr.cpp @@ -0,0 +1,114 @@ +#include <cstdlib> +#include <cstring> +#include <string> +#include <cstdio> +#include <fstream> +#include <unistd.h> +#include <dirent.h> + +#include "Util.h" +#include "TmpFileMgr.h" + +std::string TmpFileMgr::get_tmp_nam() const +{ + return tmp_nam_prefix + to_s(getpid()); +} + +void TmpFileMgr::create_tmp_file(unsigned server_port) const +{ + std::string tmp_nam = get_tmp_nam(); + if(0 == access(tmp_nam.c_str(), F_OK)) { + fprintf(stderr, "Error: Cannot overwrite file %s. " + "You should probably remove it.", tmp_nam.c_str()); + exit(EXIT_FAILURE); + } + FILE* tmp_fp = fopen(tmp_nam.c_str(), "w"); + if(!tmp_fp) + fprintf(stderr, "Warning: could not create new file %s.\n", + tmp_nam.c_str()); + else + fprintf(tmp_fp, "%u", server_port); + fclose(tmp_fp); +} + +void TmpFileMgr::clean_up_tmp_nams() const +{ + DIR *dir; + struct dirent *entry; + if ((dir = opendir ("/tmp/")) != nullptr) + { + while ((entry = readdir (dir)) != nullptr) + { + std::string name = std::string("/tmp/") + entry->d_name; + if(!name.compare(0, strlen(tmp_nam_prefix),tmp_nam_prefix)) + { + std::string pid = name.substr(strlen(tmp_nam_prefix)); + std::string proc_file = "/proc/" + std::move(pid) + + "/comm"; + + std::ifstream ifs(proc_file); + bool remove = false; + + if(!ifs.good()) + { + fprintf(stderr, "Note: trying to remove %s - the " + "process does not exist anymore.\n", + name.c_str()); + remove = true; + } + else + { + std::string comm_name; + ifs >> comm_name; + if(comm_name == "zynaddsubfx") + fprintf(stderr, "Note: detected running " + "zynaddsubfx with PID %s.\n", + name.c_str() + strlen(tmp_nam_prefix)); + else { + fprintf(stderr, "Note: trying to remove %s - the " + "PID is owned by\n another " + "process: %s\n", + name.c_str(), comm_name.c_str()); + remove = true; + } + } + + + if(remove) + { + // make sure this file contains only one unsigned + unsigned udp_port; + std::ifstream ifs2(name); + if(!ifs2.good()) + fprintf(stderr, "Warning: could not open %s.\n", + name.c_str()); + else + { + ifs2 >> udp_port; + if(ifs.good()) + fprintf(stderr, "Warning: could not remove " + "%s, \n it has not been " + "written by zynaddsubfx\n", + name.c_str()); + else + { + if(std::remove(name.c_str()) != 0) + fprintf(stderr, "Warning: can not remove " + "%s.\n", name.c_str()); + } + } + } + + /* one might want to connect to zyn here, + but it is not necessary: + lo_address la = lo_address_new(nullptr, udp_port.c_str()); + if(lo_send(la, "/echo", nullptr) <= 0) + fputs("Note: found crashed file %s\n", stderr); + lo_address_free(la);*/ + } + } + closedir (dir); + } else { + fputs("Warning: can not read /tmp.\n", stderr); + } +} diff --git a/src/Misc/TmpFileMgr.h b/src/Misc/TmpFileMgr.h @@ -0,0 +1,18 @@ + +/** + This file provides routines for using zyn's tmp files. +*/ +class TmpFileMgr +{ + static constexpr const char* tmp_nam_prefix = "/tmp/zynaddsubfx_"; + +public: + //! returns file name to where UDP port is saved + std::string get_tmp_nam() const; + + //! creates a tmp file with given UDP port information + void create_tmp_file(unsigned server_port) const; + + //! cleans up as many tmp files as possible + void clean_up_tmp_nams() const; +};