mirror of https://github.com/kiwix/libkiwix.git
Merge pull request #445 from kiwix/no_pthread
This commit is contained in:
commit
c81c2a4630
|
@ -23,7 +23,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <pthread.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ install_headers(
|
||||||
'tools/pathTools.h',
|
'tools/pathTools.h',
|
||||||
'tools/regexTools.h',
|
'tools/regexTools.h',
|
||||||
'tools/stringTools.h',
|
'tools/stringTools.h',
|
||||||
'tools/lock.h',
|
|
||||||
subdir:'kiwix/tools'
|
subdir:'kiwix/tools'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -23,7 +23,12 @@ if ['arm', 'mips', 'm68k', 'ppc', 'sh4'].contains(target_machine.cpu_family())
|
||||||
extra_libs += '-latomic'
|
extra_libs += '-latomic'
|
||||||
endif
|
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)
|
libicu_dep = dependency('icu-i18n', static:static_deps)
|
||||||
pugixml_dep = dependency('pugixml', static:static_deps)
|
pugixml_dep = dependency('pugixml', static:static_deps)
|
||||||
libcurl_dep = dependency('libcurl', static:static_deps)
|
libcurl_dep = dependency('libcurl', static:static_deps)
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include "reader.h"
|
#include "reader.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <zim/search.h>
|
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,6 @@ extern "C" {
|
||||||
|
|
||||||
#include <mustache.hpp>
|
#include <mustache.hpp>
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -12,46 +12,31 @@
|
||||||
UnixImpl::UnixImpl():
|
UnixImpl::UnixImpl():
|
||||||
m_pid(0),
|
m_pid(0),
|
||||||
m_running(false),
|
m_running(false),
|
||||||
m_mutex(PTHREAD_MUTEX_INITIALIZER),
|
m_shouldQuit(false)
|
||||||
m_waitingThread()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
UnixImpl::~UnixImpl()
|
UnixImpl::~UnixImpl()
|
||||||
{
|
{
|
||||||
kill();
|
kill();
|
||||||
// Android has no pthread_cancel :(
|
m_shouldQuit = true;
|
||||||
#ifdef __ANDROID__
|
m_waitingThread.join();
|
||||||
pthread_kill(m_waitingThread, SIGUSR1);
|
|
||||||
#else
|
|
||||||
pthread_cancel(m_waitingThread);
|
|
||||||
#endif
|
|
||||||
pthread_join(m_waitingThread, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
void thread_exit_handler(int sig) {
|
|
||||||
pthread_exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void* UnixImpl::waitForPID(void* _self)
|
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);
|
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;
|
self->m_running = false;
|
||||||
pthread_mutex_unlock(&self->m_mutex);
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +60,7 @@ void UnixImpl::run(commandLine_t& commandLine)
|
||||||
default:
|
default:
|
||||||
m_pid = pid;
|
m_pid = pid;
|
||||||
m_running = true;
|
m_running = true;
|
||||||
pthread_create(&m_waitingThread, NULL, waitForPID, this);
|
m_waitingThread = std::thread(waitForPID, this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,8 +72,5 @@ bool UnixImpl::kill()
|
||||||
|
|
||||||
bool UnixImpl::isRunning()
|
bool UnixImpl::isRunning()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&m_mutex);
|
return m_running;
|
||||||
bool ret = m_running;
|
|
||||||
pthread_mutex_unlock(&m_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
|
|
||||||
#include "subprocess.h"
|
#include "subprocess.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
class UnixImpl : public SubprocessImpl
|
class UnixImpl : public SubprocessImpl
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int m_pid;
|
int m_pid;
|
||||||
bool m_running;
|
std::atomic<bool> m_running;
|
||||||
pthread_mutex_t m_mutex;
|
std::atomic<bool> m_shouldQuit;
|
||||||
pthread_t m_waitingThread;
|
std::thread m_waitingThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UnixImpl();
|
UnixImpl();
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tools/regexTools.h>
|
#include <tools/regexTools.h>
|
||||||
#include <tools/lock.h>
|
|
||||||
|
|
||||||
#include <unicode/regex.h>
|
#include <unicode/regex.h>
|
||||||
#include <unicode/ucnv.h>
|
#include <unicode/ucnv.h>
|
||||||
|
@ -26,10 +25,10 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <pthread.h>
|
#include <mutex>
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<icu::RegexPattern>> regexCache;
|
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)
|
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);
|
pattern = regexCache.at(regex);
|
||||||
} catch (std::out_of_range&) {
|
} catch (std::out_of_range&) {
|
||||||
// Redo the search with a lock to avoid race condition.
|
// Redo the search with a lock to avoid race condition.
|
||||||
kiwix::Lock l(®exLock);
|
std::lock_guard<std::mutex> l(regexLock);
|
||||||
try {
|
try {
|
||||||
pattern = regexCache.at(regex);
|
pattern = regexCache.at(regex);
|
||||||
} catch (std::out_of_range&) {
|
} catch (std::out_of_range&) {
|
||||||
|
|
|
@ -28,11 +28,7 @@
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#if __ANDROID__
|
std::mutex globalLock;
|
||||||
pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
|
|
||||||
#else
|
|
||||||
pthread_mutex_t globalLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIICU_setDataDirectory(
|
JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIICU_setDataDirectory(
|
||||||
JNIEnv* env, jclass kclass, jstring dirStr)
|
JNIEnv* env, jclass kclass, jstring dirStr)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
#define LOG(...)
|
#define LOG(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern pthread_mutex_t globalLock;
|
extern std::mutex globalLock;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void setPtr(JNIEnv* env, jobject thisObj, T* ptr)
|
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);
|
return env->NewObjectArray(length, c, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Lock
|
class Lock : public std::unique_lock<std::mutex>
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
pthread_mutex_t* lock;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Lock() : lock(&globalLock) { pthread_mutex_lock(lock); }
|
Lock() : std::unique_lock<std::mutex>(globalLock) { }
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -11,7 +11,7 @@ TEST(ManagerTest, addBookFromPathAndGetIdTest)
|
||||||
kiwix::Manager manager = kiwix::Manager(&lib);
|
kiwix::Manager manager = kiwix::Manager(&lib);
|
||||||
|
|
||||||
auto bookId = manager.addBookFromPathAndGetId("./test/example.zim");
|
auto bookId = manager.addBookFromPathAndGetId("./test/example.zim");
|
||||||
EXPECT_NE(bookId, "");
|
ASSERT_NE(bookId, "");
|
||||||
kiwix::Book book = lib.getBookById(bookId);
|
kiwix::Book book = lib.getBookById(bookId);
|
||||||
EXPECT_EQ(book.getPath(), computeAbsolutePath("", "./test/example.zim"));
|
EXPECT_EQ(book.getPath(), computeAbsolutePath("", "./test/example.zim"));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue