Browse Source

Simplify LinkedList code; Other fixes

tags/1.9.4
falkTX 11 years ago
parent
commit
25c7807b44
6 changed files with 158 additions and 219 deletions
  1. +5
    -1
      source/utils/CarlaBackendUtils.hpp
  2. +1
    -1
      source/utils/CarlaLibCounter.hpp
  3. +10
    -10
      source/utils/CarlaLibUtils.hpp
  4. +15
    -15
      source/utils/CarlaShmUtils.hpp
  5. +115
    -178
      source/utils/LinkedList.hpp
  6. +12
    -14
      source/utils/RtLinkedList.hpp

+ 5
- 1
source/utils/CarlaBackendUtils.hpp View File

@@ -441,9 +441,13 @@ PluginType getPluginTypeFromString(const char* const ctype) noexcept
carla_debug("CarlaBackend::getPluginTypeFromString(\"%s\")", ctype);

CarlaString stype(ctype);

if (stype.isEmpty())
return PLUGIN_NONE;

stype.toLower();

if (stype.isEmpty() || stype == "none")
if (stype == "none")
return PLUGIN_NONE;
if (stype == "internal")
return PLUGIN_INTERNAL;


+ 1
- 1
source/utils/CarlaLibCounter.hpp View File

@@ -29,7 +29,7 @@ class LibCounter
public:
LibCounter() noexcept {}

~LibCounter()
~LibCounter() noexcept
{
// might have some leftovers
for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())


+ 10
- 10
source/utils/CarlaLibUtils.hpp View File

@@ -38,9 +38,9 @@ void* lib_open(const char* const filename) noexcept

try {
#ifdef CARLA_OS_WIN
return (void*)LoadLibraryA(filename);
return (void*)::LoadLibraryA(filename);
#else
return dlopen(filename, RTLD_NOW|RTLD_LOCAL);
return ::dlopen(filename, RTLD_NOW|RTLD_LOCAL);
#endif
} CARLA_SAFE_EXCEPTION_RETURN("lib_open", nullptr);
}
@@ -56,9 +56,9 @@ bool lib_close(void* const lib) noexcept

try {
#ifdef CARLA_OS_WIN
return FreeLibrary((HMODULE)lib);
return ::FreeLibrary((HMODULE)lib);
#else
return (dlclose(lib) == 0);
return (::dlclose(lib) == 0);
#endif
} CARLA_SAFE_EXCEPTION_RETURN("lib_close", false);
}
@@ -74,9 +74,9 @@ void* lib_symbol(void* const lib, const char* const symbol) noexcept
CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', nullptr);

#ifdef CARLA_OS_WIN
return (void*)GetProcAddress((HMODULE)lib, symbol);
return (void*)::GetProcAddress((HMODULE)lib, symbol);
#else
return dlsym(lib, symbol);
return ::dlsym(lib, symbol);
#endif
}

@@ -95,16 +95,16 @@ const char* lib_error(const char* const filename) noexcept

try {
LPVOID winErrorString;
DWORD winErrorCode = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);
DWORD winErrorCode = ::GetLastError();
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);

std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
LocalFree(winErrorString);
::LocalFree(winErrorString);
} CARLA_SAFE_EXCEPTION("lib_error");

return (libError[0] != '\0') ? libError : nullptr;
#else
return dlerror();
return ::dlerror();
#endif
}



+ 15
- 15
source/utils/CarlaShmUtils.hpp View File

@@ -29,9 +29,9 @@ typedef int shm_t;
#endif

#ifdef CARLA_OS_WIN
static shm_t gNullCarlaShm = { nullptr, nullptr };
static const shm_t gNullCarlaShm = { nullptr, nullptr };
#else
static shm_t gNullCarlaShm = -1;
static const shm_t gNullCarlaShm = -1;
#endif

// -----------------------------------------------------------------------
@@ -77,7 +77,7 @@ shm_t carla_shm_attach(const char* const name)
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);

