Merge pull request #445 from kiwix/no_pthread

This commit is contained in:
Matthieu Gautier 2021-01-26 18:06:16 +01:00 committed by GitHub
commit c81c2a4630
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 35 additions and 116 deletions

View File

@ -23,7 +23,6 @@
#include <string>
#include <vector>
#include <map>
#include <pthread.h>
#include <memory>
#include <stdexcept>

View File

@ -25,7 +25,6 @@ install_headers(
'tools/pathTools.h',
'tools/regexTools.h',
'tools/stringTools.h',
'tools/lock.h',
subdir:'kiwix/tools'
)

View File

@ -1,46 +0,0 @@
#ifndef KIWIXLIB_TOOL_LOCK_H
#define KIWIXLIB_TOOL_LOCK_H
#include <pthread.h>
namespace kiwix {
class Lock
{
public:
explicit Lock(pthread_mutex_t* mutex) :
mp_mutex(mutex)
{
pthread_mutex_lock(mp_mutex);
}
~Lock() {
if (mp_mutex != nullptr) {
pthread_mutex_unlock(mp_mutex);
}
}
Lock(Lock && other) :
mp_mutex(other.mp_mutex)
{
other.mp_mutex = nullptr;
}
Lock & operator=(Lock && other)
{
mp_mutex = other.mp_mutex;
other.mp_mutex = nullptr;
return *this;
}
private:
pthread_mutex_t* mp_mutex;
Lock(Lock const &) = delete;
Lock & operator=(Lock const &) = delete;
};
}
#endif //KIWIXLIB_TOOL_LOCK_H

View File

@ -23,7 +23,12 @@ if ['arm', 'mips', 'm68k', 'ppc', 'sh4'].contains(target_machine.cpu_family())
extra_libs += '-latomic'
endif
thread_dep = dependency('threads')
if (compiler.get_id() == 'gcc' and build_machine.system() == 'linux') or target_machine.system() == 'freebsd'
# C++ std::thread is implemented using pthread on linux by gcc
thread_dep = dependency('threads')
else
thread_dep = dependency('', required:false)
endif
libicu_dep = dependency('icu-i18n', static:static_deps)
pugixml_dep = dependency('pugixml', static:static_deps)
libcurl_dep = dependency('libcurl', static:static_deps)

View File

