cmake: Further refactoring and formatting
This commit is contained in:
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
# Basic Formatting
|
# Basic Formatting
|
||||||
TabWidth: 8
|
TabWidth: 4
|
||||||
UseTab: ForIndentation
|
UseTab: ForContinuationAndIndentation
|
||||||
ColumnLimit: 120
|
ColumnLimit: 120
|
||||||
|
|
||||||
# Language
|
# Language
|
||||||
@@ -13,7 +13,7 @@ ConstructorInitializerIndentWidth: 4
|
|||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
#IndentPPDirectives: true
|
#IndentPPDirectives: true
|
||||||
IndentWidth: 8
|
IndentWidth: 4
|
||||||
IndentWrappedFunctionNames: true
|
IndentWrappedFunctionNames: true
|
||||||
NamespaceIndentation: All
|
NamespaceIndentation: All
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ SortIncludes: true
|
|||||||
AlignAfterOpenBracket: true
|
AlignAfterOpenBracket: true
|
||||||
AlignConsecutiveAssignments: true
|
AlignConsecutiveAssignments: true
|
||||||
AlignConsecutiveDeclarations: true
|
AlignConsecutiveDeclarations: true
|
||||||
AlignEscapedNewlines: DontAlign
|
AlignEscapedNewlines: Left
|
||||||
AlignOperands: true
|
AlignOperands: true
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file.
|
||||||
|
[*]
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
+112
-96
@@ -91,25 +91,26 @@ endif()
|
|||||||
# Options
|
# Options
|
||||||
#================================================================================#
|
#================================================================================#
|
||||||
# Static or Dynamic?
|
# Static or Dynamic?
|
||||||
option(${PropertyPrefix}MAKE_STATIC "Make Static Library" ON)
|
option(${PropertyPrefix}MAKE_DYNAMIC "Create dynamically linked library instead of static library." OFF)
|
||||||
option(${PropertyPrefix}MAKE_DYNAMIC "Make Dynamic Library" OFF)
|
option(${PropertyPrefix}MAKE_MODULE "Create dynamically linked module instead of dynamically linked library." OFF)
|
||||||
option(${PropertyPrefix}MAKE_MODULE "Make Module Library" OFF)
|
option(${PropertyPrefix}BUILD_SAMPLES "Build Samples" ON)
|
||||||
|
|
||||||
#================================================================================#
|
#================================================================================#
|
||||||
# Sources
|
# Sources
|
||||||
option(${PropertyPrefix}BUILD_SAMPLES "Build Samples" ON)
|
#================================================================================#
|
||||||
|
|
||||||
# Configure Version Header
|
# Configure Version Header
|
||||||
configure_file(
|
configure_file(
|
||||||
"${PROJECT_SOURCE_DIR}/cmake/version.hpp.in"
|
"${PROJECT_SOURCE_DIR}/cmake/version.hpp.in"
|
||||||
"${PROJECT_BINARY_DIR}/include/version.hpp"
|
"${PROJECT_BINARY_DIR}/generated/version.hpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Public (exported with module)
|
# Source Files
|
||||||
set(PROJECT_PUBLIC
|
set(PROJECT_PUBLIC "")
|
||||||
"include/bitmask.hpp"
|
list(APPEND PROJECT_PUBLIC
|
||||||
"include/datapath.hpp"
|
"include/datapath.hpp"
|
||||||
"include/error.hpp"
|
"include/error.hpp"
|
||||||
|
"include/bitmask.hpp"
|
||||||
"include/event.hpp"
|
"include/event.hpp"
|
||||||
"include/isocket.hpp"
|
"include/isocket.hpp"
|
||||||
"include/iserver.hpp"
|
"include/iserver.hpp"
|
||||||
@@ -119,27 +120,30 @@ set(PROJECT_PUBLIC
|
|||||||
"include/threadpool.hpp"
|
"include/threadpool.hpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PROJECT_PUBLIC_GENERATED
|
set(PROJECT_PRIVATE "")
|
||||||
"${PROJECT_BINARY_DIR}/include/version.hpp"
|
list(APPEND PROJECT_PRIVATE
|
||||||
|
"source/threadpool.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PROJECT_DATA
|
set(PROJECT_TEMPLATES "")
|
||||||
|
list(APPEND PROJECT_TEMPLATES
|
||||||
|
"${PROJECT_SOURCE_DIR}/cmake/version.hpp.in"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_GENERATED "")
|
||||||
|
list(APPEND PROJECT_GENERATED
|
||||||
|
"${PROJECT_BINARY_DIR}/generated/version.hpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_DATA "")
|
||||||
|
list(APPEND PROJECT_DATA
|
||||||
"README.md"
|
"README.md"
|
||||||
"LICENSE"
|
"LICENSE"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Private (only compiled/used locally)
|
set(PROJECT_LIBRARIES "")
|
||||||
set(PROJECT_PRIVATE
|
|
||||||
"source/threadpool.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Libraries
|
set(PROJECT_DEFINES "")
|
||||||
set(PROJECT_LIBRARIES
|
|
||||||
)
|
|
||||||
|
|
||||||
# Defines
|
|
||||||
set(PROJECT_DEFINES
|
|
||||||
)
|
|
||||||
|
|
||||||
# Platforms
|
# Platforms
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@@ -150,48 +154,48 @@ if(WIN32)
|
|||||||
|
|
||||||
list(APPEND PROJECT_DEFINES
|
list(APPEND PROJECT_DEFINES
|
||||||
_CRT_SECURE_NO_WARNINGS
|
_CRT_SECURE_NO_WARNINGS
|
||||||
WIN32_LEAN_AND_MEAN
|
WIN32_LEAN_AND_MEAN
|
||||||
NOGPICAPMASKS
|
NOGPICAPMASKS
|
||||||
NOVIRTUALKEYCODES
|
NOVIRTUALKEYCODES
|
||||||
NOWINMESSAGES
|
NOWINMESSAGES
|
||||||
NOWINSTYLES
|
NOWINSTYLES
|
||||||
NOSYSMETRICS
|
NOSYSMETRICS
|
||||||
NOMENUS
|
NOMENUS
|
||||||
NOICONS
|
NOICONS
|
||||||
NOKEYSTATES
|
NOKEYSTATES
|
||||||
NOSYSCOMMANDS
|
NOSYSCOMMANDS
|
||||||
NORASTEROPS
|
NORASTEROPS
|
||||||
NOSHOWWINDOW
|
NOSHOWWINDOW
|
||||||
NOATOM
|
NOATOM
|
||||||
NOCLIPBOARD
|
NOCLIPBOARD
|
||||||
NOCOLOR
|
NOCOLOR
|
||||||
NOCTLMGR
|
NOCTLMGR
|
||||||
NODRAWTEXT
|
NODRAWTEXT
|
||||||
NOGDI
|
NOGDI
|
||||||
NOKERNEL
|
NOKERNEL
|
||||||
#NOUSER
|
#NOUSER
|
||||||
#NONLS
|
#NONLS
|
||||||
NOMB
|
NOMB
|
||||||
NOMEMMGR
|
NOMEMMGR
|
||||||
NOMETAFILE
|
NOMETAFILE
|
||||||
NOMINMAX
|
NOMINMAX
|
||||||
NOMSG
|
NOMSG
|
||||||
NOOPENFILE
|
NOOPENFILE
|
||||||
NOSCROLL
|
NOSCROLL
|
||||||
NOSERVICE
|
NOSERVICE
|
||||||
NOSOUND
|
NOSOUND
|
||||||
NOTEXTMETRIC
|
NOTEXTMETRIC
|
||||||
NOWH
|
NOWH
|
||||||
NOWINOFFSETS
|
NOWINOFFSETS
|
||||||
NOCOMM
|
NOCOMM
|
||||||
NOKANJI
|
NOKANJI
|
||||||
NOHELP
|
NOHELP
|
||||||
NOPROFILER
|
NOPROFILER
|
||||||
NODEFERWINDOWPOS
|
NODEFERWINDOWPOS
|
||||||
NOMCX
|
NOMCX
|
||||||
NOIME
|
NOIME
|
||||||
NOMDI
|
NOMDI
|
||||||
NOINOUT
|
NOINOUT
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND PROJECT_PRIVATE
|
list(APPEND PROJECT_PRIVATE
|
||||||
@@ -225,45 +229,58 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Grouping
|
# Grouping
|
||||||
source_group("Data Files" FILES $PROJECT_DATA)
|
source_group(TREE "${PROJECT_SOURCE_DIR}" PREFIX "Data Files" FILES ${PROJECT_DATA})
|
||||||
source_group(TREE "${PROJECT_SOURCE_DIR}/source" PREFIX "Source" FILES ${PROJECT_PRIVATE})
|
source_group(TREE "${PROJECT_SOURCE_DIR}/cmake" PREFIX "Template Files" FILES ${PROJECT_TEMPLATES})
|
||||||
source_group(TREE "${PROJECT_SOURCE_DIR}/include" PREFIX "Include" FILES ${PROJECT_PUBLIC})
|
source_group(TREE "${PROJECT_BINARY_DIR}/generated" PREFIX "Generated Files" FILES ${PROJECT_GENERATED})
|
||||||
source_group(TREE "${PROJECT_BINARY_DIR}" PREFIX "Generated" FILES ${PROJECT_PUBLIC_GENERATED})
|
source_group(TREE "${PROJECT_SOURCE_DIR}/include" PREFIX "Exported Files" FILES ${PROJECT_PUBLIC})
|
||||||
|
|
||||||
|
# Filter Sources
|
||||||
|
set(_TMP_SOURCE ${PROJECT_PRIVATE})
|
||||||
|
list(FILTER _TMP_SOURCE INCLUDE REGEX "\.(c|cpp)$")
|
||||||
|
source_group(TREE "${PROJECT_SOURCE_DIR}/source" PREFIX "Source Files" FILES ${_TMP_SOURCE})
|
||||||
|
|
||||||
|
# Filter Headers
|
||||||
|
set(_TMP_HEADER ${PROJECT_PRIVATE})
|
||||||
|
list(FILTER _TMP_HEADER INCLUDE REGEX "\.(h|hpp)$")
|
||||||
|
source_group(TREE "${PROJECT_SOURCE_DIR}/source" PREFIX "Header Files" FILES ${_TMP_HEADER})
|
||||||
|
|
||||||
#================================================================================#
|
#================================================================================#
|
||||||
# Building
|
# Building
|
||||||
#================================================================================#
|
#================================================================================#
|
||||||
|
|
||||||
# Library definition
|
# Library definition
|
||||||
if(${PropertyPrefix}MAKE_STATIC)
|
set(_BUILD_TYPE)
|
||||||
add_library(${PROJECT_NAME} STATIC
|
if(${PropertyPrefix}MAKE_DYNAMIC)
|
||||||
${PROJECT_PRIVATE}
|
if(${PropertyPrefix}MAKE_MODULE)
|
||||||
${PROJECT_PUBLIC}
|
set(_BUILD_TYPE MODULE)
|
||||||
${PROJECT_PUBLIC_GENERATED}
|
else()
|
||||||
${PROJECT_DATA}
|
set(_BUILD_TYPE SHARED)
|
||||||
)
|
endif()
|
||||||
elseif(${PropertyPrefix}MAKE_DYNAMIC)
|
|
||||||
add_library(${PROJECT_NAME} SHARED
|
|
||||||
${PROJECT_PRIVATE}
|
|
||||||
${PROJECT_PUBLIC}
|
|
||||||
${PROJECT_PUBLIC_GENERATED}
|
|
||||||
${PROJECT_DATA}
|
|
||||||
)
|
|
||||||
elseif(${PropertyPrefix}MAKE_MODULE)
|
|
||||||
add_library(${PROJECT_NAME} MODULE
|
|
||||||
${PROJECT_PRIVATE}
|
|
||||||
${PROJECT_PUBLIC}
|
|
||||||
${PROJECT_PUBLIC_GENERATED}
|
|
||||||
${PROJECT_DATA}
|
|
||||||
)
|
|
||||||
else()
|
else()
|
||||||
message(CRITICAL "Building nothing completed, aborting. Check MAKE_STATIC, MAKE_DYNAMIC and MAKE_DYNAMIC.")
|
set(_BUILD_TYPE STATIC)
|
||||||
return()
|
endif()
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} ${_BUILD_TYPE}
|
||||||
|
${PROJECT_PUBLIC}
|
||||||
|
${PROJECT_PRIVATE}
|
||||||
|
${PROJECT_GENERATED}
|
||||||
|
${PROJECT_TEMPLATES}
|
||||||
|
${PROJECT_DATA}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clang
|
||||||
|
if("${PropertyPrefix}" STREQUAL "")
|
||||||
|
clang_format(
|
||||||
|
TARGETS ${PROJECT_NAME}
|
||||||
|
DEPENDENCY
|
||||||
|
VERSION 9.0.0
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Includes
|
# Includes
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME}
|
||||||
PRIVATE source
|
PRIVATE "source"
|
||||||
PUBLIC include
|
PUBLIC "include"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Defines
|
# Defines
|
||||||
@@ -297,10 +314,9 @@ else()
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#================================================================================#
|
||||||
################################################################################
|
|
||||||
# Samples
|
# Samples
|
||||||
################################################################################
|
#================================================================================#
|
||||||
if(${PropertyPrefix}BUILD_SAMPLES)
|
if(${PropertyPrefix}BUILD_SAMPLES)
|
||||||
add_subdirectory(${PROJECT_SOURCE_DIR}/samples)
|
add_subdirectory(${PROJECT_SOURCE_DIR}/samples)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
+2
-2
@@ -38,8 +38,8 @@ typename std::enable_if<enable_bitmask_operators<Enum>::enable, Enum>::type oper
|
|||||||
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
|
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ENABLE_BITMASK_OPERATORS(x) \
|
#define ENABLE_BITMASK_OPERATORS(x) \
|
||||||
template<> \
|
template<> \
|
||||||
struct enable_bitmask_operators<x> { \
|
struct enable_bitmask_operators<x> { \
|
||||||
static const bool enable = true; \
|
static const bool enable = true; \
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ namespace datapath {
|
|||||||
datapath::error connect(std::shared_ptr<datapath::isocket>& socket, std::string path);
|
datapath::error connect(std::shared_ptr<datapath::isocket>& socket, std::string path);
|
||||||
|
|
||||||
datapath::error host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
datapath::error host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
||||||
datapath::permissions permissions, size_t max_clients = 0);
|
datapath::permissions permissions, size_t max_clients = 0);
|
||||||
} // namespace datapath
|
} // namespace datapath
|
||||||
|
|||||||
+17
-17
@@ -24,10 +24,10 @@
|
|||||||
namespace datapath {
|
namespace datapath {
|
||||||
template<typename... _args>
|
template<typename... _args>
|
||||||
class event {
|
class event {
|
||||||
std::list<std::function<void(_args...)>> listeners;
|
std::list<std::function<void(_args...)>> _listeners;
|
||||||
|
|
||||||
std::function<void()> listen_cb;
|
std::function<void()> _listen_cb;
|
||||||
std::function<void()> silence_cb;
|
std::function<void()> _silence_cb;
|
||||||
|
|
||||||
public /* functions */:
|
public /* functions */:
|
||||||
|
|
||||||
@@ -40,20 +40,20 @@ namespace datapath {
|
|||||||
// Add new listener.
|
// Add new listener.
|
||||||
inline void add(std::function<void(_args...)> listener)
|
inline void add(std::function<void(_args...)> listener)
|
||||||
{
|
{
|
||||||
if (listeners.size() == 0) {
|
if (_listeners.size() == 0) {
|
||||||
if (listen_cb) {
|
if (_listen_cb) {
|
||||||
listen_cb();
|
_listen_cb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
listeners.push_back(listener);
|
_listeners.push_back(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove existing listener.
|
// Remove existing listener.
|
||||||
inline void remove(std::function<void(_args...)> listener)
|
inline void remove(std::function<void(_args...)> listener)
|
||||||
{
|
{
|
||||||
listeners.remove(listener);
|
_listeners.remove(listener);
|
||||||
if (listeners.size() == 0) {
|
if (_listeners.size() == 0) {
|
||||||
if (silence_cb) {
|
if (_silence_cb) {
|
||||||
silence_cb();
|
silence_cb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,15 +62,15 @@ namespace datapath {
|
|||||||
// Check if empty / no listeners.
|
// Check if empty / no listeners.
|
||||||
inline bool empty()
|
inline bool empty()
|
||||||
{
|
{
|
||||||
return listeners.empty();
|
return _listeners.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all listeners.
|
// Remove all listeners.
|
||||||
inline void clear()
|
inline void clear()
|
||||||
{
|
{
|
||||||
listeners.clear();
|
_listeners.clear();
|
||||||
if (silence_cb) {
|
if (_silence_cb) {
|
||||||
silence_cb();
|
_silence_cb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ namespace datapath {
|
|||||||
template<typename... _largs>
|
template<typename... _largs>
|
||||||
inline void operator()(_args... args)
|
inline void operator()(_args... args)
|
||||||
{
|
{
|
||||||
for (auto& l : listeners) {
|
for (auto& l : _listeners) {
|
||||||
l(args...);
|
l(args...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,12 +108,12 @@ namespace datapath {
|
|||||||
public /* events */:
|
public /* events */:
|
||||||
void set_listen_callback(std::function<void()> cb)
|
void set_listen_callback(std::function<void()> cb)
|
||||||
{
|
{
|
||||||
this->listen_cb = cb;
|
this->_listen_cb = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_silence_callback(std::function<void()> cb)
|
void set_silence_callback(std::function<void()> cb)
|
||||||
{
|
{
|
||||||
this->silence_cb = cb;
|
this->_silence_cb = cb;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}; // namespace datapath
|
}; // namespace datapath
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ namespace datapath {
|
|||||||
* @param std::shared_ptr<datapath::isocket> Socket.
|
* @param std::shared_ptr<datapath::isocket> Socket.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
datapath::event<bool&, std::shared_ptr<datapath::isocket>> on_accept;
|
datapath::event<bool&, std::shared_ptr<datapath::isocket>> _on_accept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual datapath::error close() = 0;
|
virtual datapath::error close() = 0;
|
||||||
|
|||||||
+2
-2
@@ -24,9 +24,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
namespace datapath {
|
namespace datapath {
|
||||||
class isocket {
|
class isocket {
|
||||||
public /*events*/:
|
public /*events*/:
|
||||||
datapath::event<const std::vector<char>&> on_message;
|
datapath::event<const std::vector<char>&> _on_message;
|
||||||
|
|
||||||
datapath::event<> on_close;
|
datapath::event<> _on_close;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool good() = 0;
|
virtual bool good() = 0;
|
||||||
|
|||||||
+2
-2
@@ -26,9 +26,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
namespace datapath {
|
namespace datapath {
|
||||||
class itask : public waitable {
|
class itask : public waitable {
|
||||||
public /*event*/:
|
public /*event*/:
|
||||||
datapath::event<datapath::error> on_failure;
|
datapath::event<datapath::error> _on_failure;
|
||||||
|
|
||||||
datapath::event<datapath::error, const std::vector<char>&> on_success;
|
datapath::event<datapath::error, const std::vector<char>&> _on_success;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual datapath::error cancel() = 0;
|
virtual datapath::error cancel() = 0;
|
||||||
|
|||||||
@@ -21,12 +21,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include "bitmask.hpp"
|
#include "bitmask.hpp"
|
||||||
|
|
||||||
namespace datapath {
|
namespace datapath {
|
||||||
enum class permissions : int8_t {
|
enum class permissions : int8_t { None, User, Group, World, Reserved };
|
||||||
None,
|
|
||||||
User,
|
|
||||||
Group,
|
|
||||||
World,
|
|
||||||
Reserved
|
|
||||||
};
|
|
||||||
ENABLE_BITMASK_OPERATORS(datapath::permissions);
|
ENABLE_BITMASK_OPERATORS(datapath::permissions);
|
||||||
} // namespace datapath
|
} // namespace datapath
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
|
|
||||||
namespace datapath {
|
namespace datapath {
|
||||||
namespace threadpool {
|
namespace threadpool {
|
||||||
typedef uint64_t affinity_t;
|
typedef uint64_t affinity_t;
|
||||||
|
|
||||||
constexpr affinity_t default_mask = std::numeric_limits<affinity_t>::max();
|
constexpr affinity_t default_mask = std::numeric_limits<affinity_t>::max();
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ namespace datapath {
|
|||||||
void push(std::shared_ptr<task> task);
|
void push(std::shared_ptr<task> task);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<affinity_t, std::shared_ptr<worker>> workers;
|
std::map<affinity_t, std::shared_ptr<worker>> _workers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pool();
|
pool();
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
namespace datapath {
|
namespace datapath {
|
||||||
class waitable {
|
class waitable {
|
||||||
public /*events*/:
|
public /*events*/:
|
||||||
datapath::event<datapath::error> on_wait_error;
|
datapath::event<datapath::error> _on_wait_error;
|
||||||
|
|
||||||
datapath::event<datapath::error> on_wait_success;
|
datapath::event<datapath::error> _on_wait_success;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void* get_waitable() = 0;
|
virtual void* get_waitable() = 0;
|
||||||
@@ -40,22 +40,22 @@ namespace datapath {
|
|||||||
public /*static*/:
|
public /*static*/:
|
||||||
|
|
||||||
static datapath::error wait(datapath::waitable* obj,
|
static datapath::error wait(datapath::waitable* obj,
|
||||||
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0));
|
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0));
|
||||||
|
|
||||||
static datapath::error wait(datapath::waitable** objs, size_t count,
|
static datapath::error wait(datapath::waitable** objs, size_t count,
|
||||||
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0));
|
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0));
|
||||||
|
|
||||||
static inline datapath::error wait(std::vector<datapath::waitable*> objs,
|
static inline datapath::error wait(std::vector<datapath::waitable*> objs,
|
||||||
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0))
|
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0))
|
||||||
{
|
{
|
||||||
return datapath::waitable::wait(objs.data(), objs.size(), duration);
|
return datapath::waitable::wait(objs.data(), objs.size(), duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
static datapath::error wait_any(datapath::waitable** objs, size_t count, size_t& index,
|
static datapath::error wait_any(datapath::waitable** objs, size_t count, size_t& index,
|
||||||
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0));
|
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0));
|
||||||
|
|
||||||
static inline datapath::error wait_any(std::vector<datapath::waitable*> objs, size_t& index,
|
static inline datapath::error wait_any(std::vector<datapath::waitable*> objs, size_t& index,
|
||||||
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0))
|
std::chrono::nanoseconds duration = std::chrono::nanoseconds(0))
|
||||||
{
|
{
|
||||||
return datapath::waitable::wait_any(objs.data(), objs.size(), index, duration);
|
return datapath::waitable::wait_any(objs.data(), objs.size(), index, duration);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ void datapath::threadpool::pool::worker::runner()
|
|||||||
my_task.reset();
|
my_task.reset();
|
||||||
}
|
}
|
||||||
if (this->queue.size() == 0) {
|
if (this->queue.size() == 0) {
|
||||||
this->signal.wait(slock,
|
this->signal.wait(slock, [this]() { return (this->should_stop) || (this->queue.size() > 0); });
|
||||||
[this]() { return (this->should_stop) || (this->queue.size() > 0); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,13 +93,13 @@ datapath::threadpool::pool::pool()
|
|||||||
uint64_t num_hw_concurrency = std::thread::hardware_concurrency();
|
uint64_t num_hw_concurrency = std::thread::hardware_concurrency();
|
||||||
for (uint64_t idx = 0; idx < num_hw_concurrency; idx++) {
|
for (uint64_t idx = 0; idx < num_hw_concurrency; idx++) {
|
||||||
auto worker = std::make_shared<datapath::threadpool::pool::worker>(1 << idx);
|
auto worker = std::make_shared<datapath::threadpool::pool::worker>(1 << idx);
|
||||||
this->workers.insert({idx, worker});
|
this->_workers.insert({idx, worker});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
datapath::threadpool::pool::~pool()
|
datapath::threadpool::pool::~pool()
|
||||||
{
|
{
|
||||||
this->workers.clear();
|
this->_workers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool datapath::threadpool::pool::push(std::shared_ptr<task> task)
|
bool datapath::threadpool::pool::push(std::shared_ptr<task> task)
|
||||||
@@ -114,13 +113,13 @@ bool datapath::threadpool::pool::push(std::shared_ptr<task> task)
|
|||||||
throw std::invalid_argument("task->function must not be nullptr");
|
throw std::invalid_argument("task->function must not be nullptr");
|
||||||
}
|
}
|
||||||
/// Check for invalid affinity masks.
|
/// Check for invalid affinity masks.
|
||||||
if ((task->mask & (this->workers.size() - 1)) == 0) {
|
if ((task->mask & (this->_workers.size() - 1)) == 0) {
|
||||||
throw std::invalid_argument("mask does not fit any thread");
|
throw std::invalid_argument("mask does not fit any thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
affinity_t lowest_id;
|
affinity_t lowest_id;
|
||||||
size_t lowest_count = std::numeric_limits<size_t>::max();
|
size_t lowest_count = std::numeric_limits<size_t>::max();
|
||||||
for (auto kv : workers) {
|
for (auto kv : _workers) {
|
||||||
if ((kv.second->affinity & task->mask) == 0) {
|
if ((kv.second->affinity & task->mask) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -135,18 +134,18 @@ bool datapath::threadpool::pool::push(std::shared_ptr<task> task)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->workers[lowest_id]->push(task);
|
this->_workers[lowest_id]->push(task);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void datapath::threadpool::pool::clear(affinity_t mask)
|
void datapath::threadpool::pool::clear(affinity_t mask)
|
||||||
{
|
{
|
||||||
// Early-Exit tests.
|
// Early-Exit tests.
|
||||||
if ((mask & (this->workers.size() - 1)) == 0) {
|
if ((mask & (this->_workers.size() - 1)) == 0) {
|
||||||
throw std::invalid_argument("mask does not fit any thread");
|
throw std::invalid_argument("mask does not fit any thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto kv : workers) {
|
for (auto kv : _workers) {
|
||||||
if ((kv.second->affinity & mask) == 0) {
|
if ((kv.second->affinity & mask) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ datapath::error datapath::connect(std::shared_ptr<datapath::isocket>& socket, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
datapath::error datapath::host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
datapath::error datapath::host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
||||||
datapath::permissions permissions, size_t max_clients)
|
datapath::permissions permissions, size_t max_clients)
|
||||||
{
|
{
|
||||||
return datapath::windows::server::host(server, path, permissions, max_clients);
|
return datapath::windows::server::host(server, path, permissions, max_clients);
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-18
@@ -26,7 +26,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#define WIN_BACKLOG_NUM 8
|
#define WIN_BACKLOG_NUM 8
|
||||||
|
|
||||||
datapath::error datapath::windows::server::create(std::string path, datapath::permissions permissions,
|
datapath::error datapath::windows::server::create(std::string path, datapath::permissions permissions,
|
||||||
size_t max_clients)
|
size_t max_clients)
|
||||||
{
|
{
|
||||||
// If old sockets are available, close them.
|
// If old sockets are available, close them.
|
||||||
this->close();
|
this->close();
|
||||||
@@ -84,8 +84,8 @@ HANDLE datapath::windows::server::_create_socket(std::string path, bool initial)
|
|||||||
|
|
||||||
DWORD pipe_flags = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
|
DWORD pipe_flags = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
|
||||||
|
|
||||||
HANDLE handle = CreateNamedPipeW(wpath.c_str(), file_flags, pipe_flags, PIPE_UNLIMITED_INSTANCES,
|
HANDLE handle = CreateNamedPipeW(wpath.c_str(), file_flags, pipe_flags, PIPE_UNLIMITED_INSTANCES, WIN_BUFFER_SIZE,
|
||||||
WIN_BUFFER_SIZE, WIN_BUFFER_SIZE, WIN_WAIT_TIME, &this->security_attributes);
|
WIN_BUFFER_SIZE, WIN_WAIT_TIME, &this->security_attributes);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ void datapath::windows::server::_watcher()
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
datapath::error ec = datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(0));
|
datapath::error ec = datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(0));
|
||||||
if (ec != datapath::error::Success) {
|
if (ec != datapath::error::Success) {
|
||||||
datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(1));
|
datapath::waitable::wait_any(waits, index, std::chrono::milliseconds(1));
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ void datapath::windows::server::_watcher()
|
|||||||
auto ov = std::make_shared<datapath::windows::overlapped>();
|
auto ov = std::make_shared<datapath::windows::overlapped>();
|
||||||
ov->set_handle(handle);
|
ov->set_handle(handle);
|
||||||
ov->set_data(this);
|
ov->set_data(this);
|
||||||
ov->on_wait_success.add([this, &ovmap, &itr, &handle](datapath::error ec) {
|
ov->_on_wait_success.add([this, &ovmap, &itr, &handle](datapath::error ec) {
|
||||||
std::unique_lock<std::mutex> ul(this->lock);
|
std::unique_lock<std::mutex> ul(this->lock);
|
||||||
this->waiting_sockets.erase(itr);
|
this->waiting_sockets.erase(itr);
|
||||||
this->pending_sockets.push_back(handle);
|
this->pending_sockets.push_back(handle);
|
||||||
@@ -152,9 +152,8 @@ void datapath::windows::server::_watcher()
|
|||||||
std::unique_lock<std::mutex> ul(this->lock);
|
std::unique_lock<std::mutex> ul(this->lock);
|
||||||
std::list<HANDLE> to_kill;
|
std::list<HANDLE> to_kill;
|
||||||
|
|
||||||
if (this->on_accept) {
|
if (this->_on_accept) {
|
||||||
for (auto itr = this->pending_sockets.begin(); itr != this->pending_sockets.end();
|
for (auto itr = this->pending_sockets.begin(); itr != this->pending_sockets.end(); itr++) {
|
||||||
itr++) {
|
|
||||||
HANDLE handle = *itr;
|
HANDLE handle = *itr;
|
||||||
bool accept = true;
|
bool accept = true;
|
||||||
|
|
||||||
@@ -162,16 +161,14 @@ void datapath::windows::server::_watcher()
|
|||||||
sock->_connect(handle);
|
sock->_connect(handle);
|
||||||
|
|
||||||
auto isock = std::dynamic_pointer_cast<datapath::isocket>(sock);
|
auto isock = std::dynamic_pointer_cast<datapath::isocket>(sock);
|
||||||
this->on_accept(accept, isock);
|
this->_on_accept(accept, isock);
|
||||||
|
|
||||||
if (accept) {
|
if (accept) {
|
||||||
to_kill.push_back(handle);
|
to_kill.push_back(handle);
|
||||||
this->active_sockets.insert({handle, sock});
|
this->active_sockets.insert({handle, sock});
|
||||||
|
|
||||||
if ((this->waiting_sockets.size() + this->pending_sockets.size())
|
if ((this->waiting_sockets.size() + this->pending_sockets.size()) < WIN_BACKLOG_NUM) {
|
||||||
< WIN_BACKLOG_NUM) {
|
if ((this->sockets.size() <= this->max_clients) && (this->max_clients > 0)) {
|
||||||
if ((this->sockets.size() <= this->max_clients)
|
|
||||||
&& (this->max_clients > 0)) {
|
|
||||||
HANDLE handle = _create_socket(this->path, false);
|
HANDLE handle = _create_socket(this->path, false);
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
if (handle != INVALID_HANDLE_VALUE) {
|
||||||
this->sockets.push_back(handle);
|
this->sockets.push_back(handle);
|
||||||
@@ -199,8 +196,7 @@ void datapath::windows::server::_watcher()
|
|||||||
for (auto itr = this->active_sockets.begin(); itr != this->active_sockets.end(); itr++) {
|
for (auto itr = this->active_sockets.begin(); itr != this->active_sockets.end(); itr++) {
|
||||||
if (itr->second.expired()) {
|
if (itr->second.expired()) {
|
||||||
// Enforce backlog size
|
// Enforce backlog size
|
||||||
if ((this->waiting_sockets.size() + this->pending_sockets.size())
|
if ((this->waiting_sockets.size() + this->pending_sockets.size()) < WIN_BACKLOG_NUM) {
|
||||||
< WIN_BACKLOG_NUM) {
|
|
||||||
this->waiting_sockets.push_back(itr->first);
|
this->waiting_sockets.push_back(itr->first);
|
||||||
} else {
|
} else {
|
||||||
DisconnectNamedPipe(itr->first);
|
DisconnectNamedPipe(itr->first);
|
||||||
@@ -213,8 +209,7 @@ void datapath::windows::server::_watcher()
|
|||||||
auto obj = itr->second.lock();
|
auto obj = itr->second.lock();
|
||||||
if (!obj->good()) {
|
if (!obj->good()) {
|
||||||
// Enforce backlog size
|
// Enforce backlog size
|
||||||
if ((this->waiting_sockets.size() + this->pending_sockets.size())
|
if ((this->waiting_sockets.size() + this->pending_sockets.size()) < WIN_BACKLOG_NUM) {
|
||||||
< WIN_BACKLOG_NUM) {
|
|
||||||
this->waiting_sockets.push_back(itr->first);
|
this->waiting_sockets.push_back(itr->first);
|
||||||
} else {
|
} else {
|
||||||
DisconnectNamedPipe(itr->first);
|
DisconnectNamedPipe(itr->first);
|
||||||
@@ -299,7 +294,7 @@ datapath::error datapath::windows::server::close()
|
|||||||
}
|
}
|
||||||
|
|
||||||
datapath::error datapath::windows::server::host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
datapath::error datapath::windows::server::host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
||||||
datapath::permissions permissions, size_t max_clients)
|
datapath::permissions permissions, size_t max_clients)
|
||||||
{
|
{
|
||||||
if (!server) {
|
if (!server) {
|
||||||
server = std::dynamic_pointer_cast<datapath::iserver>(std::make_shared<datapath::windows::server>());
|
server = std::dynamic_pointer_cast<datapath::iserver>(std::make_shared<datapath::windows::server>());
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace datapath {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static datapath::error host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
static datapath::error host(std::shared_ptr<datapath::iserver>& server, std::string path,
|
||||||
datapath::permissions permissions, size_t max_clients);
|
datapath::permissions permissions, size_t max_clients);
|
||||||
};
|
};
|
||||||
} // namespace windows
|
} // namespace windows
|
||||||
} // namespace datapath
|
} // namespace datapath
|
||||||
+30
-34
@@ -39,8 +39,8 @@ void datapath::windows::socket::_connect(HANDLE handle)
|
|||||||
|
|
||||||
void datapath::windows::socket::_disconnect()
|
void datapath::windows::socket::_disconnect()
|
||||||
{
|
{
|
||||||
if (this->on_close) {
|
if (this->_on_close) {
|
||||||
this->on_close();
|
this->_on_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -62,45 +62,42 @@ void datapath::windows::socket::_watcher()
|
|||||||
|
|
||||||
std::vector<char> read_buffer;
|
std::vector<char> read_buffer;
|
||||||
|
|
||||||
std::shared_ptr<datapath::windows::overlapped> read_header_ov =
|
std::shared_ptr<datapath::windows::overlapped> read_header_ov = std::make_shared<datapath::windows::overlapped>();
|
||||||
std::make_shared<datapath::windows::overlapped>();
|
std::shared_ptr<datapath::windows::overlapped> read_content_ov = std::make_shared<datapath::windows::overlapped>();
|
||||||
std::shared_ptr<datapath::windows::overlapped> read_content_ov =
|
|
||||||
std::make_shared<datapath::windows::overlapped>();
|
|
||||||
std::shared_ptr<datapath::windows::overlapped> waitable;
|
std::shared_ptr<datapath::windows::overlapped> waitable;
|
||||||
|
|
||||||
read_header_ov->on_wait_error.add([&state, &waitable](datapath::error ec) {
|
read_header_ov->_on_wait_error.add([&state, &waitable](datapath::error ec) {
|
||||||
// There was an error waiting on the header.
|
// There was an error waiting on the header.
|
||||||
state = readstate::Unknown;
|
state = readstate::Unknown;
|
||||||
waitable.reset();
|
waitable.reset();
|
||||||
});
|
});
|
||||||
read_header_ov->on_wait_success.add(
|
read_header_ov->_on_wait_success.add([this, &read_buffer, &read_content_ov, &state, &waitable](datapath::error ec) {
|
||||||
[this, &read_buffer, &read_content_ov, &state, &waitable](datapath::error ec) {
|
read_content_ov->set_handle(this->socket_handle);
|
||||||
read_content_ov->set_handle(this->socket_handle);
|
read_content_ov->set_data(this);
|
||||||
read_content_ov->set_data(this);
|
|
||||||
|
|
||||||
// ToDo: Add optional message size limit, messages above this size kill the connection for attempting DoS.
|
// ToDo: Add optional message size limit, messages above this size kill the connection for attempting DoS.
|
||||||
size_t msg_size = reinterpret_cast<SIZE_ELEMENT&>(read_buffer[0]);
|
size_t msg_size = reinterpret_cast<SIZE_ELEMENT&>(read_buffer[0]);
|
||||||
read_buffer.resize(msg_size);
|
read_buffer.resize(msg_size);
|
||||||
|
|
||||||
// Read content.
|
// Read content.
|
||||||
if (ReadFileEx(this->socket_handle, read_buffer.data(), DWORD(read_buffer.size()),
|
if (ReadFileEx(this->socket_handle, read_buffer.data(), DWORD(read_buffer.size()),
|
||||||
read_content_ov->get_overlapped(), &datapath::windows::utility::def_io_completion_routine)) {
|
read_content_ov->get_overlapped(), &datapath::windows::utility::def_io_completion_routine)) {
|
||||||
state = readstate::Content;
|
state = readstate::Content;
|
||||||
waitable = read_content_ov;
|
waitable = read_content_ov;
|
||||||
} else {
|
} else {
|
||||||
state = readstate::Unknown;
|
state = readstate::Unknown;
|
||||||
waitable.reset();
|
waitable.reset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
read_content_ov->on_wait_error.add([&state, &waitable](datapath::error ec) {
|
read_content_ov->_on_wait_error.add([&state, &waitable](datapath::error ec) {
|
||||||
// There was an error waiting on the content.
|
// There was an error waiting on the content.
|
||||||
state = readstate::Unknown;
|
state = readstate::Unknown;
|
||||||
waitable.reset();
|
waitable.reset();
|
||||||
});
|
});
|
||||||
read_content_ov->on_wait_success.add([this, &read_buffer, &state, &waitable](datapath::error ec) {
|
read_content_ov->_on_wait_success.add([this, &read_buffer, &state, &waitable](datapath::error ec) {
|
||||||
// We have content!
|
// We have content!
|
||||||
if (this->on_message) {
|
if (this->_on_message) {
|
||||||
this->on_message(read_buffer);
|
this->_on_message(read_buffer);
|
||||||
state = readstate::Unknown;
|
state = readstate::Unknown;
|
||||||
} else {
|
} else {
|
||||||
// We're buffering the message in read_buffer until there is a hook to on_message.
|
// We're buffering the message in read_buffer until there is a hook to on_message.
|
||||||
@@ -127,8 +124,7 @@ void datapath::windows::socket::_watcher()
|
|||||||
|
|
||||||
// Read content.
|
// Read content.
|
||||||
if (ReadFileEx(this->socket_handle, read_buffer.data(), DWORD(read_buffer.size()),
|
if (ReadFileEx(this->socket_handle, read_buffer.data(), DWORD(read_buffer.size()),
|
||||||
read_header_ov->get_overlapped(),
|
read_header_ov->get_overlapped(), &datapath::windows::utility::def_io_completion_routine)) {
|
||||||
&datapath::windows::utility::def_io_completion_routine)) {
|
|
||||||
state = readstate::Header;
|
state = readstate::Header;
|
||||||
waitable = read_header_ov;
|
waitable = read_header_ov;
|
||||||
|
|
||||||
@@ -142,8 +138,8 @@ void datapath::windows::socket::_watcher()
|
|||||||
// This logic is in the on_wait_success handler, and continued here.
|
// This logic is in the on_wait_success handler, and continued here.
|
||||||
if (!waitable) {
|
if (!waitable) {
|
||||||
// We currently have a message buffered, but there was no handler last time we checked.
|
// We currently have a message buffered, but there was no handler last time we checked.
|
||||||
if (this->on_message) {
|
if (this->_on_message) {
|
||||||
this->on_message(read_buffer);
|
this->_on_message(read_buffer);
|
||||||
state = readstate::Unknown;
|
state = readstate::Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +193,7 @@ datapath::error datapath::windows::socket::write(std::shared_ptr<datapath::itask
|
|||||||
obj->_assign(data, ov);
|
obj->_assign(data, ov);
|
||||||
|
|
||||||
BOOL suc = WriteFileEx(socket_handle, obj->data().data(), DWORD(obj->data().size()), ov->get_overlapped(),
|
BOOL suc = WriteFileEx(socket_handle, obj->data().data(), DWORD(obj->data().size()), ov->get_overlapped(),
|
||||||
&datapath::windows::utility::def_io_completion_routine);
|
&datapath::windows::utility::def_io_completion_routine);
|
||||||
if (suc) {
|
if (suc) {
|
||||||
return datapath::error::Success;
|
return datapath::error::Success;
|
||||||
} else {
|
} else {
|
||||||
@@ -214,7 +210,7 @@ datapath::error datapath::windows::socket::connect(std::shared_ptr<datapath::iso
|
|||||||
|
|
||||||
SetLastError(ERROR_SUCCESS);
|
SetLastError(ERROR_SUCCESS);
|
||||||
HANDLE handle = CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
HANDLE handle = CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||||
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);
|
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);
|
||||||
if ((handle == INVALID_HANDLE_VALUE) || (GetLastError() != ERROR_SUCCESS)) {
|
if ((handle == INVALID_HANDLE_VALUE) || (GetLastError() != ERROR_SUCCESS)) {
|
||||||
return datapath::error::Failure;
|
return datapath::error::Failure;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace datapath {
|
|||||||
virtual datapath::error close() override;
|
virtual datapath::error close() override;
|
||||||
|
|
||||||
virtual datapath::error write(std::shared_ptr<datapath::itask>& task,
|
virtual datapath::error write(std::shared_ptr<datapath::itask>& task,
|
||||||
const std::vector<char>& data) override;
|
const std::vector<char>& data) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static datapath::error connect(std::shared_ptr<datapath::isocket>& socket, std::string path);
|
static datapath::error connect(std::shared_ptr<datapath::isocket>& socket, std::string path);
|
||||||
|
|||||||
@@ -20,17 +20,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#define SIZE_ELEMENT uint32_t
|
#define SIZE_ELEMENT uint32_t
|
||||||
|
|
||||||
void datapath::windows::task::_assign(const std::vector<char>& data, std::shared_ptr<datapath::windows::overlapped> ov){
|
void datapath::windows::task::_assign(const std::vector<char>& data, std::shared_ptr<datapath::windows::overlapped> ov)
|
||||||
|
{
|
||||||
this->buffer.resize(data.size() + sizeof(SIZE_ELEMENT));
|
this->buffer.resize(data.size() + sizeof(SIZE_ELEMENT));
|
||||||
std::memcpy(buffer.data() + sizeof(SIZE_ELEMENT), data.data(), data.size());
|
std::memcpy(buffer.data() + sizeof(SIZE_ELEMENT), data.data(), data.size());
|
||||||
reinterpret_cast<SIZE_ELEMENT&>(buffer[0]) = SIZE_ELEMENT(data.size());
|
reinterpret_cast<SIZE_ELEMENT&>(buffer[0]) = SIZE_ELEMENT(data.size());
|
||||||
this->overlapped = ov;
|
this->overlapped = ov;
|
||||||
}
|
}
|
||||||
|
|
||||||
datapath::windows::task::task()
|
datapath::windows::task::task()
|
||||||
{
|
{
|
||||||
this->on_wait_error.add([this](datapath::error ec) { this->on_failure(ec); });
|
this->_on_wait_error.add([this](datapath::error ec) { this->_on_failure(ec); });
|
||||||
this->on_wait_success.add([this](datapath::error ec) { this->on_success(ec, this->data()); });
|
this->_on_wait_success.add([this](datapath::error ec) { this->_on_success(ec, this->data()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
datapath::windows::task::~task()
|
datapath::windows::task::~task()
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include "itask.hpp"
|
#include "itask.hpp"
|
||||||
#include "overlapped.hpp"
|
#include "overlapped.hpp"
|
||||||
#include "socket.hpp"
|
|
||||||
#include "server.hpp"
|
#include "server.hpp"
|
||||||
|
#include "socket.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|||||||
@@ -50,13 +50,12 @@ namespace datapath {
|
|||||||
return converter.from_bytes(string);
|
return converter.from_bytes(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID CALLBACK def_io_completion_routine(_In_ DWORD dwErrorCode,
|
static VOID CALLBACK def_io_completion_routine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered,
|
||||||
_In_ DWORD dwNumberOfBytesTransfered,
|
_Inout_ LPOVERLAPPED lpOverlapped)
|
||||||
_Inout_ LPOVERLAPPED lpOverlapped)
|
|
||||||
{
|
{
|
||||||
SetEvent(lpOverlapped->hEvent);
|
SetEvent(lpOverlapped->hEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace utility
|
} // namespace utility
|
||||||
} // namespace windows
|
} // namespace windows
|
||||||
} // namespace datapath
|
} // namespace datapath
|
||||||
|
|||||||
+10
-10
@@ -42,16 +42,16 @@ datapath::error datapath::waitable::wait(datapath::waitable* obj, std::chrono::n
|
|||||||
DWORD result = WaitForSingleObjectEx(handle, DWORD(timeout), TRUE);
|
DWORD result = WaitForSingleObjectEx(handle, DWORD(timeout), TRUE);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
obj->on_wait_success(datapath::error::Success);
|
obj->_on_wait_success(datapath::error::Success);
|
||||||
return datapath::error::Success;
|
return datapath::error::Success;
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
return datapath::error::TimedOut;
|
return datapath::error::TimedOut;
|
||||||
case WAIT_ABANDONED:
|
case WAIT_ABANDONED:
|
||||||
obj->on_wait_error(datapath::error::Closed);
|
obj->_on_wait_error(datapath::error::Closed);
|
||||||
return datapath::error::Closed;
|
return datapath::error::Closed;
|
||||||
case WAIT_IO_COMPLETION:
|
case WAIT_IO_COMPLETION:
|
||||||
duration = (std::chrono::high_resolution_clock::now() - start);
|
duration = (std::chrono::high_resolution_clock::now() - start);
|
||||||
timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
}
|
}
|
||||||
@@ -96,19 +96,19 @@ datapath::error datapath::waitable::wait(datapath::waitable** objs, size_t count
|
|||||||
DWORD result = WaitForMultipleObjectsEx(handles.size(), handles.data(), TRUE, DWORD(timeout), TRUE);
|
DWORD result = WaitForMultipleObjectsEx(handles.size(), handles.data(), TRUE, DWORD(timeout), TRUE);
|
||||||
if ((result >= WAIT_OBJECT_0) && (result < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS))) {
|
if ((result >= WAIT_OBJECT_0) && (result < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS))) {
|
||||||
for (auto idx : indexes) {
|
for (auto idx : indexes) {
|
||||||
objs[idx]->on_wait_success(datapath::error::Success);
|
objs[idx]->_on_wait_success(datapath::error::Success);
|
||||||
}
|
}
|
||||||
return datapath::error::Success;
|
return datapath::error::Success;
|
||||||
} else if ((result >= WAIT_ABANDONED_0) && (result < (WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS))) {
|
} else if ((result >= WAIT_ABANDONED_0) && (result < (WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS))) {
|
||||||
for (auto idx : indexes) {
|
for (auto idx : indexes) {
|
||||||
objs[idx]->on_wait_error(datapath::error::Closed);
|
objs[idx]->_on_wait_error(datapath::error::Closed);
|
||||||
}
|
}
|
||||||
return datapath::error::Closed;
|
return datapath::error::Closed;
|
||||||
} else if (result == WAIT_TIMEOUT) {
|
} else if (result == WAIT_TIMEOUT) {
|
||||||
return datapath::error::TimedOut;
|
return datapath::error::TimedOut;
|
||||||
} else if (result == WAIT_IO_COMPLETION) {
|
} else if (result == WAIT_IO_COMPLETION) {
|
||||||
duration = (std::chrono::high_resolution_clock::now() - start);
|
duration = (std::chrono::high_resolution_clock::now() - start);
|
||||||
timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ datapath::error datapath::waitable::wait(datapath::waitable** objs, size_t count
|
|||||||
}
|
}
|
||||||
|
|
||||||
datapath::error datapath::waitable::wait_any(datapath::waitable** objs, size_t count, size_t& index,
|
datapath::error datapath::waitable::wait_any(datapath::waitable** objs, size_t count, size_t& index,
|
||||||
std::chrono::nanoseconds duration)
|
std::chrono::nanoseconds duration)
|
||||||
{
|
{
|
||||||
assert(objs != nullptr);
|
assert(objs != nullptr);
|
||||||
assert((count > 0) && (count <= MAXIMUM_WAIT_OBJECTS));
|
assert((count > 0) && (count <= MAXIMUM_WAIT_OBJECTS));
|
||||||
@@ -154,17 +154,17 @@ datapath::error datapath::waitable::wait_any(datapath::waitable** objs, size_t c
|
|||||||
DWORD result = WaitForMultipleObjectsEx(handles.size(), handles.data(), FALSE, DWORD(timeout), TRUE);
|
DWORD result = WaitForMultipleObjectsEx(handles.size(), handles.data(), FALSE, DWORD(timeout), TRUE);
|
||||||
if ((result >= WAIT_OBJECT_0) && (result < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS))) {
|
if ((result >= WAIT_OBJECT_0) && (result < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS))) {
|
||||||
index = indexes[result - WAIT_OBJECT_0];
|
index = indexes[result - WAIT_OBJECT_0];
|
||||||
objs[index]->on_wait_success(datapath::error::Success);
|
objs[index]->_on_wait_success(datapath::error::Success);
|
||||||
return datapath::error::Success;
|
return datapath::error::Success;
|
||||||
} else if ((result >= WAIT_ABANDONED_0) && (result < (WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS))) {
|
} else if ((result >= WAIT_ABANDONED_0) && (result < (WAIT_ABANDONED_0 + MAXIMUM_WAIT_OBJECTS))) {
|
||||||
index = indexes[result - WAIT_OBJECT_0];
|
index = indexes[result - WAIT_OBJECT_0];
|
||||||
objs[index]->on_wait_error(datapath::error::Closed);
|
objs[index]->_on_wait_error(datapath::error::Closed);
|
||||||
return datapath::error::Closed;
|
return datapath::error::Closed;
|
||||||
} else if (result == WAIT_TIMEOUT) {
|
} else if (result == WAIT_TIMEOUT) {
|
||||||
return datapath::error::TimedOut;
|
return datapath::error::TimedOut;
|
||||||
} else if (result == WAIT_IO_COMPLETION) {
|
} else if (result == WAIT_IO_COMPLETION) {
|
||||||
duration = (std::chrono::high_resolution_clock::now() - start);
|
duration = (std::chrono::high_resolution_clock::now() - start);
|
||||||
timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user