shm_t ret;
ret.shm = CreateFileA(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
ret.shm = ::CreateFileA(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
ret.map = nullptr;

return ret;
@@ -88,7 +88,7 @@ shm_t carla_shm_create(const char* const name)
{
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);

return shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
return ::shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
}

static inline
@@ -96,7 +96,7 @@ shm_t carla_shm_attach(const char* const name)
{
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);

return shm_open(name, O_RDWR, 0);
return ::shm_open(name, O_RDWR, 0);
}
#endif

@@ -108,10 +108,10 @@ void carla_shm_close(shm_t& shm)
#ifdef CARLA_OS_WIN
CARLA_SAFE_ASSERT(shm.map == nullptr);

CloseHandle(shm.shm);
::CloseHandle(shm.shm);
shm.shm = nullptr;
#else
close(shm);
::close(shm);
shm = -1;
#endif
}
@@ -125,15 +125,15 @@ void* carla_shm_map(shm_t& shm, const size_t size)
#ifdef CARLA_OS_WIN
CARLA_SAFE_ASSERT_RETURN(shm.map == nullptr, nullptr);

HANDLE map = CreateFileMapping(shm.shm, NULL, PAGE_READWRITE, size, size, NULL);
HANDLE map = ::CreateFileMapping(shm.shm, NULL, PAGE_READWRITE, size, size, NULL);

CARLA_SAFE_ASSERT_RETURN(map != nullptr, nullptr);

HANDLE ptr = MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size);
HANDLE ptr = ::MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size);

if (ptr == nullptr)
{
CloseHandle(map);
::CloseHandle(map);
return nullptr;
}

@@ -141,10 +141,10 @@ void* carla_shm_map(shm_t& shm, const size_t size)

return ptr;
#else
if (ftruncate(shm, static_cast<off_t>(size)) != 0)
if (::ftruncate(shm, static_cast<off_t>(size)) != 0)
return nullptr;

return mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);
return ::mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);
#endif
}

@@ -158,15 +158,15 @@ void carla_shm_unmap(shm_t& shm, void* const ptr, const size_t size)
#ifdef CARLA_OS_WIN
CARLA_SAFE_ASSERT_RETURN(shm.map != nullptr,);

UnmapViewOfFile(ptr);
CloseHandle(shm.map);
::UnmapViewOfFile(ptr);
::CloseHandle(shm.map);
shm.map = nullptr;
return;

// unused
(void)size;
#else
munmap(ptr, size);
::munmap(ptr, size);
return;

// unused


+ 115
- 178
source/utils/LinkedList.hpp View File

@@ -46,7 +46,7 @@ typedef struct list_head k_list_head;
// Abstract Linked List class
// _allocate() and _deallocate are virtual calls provided by subclasses

// NOTE: data-type classes are allowed to throw on creation, but NOT on deletion!
// NOTE: data-type classes are not allowed to throw

template<typename T>
class AbstractLinkedList
@@ -57,10 +57,9 @@ protected:
k_list_head siblings;
};

AbstractLinkedList(const bool needsCopyCtr) noexcept
: fDataSize(sizeof(Data)),
fCount(0),
fNeedsCopyCtr(needsCopyCtr)
AbstractLinkedList(const bool isClass) noexcept
: kIsClass(isClass),
kDataSize(sizeof(Data))
{
_init();
}
@@ -73,20 +72,19 @@ public:

class Itenerator {
public:
Itenerator(const k_list_head* queue) noexcept
Itenerator(const k_list_head& queue) noexcept
: fData(nullptr),
fEntry(queue->next),
fEntry(queue.next),
fEntry2(fEntry->next),
fQueue(queue)
kQueue(queue)
{
CARLA_SAFE_ASSERT(fEntry != nullptr);
CARLA_SAFE_ASSERT(fEntry2 != nullptr);
CARLA_SAFE_ASSERT(fQueue != nullptr);
}

bool valid() const noexcept
{
return (fEntry != fQueue);
return (fEntry != &kQueue);
}

void next() noexcept
@@ -111,34 +109,34 @@ public:
Data* fData;
k_list_head* fEntry;
k_list_head* fEntry2;
const k_list_head* const fQueue;
const k_list_head& kQueue;

friend class AbstractLinkedList;
};

