diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/nu/threadpool/ThreadFunctions.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/nu/threadpool/ThreadFunctions.cpp')
-rw-r--r-- | Src/nu/threadpool/ThreadFunctions.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/Src/nu/threadpool/ThreadFunctions.cpp b/Src/nu/threadpool/ThreadFunctions.cpp new file mode 100644 index 00000000..0ae23730 --- /dev/null +++ b/Src/nu/threadpool/ThreadFunctions.cpp @@ -0,0 +1,79 @@ +#include "ThreadFunctions.h" +#include "threadpool_types.h" + +ThreadFunctions::ThreadFunctions(int create_function_list) +{ + if (create_function_list) + { + functions_semaphore = CreateSemaphore(0, 0, ThreadPoolTypes::MAX_SEMAPHORE_VALUE, 0); + InitializeCriticalSectionAndSpinCount(&functions_guard, 200); + } + else + functions_semaphore = 0; +} + +ThreadFunctions::~ThreadFunctions() +{ + if (functions_semaphore) + { + CloseHandle(functions_semaphore); + DeleteCriticalSection(&functions_guard); + } +} + +void ThreadFunctions::Add(HANDLE handle, api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id) +{ + Nullsoft::Utility::AutoLock l(guard); + Data *new_data = (Data *)calloc(1, sizeof(Data)); + new_data->func = func; + new_data->user_data = user_data; + new_data->id = id; + data[handle] = new_data; +} + +bool ThreadFunctions::Get(HANDLE handle, api_threadpool::ThreadPoolFunc *func, void **user_data, intptr_t *id) +{ + Nullsoft::Utility::AutoLock l(guard); + DataMap::iterator found = data.find(handle); + if (found == data.end()) + return false; + + const Data *d = found->second; + *func = d->func; + *user_data = d->user_data; + *id = d->id; + return true; +} + +void ThreadFunctions::QueueFunction(api_threadpool::ThreadPoolFunc func, void *user_data, intptr_t id) +{ + Data *new_data = (Data *)calloc(1, sizeof(Data)); + new_data->func = func; + new_data->user_data = user_data; + new_data->id = id; + EnterCriticalSection(&functions_guard); + functions_list.push_front(new_data); + LeaveCriticalSection(&functions_guard); // unlock before releasing the semaphore early so we don't lock convoy + ReleaseSemaphore(functions_semaphore, 1, 0); +} + +bool ThreadFunctions::PopFunction(api_threadpool::ThreadPoolFunc *func, void **user_data, intptr_t *id) +{ + EnterCriticalSection(&functions_guard); + if (!functions_list.empty()) + { + ThreadFunctions::Data *data = functions_list.back(); + functions_list.pop_back(); + LeaveCriticalSection(&functions_guard); + *func = data->func; + *user_data = data->user_data; + *id = data->id; + free(data); + return true; + } + else + { + LeaveCriticalSection(&functions_guard); + return false; + } +} |