diff --git a/include/downloader.h b/include/downloader.h index d0b42cf57..4cd8337ad 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/include/meson.build b/include/meson.build index 4486c5c5f..4157970e4 100644 --- a/include/meson.build +++ b/include/meson.build @@ -25,7 +25,6 @@ install_headers( 'tools/pathTools.h', 'tools/regexTools.h', 'tools/stringTools.h', - 'tools/lock.h', subdir:'kiwix/tools' ) diff --git a/include/tools/lock.h b/include/tools/lock.h deleted file mode 100644 index 98c64937a..000000000 --- a/include/tools/lock.h +++ /dev/null @@ -1,46 +0,0 @@ - - -#ifndef KIWIXLIB_TOOL_LOCK_H -#define KIWIXLIB_TOOL_LOCK_H - -#include - -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 diff --git a/meson.build b/meson.build index 607b2b377..b12d5823d 100644 --- a/meson.build +++ b/meson.build @@ -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) diff --git a/src/entry.cpp b/src/entry.cpp index 080a52241..91abbe6e9 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -20,8 +20,6 @@ #include "reader.h" #include -#include - namespace kiwix { diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 0e588b760..52b5960e6 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -58,7 +58,6 @@ extern "C" { #include -#include #include #include #include diff --git a/src/subprocess_unix.cpp b/src/subprocess_unix.cpp index 68819255b..8884aadbb 100644 --- a/src/subprocess_unix.cpp +++ b/src/subprocess_unix.cpp @@ -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(_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; } diff --git a/src/subprocess_unix.h b/src/subprocess_unix.h index 22a03b525..77becd612 100644 --- a/src/subprocess_unix.h +++ b/src/subprocess_unix.h @@ -3,16 +3,16 @@ #include "subprocess.h" -#include - +#include +#include class UnixImpl : public SubprocessImpl { private: int m_pid; - bool m_running; - pthread_mutex_t m_mutex; - pthread_t m_waitingThread; + std::atomic m_running; + std::atomic m_shouldQuit; + std::thread m_waitingThread; public: UnixImpl(); diff --git a/src/tools/regexTools.cpp b/src/tools/regexTools.cpp index 72fc29aa8..36305cbbc 100644 --- a/src/tools/regexTools.cpp +++ b/src/tools/regexTools.cpp @@ -18,7 +18,6 @@ */ #include -#include #include #include @@ -26,10 +25,10 @@ #include #include #include -#include +#include std::map> regexCache; -static pthread_mutex_t regexLock = PTHREAD_MUTEX_INITIALIZER; +static std::mutex regexLock; std::unique_ptr buildMatcher(const std::string& regex, icu::UnicodeString& content) { @@ -39,7 +38,7 @@ std::unique_ptr 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(®exLock); + std::lock_guard l(regexLock); try { pattern = regexCache.at(regex); } catch (std::out_of_range&) { diff --git a/src/wrapper/java/kiwixicu.cpp b/src/wrapper/java/kiwixicu.cpp index 0c604ebdd..a10b57886 100644 --- a/src/wrapper/java/kiwixicu.cpp +++ b/src/wrapper/java/kiwixicu.cpp @@ -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) diff --git a/src/wrapper/java/utils.h b/src/wrapper/java/utils.h index f9220403f..00b5855a5 100644 --- a/src/wrapper/java/utils.h +++ b/src/wrapper/java/utils.h @@ -24,7 +24,7 @@ #include -#include +#include #include #include #include @@ -36,7 +36,7 @@ #define LOG(...) #endif -extern pthread_mutex_t globalLock; +extern std::mutex globalLock; template 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 { - 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(globalLock) { } }; template diff --git a/test/manager.cpp b/test/manager.cpp index 6a2bbe8bd..13446c466 100644 --- a/test/manager.cpp +++ b/test/manager.cpp @@ -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")); @@ -22,4 +22,4 @@ TEST(ManagerTest, addBookFromPathAndGetIdTest) auto savedPath = computeAbsolutePath(removeLastPathElement(manager.writableLibraryPath), pathToSave); EXPECT_EQ(book.getPath(), savedPath); EXPECT_EQ(book.getUrl(), url); -} \ No newline at end of file +}