Itenerator begin() const noexcept
{
return Itenerator(&fQueue);
return Itenerator(fQueue);
}

void clear() noexcept
{
if (fCount != 0)
if (fCount == 0)
return;

k_list_head* entry;
k_list_head* entry2;

for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next)
{
k_list_head* entry;
k_list_head* entry2;

list_for_each_safe(entry, entry2, &fQueue)
{
if (Data* data = list_entry(entry, Data, siblings))
{
if (fNeedsCopyCtr)
data->~Data();
_deallocate(data);
}
}
Data* const data = list_entry(entry, Data, siblings);
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr);

_delete(entry, data);
}

CARLA_SAFE_ASSERT(fCount == 0);

_init();
}

@@ -172,268 +170,207 @@ public:
return _add(value, false, it.fEntry->prev);
}

T& getAt(const size_t index) const noexcept
T& getAt(const size_t index, T& fallback) const noexcept
{
if (fCount == 0 || index >= fCount)
return fRetValue;
CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback);

size_t i = 0;
Data* data = nullptr;
k_list_head* entry;
k_list_head* entry2;

list_for_each_safe(entry, entry2, &fQueue)
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next)
{
if (index != i++)
continue;

data = list_entry(entry, Data, siblings);
return _get(entry, fallback);
}

if (data != nullptr)
fRetValue = data->value;
return fallback;
}

break;
}
T& getFirst(T& fallback) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback);

return _get(fQueue.next, fallback);
}

T& getLast(T& fallback) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback);

return fRetValue;
return _get(fQueue.prev, fallback);
}

T& getAt(const size_t index, const bool removeObj) noexcept
T getAt(const size_t index, T& fallback, const bool removeObj) noexcept
{
if (fCount == 0 || index >= fCount)
return fRetValue;
CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback);

size_t i = 0;
Data* data = nullptr;
k_list_head* entry;
k_list_head* entry2;

list_for_each_safe(entry, entry2, &fQueue)
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next)
{
if (index != i++)
continue;

data = list_entry(entry, Data, siblings);

if (data != nullptr)
fRetValue = data->value;

if (removeObj)
{
--fCount;
list_del(entry);

if (data != nullptr)
{
if (fNeedsCopyCtr)
data->~Data();
_deallocate(data);
}
}

break;
return _get(entry, fallback, removeObj);
}

return fRetValue;
return fallback;
}

T& getFirst(const bool removeObj = false) noexcept
T getFirst(T& fallback, const bool removeObj) noexcept
{
return _getFirstOrLast(true, removeObj);
CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback);

return _get(fQueue.next, fallback, removeObj);
}

T& getLast(const bool removeObj = false) noexcept
T getLast(T& fallback, const bool removeObj) noexcept
{
return _getFirstOrLast(false, removeObj);
CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback);

return _get(fQueue.prev, fallback, removeObj);
}

void remove(Itenerator& it) noexcept
{
CARLA_SAFE_ASSERT_RETURN(it.fEntry != nullptr,);

--fCount;
list_del(it.fEntry);

CARLA_SAFE_ASSERT_RETURN(it.fData != nullptr,);

if (fNeedsCopyCtr)
it.fData->~Data();
_deallocate(it.fData);
_delete(it.fEntry, it.fData);
}

bool removeOne(const T& value) noexcept
{
Data* data = nullptr;
k_list_head* entry;
k_list_head* entry2;

list_for_each_safe(entry, entry2, &fQueue)
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next)
{
data = list_entry(entry, Data, siblings);

Data* const data = list_entry(entry, Data, siblings);
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr);

