Merge remote-tracking branch 'origin/1.4.10' into 1.4.10
# Conflicts: # CMakeLists.txt
This commit is contained in:
commit
2747c67f44
@ -88,7 +88,7 @@ if (MSVC)
|
|||||||
CMAKE_C_FLAGS_RELEASE
|
CMAKE_C_FLAGS_RELEASE
|
||||||
)
|
)
|
||||||
foreach(CompilerFlag ${CompilerFlags})
|
foreach(CompilerFlag ${CompilerFlags})
|
||||||
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
|
string(REGEX REPLACE "/M[DT]d?" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
|
||||||
endforeach()
|
endforeach()
|
||||||
add_compile_options("/EHsc") #We require exception handling
|
add_compile_options("/EHsc") #We require exception handling
|
||||||
else()
|
else()
|
||||||
@ -173,6 +173,12 @@ set(HEADER_FILES
|
|||||||
src/channel/TreeView.h
|
src/channel/TreeView.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT ThreadPool_FOUND)
|
||||||
|
set(SOURCE_FILES ${SOURCE_FILES}
|
||||||
|
src/misc/threads.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(FEATURE_LOGGING)
|
if(FEATURE_LOGGING)
|
||||||
set(SOURCE_FILES ${SOURCE_FILES}
|
set(SOURCE_FILES ${SOURCE_FILES}
|
||||||
src/log/LogUtils.cpp
|
src/log/LogUtils.cpp
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "./task_executor.h"
|
#include "./task_executor.h"
|
||||||
#include <ThreadPool/ThreadHelper.h>
|
#include "./threads.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using std::chrono::system_clock;
|
using std::chrono::system_clock;
|
||||||
using namespace ts;
|
using namespace ts;
|
||||||
@ -315,7 +316,7 @@ void task_executor::executor(std::shared_ptr<executor_context> executor_context)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto execute_timestamp = system_clock::now();
|
auto execute_timestamp = std::chrono::system_clock::now();
|
||||||
std::chrono::system_clock::time_point next_timestamp{};
|
std::chrono::system_clock::time_point next_timestamp{};
|
||||||
if(task_context->task_recurring_head) {
|
if(task_context->task_recurring_head) {
|
||||||
if(task_context->task_recurring_head->scheduled_invoke <= execute_timestamp) {
|
if(task_context->task_recurring_head->scheduled_invoke <= execute_timestamp) {
|
||||||
@ -338,7 +339,9 @@ void task_executor::executor(std::shared_ptr<executor_context> executor_context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
task->last_invoked = execute_timestamp;
|
task->last_invoked = execute_timestamp;
|
||||||
task->scheduled_invoke = std::max(system_clock::now(), execute_timestamp + task->interval);
|
|
||||||
|
auto expected_next_invoke = execute_timestamp + std::chrono::duration_cast<std::chrono::system_clock::duration>(task->interval);
|
||||||
|
task->scheduled_invoke = std::max(std::chrono::system_clock::now(), expected_next_invoke);
|
||||||
|
|
||||||
task_lock.lock();
|
task_lock.lock();
|
||||||
executor_context->executing_recurring_task = nullptr;
|
executor_context->executing_recurring_task = nullptr;
|
||||||
|
93
src/misc/threads.cpp
Normal file
93
src/misc/threads.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "./threads.h"
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string threads::name(std::thread &thread) {
|
||||||
|
#ifdef WIN32
|
||||||
|
static std::string _empty{};
|
||||||
|
return _empty;
|
||||||
|
#else
|
||||||
|
char buffer[255]; /* min 16 characters */
|
||||||
|
pthread_getname_np(thread.native_handle(), buffer, 255);
|
||||||
|
return std::string{buffer};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool threads::name(std::thread &thread, const std::string_view &name) {
|
||||||
|
#ifdef WIN32
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
char buffer[255]; /* min 16 characters */
|
||||||
|
|
||||||
|
memcpy(buffer, name.data(), name.length());
|
||||||
|
buffer[name.length()] = '\0';
|
||||||
|
buffer[16] = '\0'; /* cut of the name after 16 characters */
|
||||||
|
|
||||||
|
auto error = pthread_setname_np(thread.native_handle(), buffer);
|
||||||
|
return error == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool threads::save_join(std::thread &thread, bool rd) {
|
||||||
|
try {
|
||||||
|
if(thread.joinable())
|
||||||
|
thread.join();
|
||||||
|
} catch(const std::system_error& ex) {
|
||||||
|
if(ex.code() == std::errc::resource_deadlock_would_occur) {
|
||||||
|
if(rd)
|
||||||
|
return false;
|
||||||
|
throw;
|
||||||
|
} else if(ex.code() == std::errc::no_such_process) {
|
||||||
|
return false;
|
||||||
|
} else if(ex.code() == std::errc::invalid_argument) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool threads::timed_join(std::thread &thread, const std::chrono::nanoseconds &timeout) {
|
||||||
|
#ifdef WIN32
|
||||||
|
auto result = WaitForSingleObject(thread.native_handle(), (DWORD) std::chrono::floor<std::chrono::milliseconds>(timeout).count());
|
||||||
|
if(result != 0)
|
||||||
|
return false;
|
||||||
|
if(thread.joinable())
|
||||||
|
thread.join();
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
struct timespec ts{};
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
|
||||||
|
return false; /* failed to get clock time */
|
||||||
|
|
||||||
|
auto seconds = std::chrono::floor<std::chrono::seconds>(timeout);
|
||||||
|
auto nanoseconds = std::chrono::ceil<std::chrono::nanoseconds>(timeout) - seconds;
|
||||||
|
ts.tv_sec += seconds.count();
|
||||||
|
ts.tv_nsec += nanoseconds.count();
|
||||||
|
if(ts.tv_nsec >= 1e9) {
|
||||||
|
ts.tv_sec += 1;
|
||||||
|
ts.tv_nsec -= 1e9;
|
||||||
|
}
|
||||||
|
auto result = pthread_timedjoin_np(thread.native_handle(), nullptr, &ts);
|
||||||
|
if(result > 0 && result != ESRCH) return false;
|
||||||
|
|
||||||
|
/* let the std lib set their flags */
|
||||||
|
std::thread _empty{}; /* could be destroyed even with an "active" thread handle because we overwrote the std::terminate() function with a macro */
|
||||||
|
_empty = std::move(thread);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Undefined behaviour:
|
||||||
|
* We destroy everything in a non trivial class,
|
||||||
|
* But when we take a closer look its just a wrapper around the native_handle type which could be an DWORD or a pthread_t which are both trivial destructible!
|
||||||
|
*/
|
||||||
|
memset(&_empty, 0, sizeof(_empty)); // NOLINT(bugprone-undefined-memory-manipulation)
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
26
src/misc/threads.h
Normal file
26
src/misc/threads.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace threads {
|
||||||
|
extern bool name(std::thread& /* thread */, const std::string_view& /* name */);
|
||||||
|
extern std::string name(std::thread& /* thread */);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function will not throw an error if the thread has already been joined.
|
||||||
|
* It returns true if join succeeded, false on any error (like thread has already be joined)
|
||||||
|
*/
|
||||||
|
extern bool save_join(std::thread& /* thread */, bool /* ignore resource deadlock */ = false);
|
||||||
|
|
||||||
|
extern bool timed_join(std::thread& /* thread */, const std::chrono::nanoseconds& /* timeout */);
|
||||||
|
|
||||||
|
template <typename Clock>
|
||||||
|
inline bool timed_join(std::thread& thread, const std::chrono::time_point<Clock>& timeout) {
|
||||||
|
auto now = Clock::now();
|
||||||
|
if(now > timeout)
|
||||||
|
timeout = now;
|
||||||
|
return timed_join(thread, timeout - now);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//#define NO_OPEN_SSL /* because we're lazy and dont want to build this lib extra for the TeaClient */
|
//#define NO_OPEN_SSL /* because we're lazy and dont want to build this lib extra for the TeaClient */
|
||||||
#define FIXEDINT_H_INCLUDED /* else it will be included by ge */
|
#define FIXEDINT_H_INCLUDED /* else it will be included by ge */
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include <ed25519/ge.h>
|
#include <ed25519/ge.h>
|
||||||
#include <ed25519/ed25519.h>
|
#include <ed25519/ed25519.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user