commit 15573ea56057f8220fe694d25d07690af00e1562
parent 2a655e26a6eb8a2685cbc41edfebdf9dbab4347a
Author: Johannes Lorenz <johannes89@ist-einmalig.de>
Date: Sun, 9 Aug 2015 04:28:58 +0200
Merge.
Diffstat:
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;
+};