if (data->value == value)
{
--fCount;
list_del(entry);
if (data->value != value)
continue;
_delete(entry, data);

if (fNeedsCopyCtr)
data->~Data();
_deallocate(data);
break;
}
return true;
}

return (data != nullptr);
return false;
}

void removeAll(const T& value) noexcept
{
Data* data;
k_list_head* entry;
k_list_head* entry2;

list_for_each_safe(entry, entry2, &fQueue)
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next)
{
data = list_entry(entry, Data, siblings);

Data* const data = list_entry(entry, Data, siblings);
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr);

if (data->value == value)
{
--fCount;
list_del(entry);
if (data->value != value)
continue;

if (fNeedsCopyCtr)
data->~Data();
_deallocate(data);
}
_delete(entry, data);
}
}

void spliceAppend(AbstractLinkedList& list, const bool init = true) noexcept
void spliceAppend(AbstractLinkedList<T>& list) noexcept
{
if (init)
{
list_splice_tail_init(&fQueue, &list.fQueue);
list.fCount += fCount;
fCount = 0;
}
else
{
list_splice_tail(&fQueue, &list.fQueue);
list.fCount += fCount;
}
list_splice_tail_init(&fQueue, &list.fQueue);
list.fCount += fCount;
fCount = 0;
}

void spliceInsert(AbstractLinkedList& list, const bool init = true) noexcept
void spliceInsert(AbstractLinkedList<T>& list) noexcept
{
if (init)
{
list_splice_init(&fQueue, &list.fQueue);
list.fCount += fCount;
fCount = 0;
}
else
{
list_splice(&fQueue, &list.fQueue);
list.fCount += fCount;
}
list_splice_init(&fQueue, &list.fQueue);
list.fCount += fCount;
fCount = 0;
}

protected:
const size_t fDataSize;
const bool kIsClass;
const size_t kDataSize;
size_t fCount;
k_list_head fQueue;

const bool fNeedsCopyCtr;

virtual Data* _allocate() noexcept = 0;
virtual void _deallocate(Data* const dataPtr) noexcept = 0;

bool _createData(Data* const data, const T& value)
void _createData(Data* const data, const T& value) noexcept
{
if (fNeedsCopyCtr)
{
try {
new(data)Data();
}
catch(...) {
_deallocate(data);
return false;
}

try {
data->value = value;
}
catch(...) {
data->~Data();
_deallocate(data);
return false;
}
}
if (kIsClass)
new(data)Data(value);
else
{
std::memcpy(&data->value, &value, this->fDataSize);
}
data->value = value;

return true;
++fCount;
}

private:
mutable T fRetValue;

void _init() noexcept
{
fCount = 0;
INIT_LIST_HEAD(&fQueue);
fQueue.next = &fQueue;
fQueue.prev = &fQueue;
}

bool _add(const T& value, const bool inTail, k_list_head* const queue) noexcept
{
if (Data* const data = _allocate())
{
if (! _createData(data, value))
return false;
_createData(data, value);

if (inTail)
list_add_tail(&data->siblings, queue);
else
list_add(&data->siblings, queue);

++fCount;
return true;
}

return false;
}

T& _getFirstOrLast(const bool first, const bool removeObj) noexcept
void _delete(k_list_head* const entry, Data* const data) noexcept
{
if (fCount == 0)
return fRetValue;
--fCount;
list_del(entry);

k_list_head* const entry = first ? fQueue.next : fQueue.prev;
Data* data = list_entry(entry, Data, siblings);
if (kIsClass)
data->~Data();
_deallocate(data);
}

if (data != nullptr)
fRetValue = data->value;
T& _get(k_list_head* const entry, T& fallback) const noexcept
{
Data* const data = list_entry(entry, Data, siblings);
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback);

if (removeObj)
{
--fCount;
list_del(entry);

if (data != nullptr)
{
if (fNeedsCopyCtr)
data->~Data();
_deallocate(data);
}
}
return data->value;
}

