Compare commits
No commits in common. "8ee44dceee06f3ab3d41c153c0cb4aed152c24ab" and "ec3af259301e5f7a289ab5d444a2e8bc075b4aa5" have entirely different histories.
8ee44dceee
...
ec3af25930
@ -2,10 +2,9 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
|
|
||||||
set(CMAKE_BUILD_TYPE DEBUG)
|
set(CMAKE_BUILD_TYPE DEBUG)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread -fsigned-char")
|
set(CMAKE_CXX_FLAGS "-std=c++11")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-pthread")
|
|
||||||
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
|
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
|
||||||
|
|||||||
@ -16,18 +16,14 @@ private:
|
|||||||
std::queue<std::function<void()>> _queue;
|
std::queue<std::function<void()>> _queue;
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
std::condition_variable _cv;
|
std::condition_variable _cv;
|
||||||
std::condition_variable _wait_cv;
|
|
||||||
std::vector<std::thread> _workers;
|
std::vector<std::thread> _workers;
|
||||||
bool _enabled;
|
bool _enabled;
|
||||||
std::atomic<std::size_t> _tasksCount;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
threadpool();
|
threadpool();
|
||||||
threadpool(std::size_t concurrency);
|
threadpool(std::size_t concurrency);
|
||||||
~threadpool();
|
~threadpool();
|
||||||
|
|
||||||
void wait_all();
|
|
||||||
|
|
||||||
template <typename R> std::future<R> add_task(std::function<R()> func)
|
template <typename R> std::future<R> add_task(std::function<R()> func)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
@ -35,7 +31,6 @@ public:
|
|||||||
std::future<R> fut = pt_ptr->get_future();
|
std::future<R> fut = pt_ptr->get_future();
|
||||||
|
|
||||||
_queue.push([pt_ptr] { (*pt_ptr)(); });
|
_queue.push([pt_ptr] { (*pt_ptr)(); });
|
||||||
_tasksCount++;
|
|
||||||
_cv.notify_one();
|
_cv.notify_one();
|
||||||
return fut;
|
return fut;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,24 +3,9 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
set(MAIN_PROJECT_NAME "cpputil")
|
set(MAIN_PROJECT_NAME "cpputil")
|
||||||
set(SRC_DIR ".")
|
set(SRC_DIR ".")
|
||||||
set(INCLUDE_DIR ../include ./asm/include)
|
set(INCLUDE_DIR ../include ./asm/include)
|
||||||
set(ARCH "x86_64")
|
|
||||||
|
|
||||||
if(APPLE)
|
project(${MAIN_PROJECT_NAME} CXX)
|
||||||
set(SYSTEM "darwin")
|
|
||||||
else()
|
|
||||||
set(SYSTEM "linux")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
SET(CMAKE_ASM_NASM_COMPILER yasm)
|
|
||||||
|
|
||||||
project(${MAIN_PROJECT_NAME} CXX ASM_NASM)
|
|
||||||
aux_source_directory(${SRC_DIR} SRC_FILES)
|
aux_source_directory(${SRC_DIR} SRC_FILES)
|
||||||
|
|
||||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
|
||||||
file(GLOB_RECURSE ASM_SRC_FILES "${SRC_DIR}/asm/${SYSTEM}/${ARCH}" "*.asm")
|
|
||||||
set(SRC_FILES ${SRC_FILES} ${ASM_SRC_FILES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories(${INCLUDE_DIR})
|
include_directories(${INCLUDE_DIR})
|
||||||
add_library(${MAIN_PROJECT_NAME} STATIC ${SRC_FILES})
|
add_library(${MAIN_PROJECT_NAME} STATIC ${SRC_FILES})
|
||||||
target_link_libraries(${MAIN_PROJECT_NAME})
|
target_link_libraries(${MAIN_PROJECT_NAME})
|
||||||
|
|||||||
@ -1,101 +0,0 @@
|
|||||||
;
|
|
||||||
; public exported functions
|
|
||||||
;
|
|
||||||
|
|
||||||
global __asm_ucs4_strstr
|
|
||||||
global __asm_ucs4_strchr
|
|
||||||
|
|
||||||
;
|
|
||||||
; code section
|
|
||||||
;
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
; constants
|
|
||||||
|
|
||||||
npos db -1
|
|
||||||
|
|
||||||
;================================================================================
|
|
||||||
;
|
|
||||||
; Поиск подстроки в строке UCS-4 (алгоритм "в лоб", подойдет для коротких строк)
|
|
||||||
;
|
|
||||||
; rdi: указатель на исходную строку
|
|
||||||
; rsi: длина исходной строки символах
|
|
||||||
; rdx: указатель на искомую подстроку
|
|
||||||
; rcx: длина подстроки в символах
|
|
||||||
;
|
|
||||||
;================================================================================
|
|
||||||
|
|
||||||
__asm_ucs4_strstr:
|
|
||||||
|
|
||||||
push r12
|
|
||||||
mov r9d, dword [rdx]
|
|
||||||
mov rax, rdx
|
|
||||||
lea r8, [rdi + rsi*4]
|
|
||||||
lea r10, [rdx + rcx*4]
|
|
||||||
|
|
||||||
strstr_try_next_symbol:
|
|
||||||
|
|
||||||
cmp r9d, dword [rdi]
|
|
||||||
je strstr_init_counter
|
|
||||||
add rdi, 4
|
|
||||||
cmp rdi, r8
|
|
||||||
jne strstr_try_next_symbol
|
|
||||||
pop r12
|
|
||||||
mov rax, 0
|
|
||||||
ret
|
|
||||||
|
|
||||||
strstr_init_counter:
|
|
||||||
|
|
||||||
mov rdx, rax
|
|
||||||
mov r12, rdi
|
|
||||||
|
|
||||||
strstr_symbol_found:
|
|
||||||
|
|
||||||
add rdx, 4
|
|
||||||
cmp rdx, r10
|
|
||||||
je strstr_the_end
|
|
||||||
add r12, 4
|
|
||||||
mov r11d, dword [r12]
|
|
||||||
cmp r11d, dword [rdx]
|
|
||||||
je strstr_symbol_found
|
|
||||||
add rdi, 4
|
|
||||||
jmp strstr_try_next_symbol
|
|
||||||
|
|
||||||
strstr_the_end:
|
|
||||||
|
|
||||||
pop r12
|
|
||||||
mov rax, rdi
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
;================================================================================
|
|
||||||
;
|
|
||||||
; Поиск символа в строке UCS-4
|
|
||||||
;
|
|
||||||
; rdi: указатель на исходную строку
|
|
||||||
; rsi: длина исходной строки символах
|
|
||||||
; rdx: искомый символ
|
|
||||||
;
|
|
||||||
;================================================================================
|
|
||||||
|
|
||||||
__asm_ucs4_strchr:
|
|
||||||
|
|
||||||
xor r8, r8
|
|
||||||
|
|
||||||
try_next_symbol:
|
|
||||||
|
|
||||||
cmp rdx, [rdi]
|
|
||||||
je symbol_found
|
|
||||||
add rdi, 4
|
|
||||||
inc r8
|
|
||||||
cmp rsi, r8
|
|
||||||
jne try_next_symbol
|
|
||||||
mov rax, 0
|
|
||||||
ret
|
|
||||||
|
|
||||||
symbol_found:
|
|
||||||
|
|
||||||
mov rax, rdi
|
|
||||||
|
|
||||||
ret
|
|
||||||
@ -1,19 +1,21 @@
|
|||||||
|
format ELF64
|
||||||
|
|
||||||
;
|
;
|
||||||
; public exported functions
|
; public exported functions
|
||||||
;
|
;
|
||||||
|
|
||||||
global _asm_ucs4_strstr
|
public _asm_ucs4_strstr
|
||||||
global _asm_ucs4_strchr
|
public _asm_ucs4_strchr
|
||||||
|
|
||||||
;
|
;
|
||||||
; code section
|
; code section
|
||||||
;
|
;
|
||||||
|
|
||||||
section '.text'
|
section '.text' executable
|
||||||
|
|
||||||
; constants
|
; constants
|
||||||
|
|
||||||
npos db -1
|
npos = -1
|
||||||
|
|
||||||
;================================================================================
|
;================================================================================
|
||||||
;
|
;
|
||||||
@ -1,11 +1,10 @@
|
|||||||
#include <iostream>
|
|
||||||
#include "threadpool.h"
|
#include "threadpool.h"
|
||||||
|
|
||||||
threadpool::threadpool() : threadpool(std::thread::hardware_concurrency())
|
threadpool::threadpool() : threadpool(std::thread::hardware_concurrency())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
threadpool::threadpool(std::size_t concurrency) : _concurrency(concurrency), _enabled(true), _tasksCount(0)
|
threadpool::threadpool(std::size_t concurrency) : _concurrency(concurrency), _enabled(true)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < _concurrency; ++i)
|
for (std::size_t i = 0; i < _concurrency; ++i)
|
||||||
{
|
{
|
||||||
@ -39,13 +38,5 @@ void threadpool::worker_func()
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
func();
|
func();
|
||||||
_tasksCount--;
|
|
||||||
_wait_cv.notify_one();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void threadpool::wait_all()
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_mutex);
|
|
||||||
_wait_cv.wait(lock, [this] { return _tasksCount == 0; });
|
|
||||||
}
|
|
||||||
|
|||||||
@ -381,19 +381,19 @@ std::size_t ustring::find(const ustring& str, std::size_t pos /* = 0 */) const
|
|||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__) // GCC and clang
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
|
/*
|
||||||
char32_t* fpos = reinterpret_cast<char32_t*>(memmem(_pData + pos, (_len - pos)*sizeof(char32_t), str._pData, str._len*sizeof(char32_t)));
|
char32_t* fpos = reinterpret_cast<char32_t*>(memmem(_pData + pos, (_len - pos)*sizeof(char32_t), str._pData, str._len*sizeof(char32_t)));
|
||||||
if(fpos)
|
if(fpos)
|
||||||
{
|
{
|
||||||
return (fpos - _pData);
|
return (fpos - _pData);
|
||||||
}
|
}
|
||||||
/*
|
*/
|
||||||
const char32_t* fpos = _asm_ucs4_strstr(_pData + pos, (_len - pos), str._pData, str._len);
|
const char32_t* fpos = _asm_ucs4_strstr(_pData + pos, (_len - pos), str._pData, str._len);
|
||||||
if(fpos)
|
if(fpos)
|
||||||
{
|
{
|
||||||
return (fpos - _pData);
|
return (fpos - _pData);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
#else
|
#else
|
||||||
const char32_t* pStr = str._pData;
|
const char32_t* pStr = str._pData;
|
||||||
const std::size_t len = _len - str.length();
|
const std::size_t len = _len - str.length();
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
#include "utf.h"
|
#include "utf.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__clang__)
|
||||||
#define bswap_16 __builtin_bswap16
|
#include <libkern/OSByteOrder.h>
|
||||||
#define bswap_32 __builtin_bswap32
|
#define bswap_32 OSSwapInt32
|
||||||
|
#define bswap_16 OSSwapInt16
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#include <byteswap.h>
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#define bswap_16 _byteswap_ushort
|
#define bswap_16 _byteswap_ushort
|
||||||
#define bswap_32 _byteswap_ulong
|
#define bswap_32 _byteswap_ulong
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
set(TEST_PROJECT_NAME "cpputil_test")
|
set(TEST_PROJECT_NAME "cpputil_test")
|
||||||
set(TEST_SERVER_PROJECT_NAME "server_test")
|
|
||||||
set(TEST_CLIENT_PROJECT_NAME "client_test")
|
|
||||||
set(SRC_DIR ".")
|
set(SRC_DIR ".")
|
||||||
set(REQUIRED_LIBRARIES cpputil)
|
set(REQUIRED_LIBRARIES cpputil)
|
||||||
set(boost_version 1.56.0)
|
set(boost_version 1.56.0)
|
||||||
@ -17,7 +15,7 @@ ExternalProject_Add(
|
|||||||
TIMEOUT 100
|
TIMEOUT 100
|
||||||
CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${CMAKE_SOURCE_DIR}/lib
|
CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${CMAKE_SOURCE_DIR}/lib
|
||||||
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${CMAKE_SOURCE_DIR}/lib
|
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${CMAKE_SOURCE_DIR}/lib
|
||||||
#-Dgtest_force_shared_crt=ON
|
-Dgtest_force_shared_crt=ON
|
||||||
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
||||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
@ -38,7 +36,7 @@ endif()
|
|||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
boost
|
boost
|
||||||
URL http://switch.dl.sourceforge.net/project/boost/boost/${boost_version}/boost_${boost_version_underscored}.zip
|
URL http://switch.dl.sourceforge.net/project/boost/boost/${boost_version}/boost_${boost_version_underscored}.zip
|
||||||
CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=coroutine,thread
|
CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=coroutine
|
||||||
BUILD_COMMAND ./b2 --ignore-site-config --stagedir=${CMAKE_SOURCE_DIR} link=static threading=multi cxxflags=-std=c++11 ${boost_build_type}
|
BUILD_COMMAND ./b2 --ignore-site-config --stagedir=${CMAKE_SOURCE_DIR} link=static threading=multi cxxflags=-std=c++11 ${boost_build_type}
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
@ -48,21 +46,17 @@ ExternalProject_Add(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ExternalProject_Get_Property( boost source_dir )
|
ExternalProject_Get_Property( boost source_dir )
|
||||||
set(BOOST_INCLUDE_DIR ${source_dir})
|
ExternalProject_Get_Property( boost binary_dir )
|
||||||
INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
|
set( Boost_INCLUDE_DIRS ${source_dir} )
|
||||||
|
set( Boost_LIBRARIES debug;${binary_dir}/stage/lib/libboost_program_options-vc110-mt-gd-1_49.lib;optimized;${binary_dir}/stage/lib/libboost_program_options-vc110-mt-1_49.lib )
|
||||||
|
|
||||||
project(${TEST_PROJECT_NAME} CXX)
|
project(${TEST_PROJECT_NAME} CXX)
|
||||||
aux_source_directory(${SRC_DIR}/cpputil TEST_SRC)
|
aux_source_directory(${SRC_DIR} TEST_SRC)
|
||||||
add_executable(${TEST_PROJECT_NAME} ${TEST_SRC})
|
add_executable(${TEST_PROJECT_NAME} ${TEST_SRC})
|
||||||
SET_TARGET_PROPERTIES(${TEST_PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
|
SET_TARGET_PROPERTIES(${TEST_PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
|
||||||
ADD_DEPENDENCIES(${TEST_PROJECT_NAME} googletest cpputil)
|
ADD_DEPENDENCIES(${TEST_PROJECT_NAME} googletest cpputil boost)
|
||||||
target_link_libraries(${TEST_PROJECT_NAME} ${REQUIRED_LIBRARIES} ${CMAKE_SOURCE_DIR}/lib/libgtest.a)
|
|
||||||
|
|
||||||
project(${TEST_SERVER_PROJECT_NAME} CXX)
|
target_link_libraries(${TEST_PROJECT_NAME} ${REQUIRED_LIBRARIES} ${CMAKE_SOURCE_DIR}/lib/libgtest.a ${CMAKE_SOURCE_DIR}/lib/libboost_coroutine.a)
|
||||||
aux_source_directory(${SRC_DIR}/server TEST_SERVER_SRC)
|
|
||||||
add_executable(${TEST_SERVER_PROJECT_NAME} ${TEST_SERVER_SRC})
|
|
||||||
add_dependencies(${TEST_SERVER_PROJECT_NAME} boost cpputil)
|
|
||||||
target_link_libraries(${TEST_SERVER_PROJECT_NAME} cpputil ${CMAKE_SOURCE_DIR}/lib/libboost_system.a ${CMAKE_SOURCE_DIR}/lib/libboost_coroutine.a ${CMAKE_SOURCE_DIR}/lib/libboost_context.a ${CMAKE_SOURCE_DIR}/lib/libboost_thread.a)
|
|
||||||
|
|
||||||
install(TARGETS ${TEST_PROJECT_NAME}
|
install(TARGETS ${TEST_PROJECT_NAME}
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
#include "session.h"
|
|
||||||
#include "server.h"
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
server srv("0.0.0.0", "12345");
|
|
||||||
|
|
||||||
std::thread t([&]{
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
|
||||||
srv.stop();
|
|
||||||
});
|
|
||||||
t.detach();
|
|
||||||
|
|
||||||
srv.run();
|
|
||||||
std::cout << "after run" << std::endl;
|
|
||||||
|
|
||||||
/*
|
|
||||||
threadpool pool;
|
|
||||||
|
|
||||||
pool.add_task<void>([]{
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
|
||||||
std::cout << "first task completed" << std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
pool.add_task<void>([]{
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
|
||||||
std::cout << "second task completed" << std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
pool.wait_all();
|
|
||||||
std::cout << "all tasks completed" << std::endl;
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
#include "server.h"
|
|
||||||
#include <boost/asio/spawn.hpp>
|
|
||||||
|
|
||||||
server::server(std::string address, std::string port)
|
|
||||||
{
|
|
||||||
tcp::resolver resolver(_io_service);
|
|
||||||
tcp::resolver::query query(address, port);
|
|
||||||
_acceptor = new tcp::acceptor(_io_service, *resolver.resolve(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
void server::run()
|
|
||||||
{
|
|
||||||
boost::asio::spawn(_io_service, [&](boost::asio::yield_context yield) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
session *s = new session(_io_service, &_pool);
|
|
||||||
_acceptor->async_accept(s->socket(), yield);
|
|
||||||
_sessions.insert(s);
|
|
||||||
s->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (boost::system::system_error& ex)
|
|
||||||
{
|
|
||||||
std::cout << "server exception: " << ex.what() << std::endl;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_io_service.run();
|
|
||||||
std::cout << "after ioservice run" << std::endl;
|
|
||||||
std::for_each(_sessions.begin(), _sessions.end(), [](session* s){ delete s; });
|
|
||||||
_sessions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
server::~server()
|
|
||||||
{
|
|
||||||
std::cout << "server destructor" << std::endl;
|
|
||||||
delete _acceptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void server::stop()
|
|
||||||
{
|
|
||||||
_io_service.post([&]{
|
|
||||||
_acceptor->close();
|
|
||||||
std::for_each(_sessions.begin(), _sessions.end(), [](session* s){ s->stop(); });
|
|
||||||
_pool.wait_all();
|
|
||||||
std::cout << "stop exited" << std::endl;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#ifndef _SERVER_H_
|
|
||||||
#define _SERVER_H_
|
|
||||||
|
|
||||||
#include "threadpool.h"
|
|
||||||
#include "session.h"
|
|
||||||
#include <boost/asio.hpp>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
class server
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef boost::asio::ip::tcp tcp;
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::asio::io_service _io_service;
|
|
||||||
tcp::acceptor* _acceptor;
|
|
||||||
threadpool _pool;
|
|
||||||
std::set<session*> _sessions;
|
|
||||||
|
|
||||||
public:
|
|
||||||
server() = delete;
|
|
||||||
server(server&) = delete;
|
|
||||||
server(std::string address, std::string port);
|
|
||||||
void run();
|
|
||||||
void stop();
|
|
||||||
~server();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _SERVER_H_
|
|
||||||
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
#include "session.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <boost/asio/spawn.hpp>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
session::session(boost::asio::io_service &io_service, threadpool* pool): _socket(io_service), _pool(pool)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void session::start()
|
|
||||||
{
|
|
||||||
boost::asio::spawn(_socket.get_io_service(), [this](boost::asio::yield_context yield){
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (;;) {
|
|
||||||
std::size_t bytes = _socket.async_read_some(boost::asio::buffer(_data, 128), yield);
|
|
||||||
|
|
||||||
std::cout << "before async call" << std::endl;
|
|
||||||
int n = async_call<int>([this] {
|
|
||||||
std::cout << "async call start waiting" << std::endl;
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(15));
|
|
||||||
std::cout << "async call ends waiting" << std::endl;
|
|
||||||
int n = std::atoi(_data);
|
|
||||||
return n * n;
|
|
||||||
}, yield);
|
|
||||||
|
|
||||||
std::cout << "before write: " << n << std::endl;
|
|
||||||
_socket.async_write_some(boost::asio::buffer(std::to_string(n) + "\n"), yield);
|
|
||||||
std::cout << "after write" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (boost::system::system_error& ex)
|
|
||||||
{
|
|
||||||
std::cout << "exception: " << ex.code().value() << " - " << ex.what() << std::endl;
|
|
||||||
|
|
||||||
if(ex.code().value() == 2) // end of file
|
|
||||||
{
|
|
||||||
//FIXME: Удалять сессию должен сервер
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::asio::ip::tcp::socket& session::socket()
|
|
||||||
{
|
|
||||||
return _socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
void session::stop()
|
|
||||||
{
|
|
||||||
_socket.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
session::~session()
|
|
||||||
{
|
|
||||||
std::cout << "session destructor called" << std::endl;
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
#ifndef _SESSION_H_
|
|
||||||
#define _SESSION_H_
|
|
||||||
|
|
||||||
#include "threadpool.h"
|
|
||||||
#include <boost/asio.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
class session
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef boost::asio::ip::tcp tcp;
|
|
||||||
|
|
||||||
private:
|
|
||||||
tcp::socket _socket;
|
|
||||||
char _data[128];
|
|
||||||
threadpool* _pool;
|
|
||||||
|
|
||||||
public:
|
|
||||||
session() = delete;
|
|
||||||
session(session&) = delete;
|
|
||||||
session(boost::asio::io_service& io_service, threadpool* pool);
|
|
||||||
~session();
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
tcp::socket& socket();
|
|
||||||
|
|
||||||
template <typename R, typename CompletionToken> R async_call(std::function<R()> func, CompletionToken&& token)
|
|
||||||
{
|
|
||||||
using namespace boost::asio;
|
|
||||||
BOOST_ASIO_HANDLER_TYPE(CompletionToken, void(R)) handler(std::forward<CompletionToken>(token));
|
|
||||||
async_result<decltype(handler)> result(handler);
|
|
||||||
|
|
||||||
_pool->add_task<void>([this, handler, &func]{
|
|
||||||
_socket.get_io_service().dispatch(std::bind(handler, func()));
|
|
||||||
});
|
|
||||||
|
|
||||||
return result.get();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _SESSION_H_
|
|
||||||
Loading…
Reference in New Issue
Block a user