rcpp_framework/libs/brynet/net/detail/ConnectorDetail.hpp

129 lines
2.7 KiB
C++
Raw Normal View History

2020-11-24 15:41:18 +01:00
#pragma once
#include <brynet/base/CPP_VERSION.hpp>
2021-04-30 16:10:14 +02:00
#include <brynet/base/NonCopyable.hpp>
2020-11-24 15:41:18 +01:00
#include <brynet/net/EventLoop.hpp>
2021-04-30 16:10:14 +02:00
#include <brynet/net/Exception.hpp>
2020-11-24 15:41:18 +01:00
#include <brynet/net/detail/ConnectorWorkInfo.hpp>
2021-04-30 16:10:14 +02:00
#include <functional>
#include <memory>
#include <thread>
2020-11-24 15:41:18 +01:00
#ifdef BRYNET_HAVE_LANG_CXX17
#include <shared_mutex>
#else
#include <mutex>
#endif
2021-05-14 17:49:39 +02:00
class AsyncConnectorDetail : public NonCopyable {
2021-04-30 16:10:14 +02:00
protected:
2021-05-14 17:16:45 +02:00
void startWorkerThread() {
2020-11-24 15:41:18 +01:00
#ifdef BRYNET_HAVE_LANG_CXX17
2021-05-14 17:16:45 +02:00
std::lock_guard<std::shared_mutex> lck(mThreadGuard);
2020-11-24 15:41:18 +01:00
#else
2021-05-14 17:16:45 +02:00
std::lock_guard<std::mutex> lck(mThreadGuard);
2020-11-24 15:41:18 +01:00
#endif
2021-05-14 17:16:45 +02:00
if (mThread != nullptr) {
return;
}
2020-11-24 15:41:18 +01:00
2021-05-14 17:16:45 +02:00
mIsRun = std::make_shared<bool>(true);
2021-05-14 17:49:39 +02:00
mWorkInfo = std::make_shared<ConnectorWorkInfo>();
2021-05-14 17:16:45 +02:00
mEventLoop = std::make_shared<EventLoop>();
2020-11-24 15:41:18 +01:00
2021-05-14 17:16:45 +02:00
auto eventLoop = mEventLoop;
auto workerInfo = mWorkInfo;
auto isRun = mIsRun;
2020-11-24 15:41:18 +01:00
2021-05-14 17:16:45 +02:00
mThread = std::make_shared<std::thread>([eventLoop, workerInfo, isRun]() {
while (*isRun) {
2021-05-14 17:49:39 +02:00
RunOnceCheckConnect(eventLoop, workerInfo);
2021-05-14 17:16:45 +02:00
}
2020-11-24 15:41:18 +01:00
2021-05-14 17:16:45 +02:00
workerInfo->causeAllFailed();
});
}
2020-11-24 15:41:18 +01:00
2021-05-14 17:16:45 +02:00
void stopWorkerThread() {
2020-11-24 15:41:18 +01:00
#ifdef BRYNET_HAVE_LANG_CXX17
2021-05-14 17:16:45 +02:00
std::lock_guard<std::shared_mutex> lck(mThreadGuard);
2020-11-24 15:41:18 +01:00
#else
2021-05-14 17:16:45 +02:00
std::lock_guard<std::mutex> lck(mThreadGuard);
2020-11-24 15:41:18 +01:00
#endif
2021-05-14 17:16:45 +02:00
if (mThread == nullptr) {
return;
}
mEventLoop->runAsyncFunctor([this]() {
*mIsRun = false;
});
try {
if (mThread->joinable()) {
mThread->join();
}
} catch (std::system_error &e) {
(void)e;
}
mEventLoop = nullptr;
mWorkInfo = nullptr;
mIsRun = nullptr;
mThread = nullptr;
}
2021-05-14 17:49:39 +02:00
void asyncConnect(ConnectOption option) {
2020-11-24 15:41:18 +01:00
#ifdef BRYNET_HAVE_LANG_CXX17
2021-05-14 17:16:45 +02:00
std::shared_lock<std::shared_mutex> lck(mThreadGuard);
2020-11-24 15:41:18 +01:00
#else
2021-05-14 17:16:45 +02:00
std::lock_guard<std::mutex> lck(mThreadGuard);
2020-11-24 15:41:18 +01:00
#endif
2021-05-14 17:16:45 +02:00
if (option.completedCallback == nullptr && option.failedCallback == nullptr) {
throw ConnectException("all callback is nullptr");
}
if (option.ip.empty()) {
throw ConnectException("addr is empty");
}
if (!(*mIsRun)) {
throw ConnectException("work thread already stop");
}
auto workInfo = mWorkInfo;
2021-05-14 17:49:39 +02:00
auto address = AsyncConnectAddr(std::move(option.ip),
2021-05-14 17:16:45 +02:00
option.port,
option.timeout,
std::move(option.completedCallback),
std::move(option.failedCallback),
std::move(option.processCallbacks));
mEventLoop->runAsyncFunctor([workInfo, address]() {
workInfo->processConnect(address);
});
}
2021-04-30 16:10:14 +02:00
protected:
2021-05-14 17:16:45 +02:00
AsyncConnectorDetail() {
mIsRun = std::make_shared<bool>(false);
}
2021-04-30 16:10:14 +02:00
2021-05-14 17:16:45 +02:00
virtual ~AsyncConnectorDetail() {
stopWorkerThread();
}
2021-04-30 16:10:14 +02:00
private:
2021-05-14 17:16:45 +02:00
std::shared_ptr<EventLoop> mEventLoop;
2020-11-24 15:41:18 +01:00
2021-05-14 17:49:39 +02:00
std::shared_ptr<ConnectorWorkInfo> mWorkInfo;
2021-05-14 17:16:45 +02:00
std::shared_ptr<std::thread> mThread;
2020-11-24 15:41:18 +01:00
#ifdef BRYNET_HAVE_LANG_CXX17
2021-05-14 17:16:45 +02:00
std::shared_mutex mThreadGuard;
2020-11-24 15:41:18 +01:00
#else
2021-05-14 17:16:45 +02:00
std::mutex mThreadGuard;
2020-11-24 15:41:18 +01:00
#endif
2021-05-14 17:16:45 +02:00
std::shared_ptr<bool> mIsRun;
2021-04-30 16:10:14 +02:00
};
2020-11-24 15:41:18 +01:00