T _get(k_list_head* const entry, T& fallback, const bool removeObj) noexcept
{
Data* const data = list_entry(entry, Data, siblings);
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback);

if (! removeObj)
return data->value;

const T value(data->value);

_delete(entry, data);

return fRetValue;
return value;
}

LINKED_LIST_DECLARATIONS(AbstractLinkedList)
@@ -446,13 +383,13 @@ template<typename T>
class LinkedList : public AbstractLinkedList<T>
{
public:
LinkedList(const bool needsCopyCtr = false) noexcept
: AbstractLinkedList<T>(needsCopyCtr) {}
LinkedList(const bool isClass = false) noexcept
: AbstractLinkedList<T>(isClass) {}

protected:
typename AbstractLinkedList<T>::Data* _allocate() noexcept override
{
return (typename AbstractLinkedList<T>::Data*)std::malloc(this->fDataSize);
return (typename AbstractLinkedList<T>::Data*)std::malloc(this->kDataSize);
}

void _deallocate(typename AbstractLinkedList<T>::Data* const dataPtr) noexcept override


+ 12
- 14
source/utils/RtLinkedList.hpp View File

@@ -39,7 +39,7 @@ public:
public:
Pool(const size_t minPreallocated, const size_t maxPreallocated) noexcept
: fHandle(nullptr),
fDataSize(sizeof(typename AbstractLinkedList<T>::Data))
kDataSize(sizeof(typename AbstractLinkedList<T>::Data))
{
resize(minPreallocated, maxPreallocated);
}
@@ -76,30 +76,30 @@ public:
fHandle = nullptr;
}

rtsafe_memory_pool_create(&fHandle, nullptr, fDataSize, minPreallocated, maxPreallocated);
rtsafe_memory_pool_create(&fHandle, nullptr, kDataSize, minPreallocated, maxPreallocated);
CARLA_SAFE_ASSERT(fHandle != nullptr);
}

bool operator==(const Pool& pool) const noexcept
{
return (fHandle == pool.fHandle && fDataSize == pool.fDataSize);
return (fHandle == pool.fHandle && kDataSize == pool.kDataSize);
}

bool operator!=(const Pool& pool) const noexcept
{
return (fHandle != pool.fHandle || fDataSize != pool.fDataSize);
return (fHandle != pool.fHandle || kDataSize != pool.kDataSize);
}

private:
mutable RtMemPool_Handle fHandle;
const size_t fDataSize;
const size_t kDataSize;
};

// -------------------------------------------------------------------
// Now the actual rt-linkedlist code

RtLinkedList(Pool& memPool, const bool needsCopyCtr = false) noexcept
: AbstractLinkedList<T>(needsCopyCtr),
RtLinkedList(Pool& memPool, const bool isClass = false) noexcept
: AbstractLinkedList<T>(isClass),
fMemPool(memPool) {}

bool append_sleepy(const T& value) noexcept
@@ -119,18 +119,18 @@ public:
fMemPool.resize(minPreallocated, maxPreallocated);
}

void spliceAppend(RtLinkedList& list, const bool init = true) noexcept
void spliceAppend(RtLinkedList<T>& list) noexcept
{
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,);

AbstractLinkedList<T>::spliceAppend(list, init);
AbstractLinkedList<T>::spliceAppend(list);
}

void spliceInsert(RtLinkedList& list, const bool init = true) noexcept
void spliceInsert(RtLinkedList<T>& list) noexcept
{
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,);

AbstractLinkedList<T>::spliceInsert(list, init);
AbstractLinkedList<T>::spliceInsert(list);
}

protected:
@@ -158,15 +158,13 @@ private:
{
if (typename AbstractLinkedList<T>::Data* const data = _allocate_sleepy())
{
if (! this->_createData(data, value))
return false;
this->_createData(data, value);

if (inTail)
list_add_tail(&data->siblings, &this->fQueue);
else
list_add(&data->siblings, &this->fQueue);

++(this->fCount);
return true;
}



Loading…
Cancel
Save