@ -20,8 +20,6 @@
#include "reader.h"
#include <time.h>
#include <zim/search.h>
namespace kiwix
{

View File

@ -58,7 +58,6 @@ extern "C" {
#include <mustache.hpp>
#include <pthread.h>
#include <atomic>
#include <string>
#include <vector>

View File

@ -12,46 +12,31 @@
UnixImpl::UnixImpl():
m_pid(0),
m_running(false),
m_mutex(PTHREAD_MUTEX_INITIALIZER),
m_waitingThread()
m_shouldQuit(false)
{
}
UnixImpl::~UnixImpl()
{
kill();
// Android has no pthread_cancel :(
#ifdef __ANDROID__
pthread_kill(m_waitingThread, SIGUSR1);
#else
pthread_cancel(m_waitingThread);
#endif
pthread_join(m_waitingThread, nullptr);
m_shouldQuit = true;
m_waitingThread.join();
}
#ifdef __ANDROID__
void thread_exit_handler(int sig) {
pthread_exit(0);
}
#endif
void* UnixImpl::waitForPID(void* _self)
{
#ifdef __ANDROID__
struct sigaction actions;
memset(&actions, 0, sizeof(actions));
sigemptyset(&actions.sa_mask);
actions.sa_flags = 0;
actions.sa_handler = thread_exit_handler;
sigaction(SIGUSR1, &actions, NULL);
#endif
UnixImpl* self = static_cast<UnixImpl*>(_self);
waitpid(self->m_pid, NULL, 0);
while (true) {
if (!waitpid(self->m_pid, NULL, WNOHANG)) {
break;
}
if (self->m_shouldQuit) {
return nullptr;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
pthread_mutex_lock(&self->m_mutex);
self->m_running = false;
pthread_mutex_unlock(&self->m_mutex);
return self;
}
@ -75,7 +60,7 @@ void UnixImpl::run(commandLine_t& commandLine)
default:
m_pid = pid;
m_running = true;
pthread_create(&m_waitingThread, NULL, waitForPID, this);
m_waitingThread = std::thread(waitForPID, this);
break;
}
}
@ -87,8 +72,5 @@ bool UnixImpl::kill()
bool UnixImpl::isRunning()
{
pthread_mutex_lock(&m_mutex);
bool ret = m_running;
pthread_mutex_unlock(&m_mutex);
return ret;
return m_running;
}

View File

@ -3,16 +3,16 @@
#include "subprocess.h"
#include <pthread.h>
#include <atomic>
#include <thread>
class UnixImpl : public SubprocessImpl
{
private:
int m_pid;
bool m_running;
pthread_mutex_t m_mutex;
pthread_t m_waitingThread;
std::atomic<bool> m_running;
std::atomic<bool> m_shouldQuit;
std::thread m_waitingThread;
public:
UnixImpl();

View File

@ -18,7 +18,6 @@
*/
#include <tools/regexTools.h>
#include <tools/lock.h>
#include <unicode/regex.h>
#include <unicode/ucnv.h>
@ -26,10 +25,10 @@
#include <memory>
#include <map>
#include <stdexcept>
#include <pthread.h>
#include <mutex>
std::map<std::string, std::shared_ptr<icu::RegexPattern>> regexCache;
static pthread_mutex_t regexLock = PTHREAD_MUTEX_INITIALIZER;
static std::mutex regexLock;
std::unique_ptr<icu::RegexMatcher> buildMatcher(const std::string& regex, icu::UnicodeString& content)
{
@ -39,7 +38,7 @@ std::unique_ptr<icu::RegexMatcher> buildMatcher(const std::string& regex, icu::U
pattern = regexCache.at(regex);
} catch (std::out_of_range&) {
// Redo the search with a lock to avoid race condition.
kiwix::Lock l(&regexLock);
std::lock_guard<std::mutex> l(regexLock);
try {
pattern = regexCache.at(regex);
} catch (std::out_of_range&) {

View File

@ -28,11 +28,7 @@
#include "utils.h"
#if __ANDROID__
pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
#else
pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
#endif
std::mutex globalLock;
JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIICU_setDataDirectory(
JNIEnv* env, jclass kclass, jstring dirStr)

View File

@ -24,7 +24,7 @@
#include <jni.h>
#include <pthread.h>
#include <mutex>
#include <string>
#include <vector>
#include <iostream>
@ -36,7 +36,7 @@
#define LOG(...)
#endif
extern pthread_mutex_t globalLock;
extern std::mutex globalLock;
template<typename T>
void setPtr(JNIEnv* env, jobject thisObj, T* ptr)
@ -88,22 +88,10 @@ inline jobjectArray createArray(JNIEnv* env, size_t length, const std::string& t
return env->NewObjectArray(length, c, NULL);
}
class Lock
class Lock : public std::unique_lock<std::mutex>
{
protected:
pthread_mutex_t* lock;
public:
Lock() : lock(&globalLock) { pthread_mutex_lock(lock); }
Lock(const Lock&) = delete;
Lock& operator=(const Lock&) = delete;
Lock(Lock&& other) : lock(&globalLock) { other.lock = nullptr; }
virtual ~Lock()
{
if (lock) {
pthread_mutex_unlock(lock);
}
}
Lock() : std::unique_lock<std::mutex>(globalLock) { }
};
template <class T>

View File

@ -11,7 +11,7 @@ TEST(ManagerTest, addBookFromPathAndGetIdTest)
kiwix::Manager manager = kiwix::Manager(&lib);
auto bookId = manager.addBookFromPathAndGetId("./test/example.zim");
EXPECT_NE(bookId, "");
ASSERT_NE(bookId, "");
kiwix::Book book = lib.getBookById(bookId);
EXPECT_EQ(book.getPath(), computeAbsolutePath("", "./test/example.zim"));