mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-04-20 01:43:12 +02:00
After a lot of thinking, I reverted moving trantor to core. I realized I want to change so many things in it, that I might as well just not take compromises with the license.
This commit is contained in:
parent
c679ad05f4
commit
75c5145370
@ -6,12 +6,6 @@ env.core_sources = []
|
||||
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
env.add_source_files(env.core_sources, "./math/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./net/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./net/resolvers/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./net/connections/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./loops/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./polling/poller/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./polling/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./containers/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./log/*.cpp")
|
||||
env.add_source_files(env.core_sources, "./os/*.cpp")
|
||||
|
@ -1,100 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - ConcurrentTaskQueue.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/containers/task_queue.h"
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief This class implements a task queue running in parallel. Basically this
|
||||
* can be called a threads pool.
|
||||
*
|
||||
*/
|
||||
class ConcurrentTaskQueue : public TaskQueue {
|
||||
public:
|
||||
ConcurrentTaskQueue() {}
|
||||
|
||||
/**
|
||||
* @brief Construct a new concurrent task queue instance.
|
||||
*
|
||||
* @param threadNum The number of threads in the queue.
|
||||
* @param name The name of the queue.
|
||||
*/
|
||||
ConcurrentTaskQueue(size_t threadNum, const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Run a task in the queue.
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
virtual void runTaskInQueue(const std::function<void()> &task);
|
||||
virtual void runTaskInQueue(std::function<void()> &&task);
|
||||
|
||||
/**
|
||||
* @brief Get the name of the queue.
|
||||
*
|
||||
* @return std::string
|
||||
*/
|
||||
virtual std::string getName() const {
|
||||
return queueName_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get the number of tasks to be executed in the queue.
|
||||
*
|
||||
* @return size_t
|
||||
*/
|
||||
size_t getTaskCount();
|
||||
|
||||
/**
|
||||
* @brief Stop all threads in the queue.
|
||||
*
|
||||
*/
|
||||
void stop();
|
||||
|
||||
~ConcurrentTaskQueue();
|
||||
|
||||
private:
|
||||
size_t queueCount_;
|
||||
std::string queueName_;
|
||||
|
||||
std::queue<std::function<void()> > taskQueue_;
|
||||
std::vector<std::thread> threads_;
|
||||
|
||||
std::mutex taskMutex_;
|
||||
std::condition_variable taskCond_;
|
||||
std::atomic_bool stop_;
|
||||
void queueFunc(int queueNum);
|
||||
};
|
@ -1,123 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - LockFreeQueue.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
#include <assert.h>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
/**
|
||||
* @brief This class template represents a lock-free multiple producers single
|
||||
* consumer queue
|
||||
*
|
||||
* @tparam T The type of the items in the queue.
|
||||
*/
|
||||
template <typename T>
|
||||
class MpscQueue {
|
||||
protected:
|
||||
MpscQueue(const MpscQueue &) = delete;
|
||||
MpscQueue &operator=(const MpscQueue &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
MpscQueue(MpscQueue &&) noexcept(true) = default;
|
||||
MpscQueue &operator=(MpscQueue &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
MpscQueue() :
|
||||
head_(new BufferNode), tail_(head_.load(std::memory_order_relaxed)) {
|
||||
}
|
||||
~MpscQueue() {
|
||||
T output;
|
||||
while (this->dequeue(output)) {
|
||||
}
|
||||
BufferNode *front = head_.load(std::memory_order_relaxed);
|
||||
delete front;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a item into the queue.
|
||||
*
|
||||
* @param input
|
||||
* @note This method can be called in multiple threads.
|
||||
*/
|
||||
void enqueue(T &&input) {
|
||||
BufferNode *node{ new BufferNode(std::move(input)) };
|
||||
BufferNode *prevhead{ head_.exchange(node, std::memory_order_acq_rel) };
|
||||
prevhead->next_.store(node, std::memory_order_release);
|
||||
}
|
||||
void enqueue(const T &input) {
|
||||
BufferNode *node{ new BufferNode(input) };
|
||||
BufferNode *prevhead{ head_.exchange(node, std::memory_order_acq_rel) };
|
||||
prevhead->next_.store(node, std::memory_order_release);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a item from the queue.
|
||||
*
|
||||
* @param output
|
||||
* @return false if the queue is empty.
|
||||
* @note This method must be called in a single thread.
|
||||
*/
|
||||
bool dequeue(T &output) {
|
||||
BufferNode *tail = tail_.load(std::memory_order_relaxed);
|
||||
BufferNode *next = tail->next_.load(std::memory_order_acquire);
|
||||
|
||||
if (next == nullptr) {
|
||||
return false;
|
||||
}
|
||||
output = std::move(*(next->dataPtr_));
|
||||
delete next->dataPtr_;
|
||||
tail_.store(next, std::memory_order_release);
|
||||
delete tail;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
BufferNode *tail = tail_.load(std::memory_order_relaxed);
|
||||
BufferNode *next = tail->next_.load(std::memory_order_acquire);
|
||||
return next == nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
struct BufferNode {
|
||||
BufferNode() = default;
|
||||
BufferNode(const T &data) :
|
||||
dataPtr_(new T(data)) {
|
||||
}
|
||||
BufferNode(T &&data) :
|
||||
dataPtr_(new T(std::move(data))) {
|
||||
}
|
||||
T *dataPtr_;
|
||||
std::atomic<BufferNode *> next_{ nullptr };
|
||||
};
|
||||
|
||||
std::atomic<BufferNode *> head_;
|
||||
std::atomic<BufferNode *> tail_;
|
||||
};
|
@ -1,65 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - SerialTaskQueue.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "core/log/logger.h"
|
||||
#include "serial_task_queue.h"
|
||||
#ifdef __linux__
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
|
||||
SerialTaskQueue::SerialTaskQueue(const std::string &name) :
|
||||
queueName_(name.empty() ? "SerailTaskQueue" : name),
|
||||
loopThread_(queueName_) {
|
||||
loopThread_.run();
|
||||
}
|
||||
void SerialTaskQueue::stop() {
|
||||
stop_ = true;
|
||||
loopThread_.getLoop()->quit();
|
||||
loopThread_.wait();
|
||||
}
|
||||
SerialTaskQueue::~SerialTaskQueue() {
|
||||
if (!stop_)
|
||||
stop();
|
||||
LOG_TRACE << "destruct SerialTaskQueue('" << queueName_ << "')";
|
||||
}
|
||||
void SerialTaskQueue::runTaskInQueue(const std::function<void()> &task) {
|
||||
loopThread_.getLoop()->runInLoop(task);
|
||||
}
|
||||
void SerialTaskQueue::runTaskInQueue(std::function<void()> &&task) {
|
||||
loopThread_.getLoop()->runInLoop(std::move(task));
|
||||
}
|
||||
|
||||
void SerialTaskQueue::waitAllTasksFinished() {
|
||||
syncTaskInQueue([]() {
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -1,114 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - SerialTaskQueue.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "task_queue.h"
|
||||
#include "core/loops/event_loop_thread.h"
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
|
||||
/**
|
||||
* @brief This class represents a task queue in which all tasks are executed one
|
||||
* by one.
|
||||
*
|
||||
*/
|
||||
class SerialTaskQueue : public TaskQueue
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Run a task in the queue.
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
virtual void runTaskInQueue(const std::function<void()> &task);
|
||||
virtual void runTaskInQueue(std::function<void()> &&task);
|
||||
|
||||
/**
|
||||
* @brief Get the name of the queue.
|
||||
*
|
||||
* @return std::string
|
||||
*/
|
||||
virtual std::string getName() const
|
||||
{
|
||||
return queueName_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Wait until all tasks in the queue are finished.
|
||||
*
|
||||
*/
|
||||
void waitAllTasksFinished();
|
||||
|
||||
SerialTaskQueue() = delete;
|
||||
|
||||
/**
|
||||
* @brief Construct a new serail task queue instance.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
explicit SerialTaskQueue(const std::string &name);
|
||||
|
||||
virtual ~SerialTaskQueue();
|
||||
|
||||
/**
|
||||
* @brief Check whether a task is running in the queue.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isRuningTask()
|
||||
{
|
||||
return loopThread_.getLoop()
|
||||
? loopThread_.getLoop()->isCallingFunctions()
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the number of tasks in the queue.
|
||||
*
|
||||
* @return size_t
|
||||
*/
|
||||
size_t getTaskCount();
|
||||
|
||||
/**
|
||||
* @brief Stop the queue.
|
||||
*
|
||||
*/
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
std::string queueName_;
|
||||
EventLoopThread loopThread_;
|
||||
bool stop_{false};
|
||||
};
|
@ -1,76 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - TaskQueue.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief This class is a pure virtual class that can be implemented as a
|
||||
* SerialTaskQueue or a ConcurrentTaskQueue.
|
||||
*
|
||||
*/
|
||||
class TaskQueue {
|
||||
protected:
|
||||
TaskQueue(const TaskQueue &) = delete;
|
||||
TaskQueue &operator=(const TaskQueue &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
TaskQueue(TaskQueue &&) noexcept(true) = default;
|
||||
TaskQueue &operator=(TaskQueue &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
TaskQueue() {}
|
||||
virtual void runTaskInQueue(const std::function<void()> &task) = 0;
|
||||
virtual void runTaskInQueue(std::function<void()> &&task) = 0;
|
||||
virtual std::string getName() const {
|
||||
return "";
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Run a task in the queue sychronously. This means that the task is
|
||||
* executed before the method returns.
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
void syncTaskInQueue(const std::function<void()> &task) {
|
||||
std::promise<int> prom;
|
||||
std::future<int> fut = prom.get_future();
|
||||
runTaskInQueue([&]() {
|
||||
task();
|
||||
prom.set_value(1);
|
||||
});
|
||||
fut.get();
|
||||
};
|
||||
virtual ~TaskQueue() {
|
||||
}
|
||||
};
|
||||
|
@ -1,160 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - AsyncFileLogger.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/math/date.h"
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
using StringPtr = std::shared_ptr<std::string>;
|
||||
using StringPtrQueue = std::queue<StringPtr>;
|
||||
|
||||
/**
|
||||
* @brief This class implements utility functions for writing logs to files
|
||||
* asynchronously.
|
||||
*
|
||||
*/
|
||||
class AsyncFileLogger {
|
||||
protected:
|
||||
AsyncFileLogger(const AsyncFileLogger &) = delete;
|
||||
AsyncFileLogger &operator=(const AsyncFileLogger &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
AsyncFileLogger(AsyncFileLogger &&) noexcept(true) = default;
|
||||
AsyncFileLogger &operator=(AsyncFileLogger &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Write the message to the log file.
|
||||
*
|
||||
* @param msg
|
||||
* @param len
|
||||
*/
|
||||
void output(const char *msg, const uint64_t len);
|
||||
|
||||
/**
|
||||
* @brief Flush data from memory buffer to the log file.
|
||||
*
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* @brief Start writing log files.
|
||||
*
|
||||
*/
|
||||
void startLogging();
|
||||
|
||||
/**
|
||||
* @brief Set the size limit of log files. When the log file size reaches
|
||||
* the limit, the log file is switched.
|
||||
*
|
||||
* @param limit
|
||||
*/
|
||||
void setFileSizeLimit(uint64_t limit) {
|
||||
sizeLimit_ = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the log file name.
|
||||
*
|
||||
* @param baseName The base name of the log file.
|
||||
* @param extName The extended name of the log file.
|
||||
* @param path The location where the log file is stored.
|
||||
*/
|
||||
void setFileName(const std::string &baseName,
|
||||
const std::string &extName = ".log",
|
||||
const std::string &path = "./") {
|
||||
fileBaseName_ = baseName;
|
||||
extName[0] == '.' ? fileExtName_ = extName : fileExtName_ = std::string(".") + extName;
|
||||
filePath_ = path;
|
||||
if (filePath_.length() == 0)
|
||||
filePath_ = "./";
|
||||
if (filePath_[filePath_.length() - 1] != '/')
|
||||
filePath_ = filePath_ + "/";
|
||||
}
|
||||
~AsyncFileLogger();
|
||||
AsyncFileLogger();
|
||||
|
||||
protected:
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
StringPtr logBufferPtr_;
|
||||
StringPtr nextBufferPtr_;
|
||||
StringPtrQueue writeBuffers_;
|
||||
StringPtrQueue tmpBuffers_;
|
||||
void writeLogToFile(const StringPtr buf);
|
||||
std::unique_ptr<std::thread> threadPtr_;
|
||||
bool stopFlag_{ false };
|
||||
void logThreadFunc();
|
||||
std::string filePath_{ "./" };
|
||||
std::string fileBaseName_{ "trantor" };
|
||||
std::string fileExtName_{ ".log" };
|
||||
uint64_t sizeLimit_{ 20 * 1024 * 1024 };
|
||||
|
||||
class LoggerFile {
|
||||
protected:
|
||||
LoggerFile(const LoggerFile &) = delete;
|
||||
LoggerFile &operator=(const LoggerFile &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
LoggerFile(LoggerFile &&) noexcept(true) = default;
|
||||
LoggerFile &operator=(LoggerFile &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
LoggerFile(const std::string &filePath,
|
||||
const std::string &fileBaseName,
|
||||
const std::string &fileExtName);
|
||||
~LoggerFile();
|
||||
void writeLog(const StringPtr buf);
|
||||
uint64_t getLength();
|
||||
explicit operator bool() const {
|
||||
return fp_ != nullptr;
|
||||
}
|
||||
void flush();
|
||||
|
||||
protected:
|
||||
FILE *fp_{ nullptr };
|
||||
Date creationDate_;
|
||||
std::string fileFullName_;
|
||||
std::string filePath_;
|
||||
std::string fileBaseName_;
|
||||
std::string fileExtName_;
|
||||
static uint64_t fileSeq_;
|
||||
};
|
||||
|
||||
std::unique_ptr<LoggerFile> loggerFilePtr_;
|
||||
|
||||
uint64_t lostCounter_{ 0 };
|
||||
void swapBuffer();
|
||||
};
|
@ -1,261 +0,0 @@
|
||||
|
||||
// This file is originally from Moduo -> Trantor - LogStream.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
// Copyright (c) 2010, Shuo Chen. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Taken from muduo lib and modified. Classes in this file are used internally.
|
||||
#include <assert.h>
|
||||
#include <string.h> // memcpy
|
||||
#include <string>
|
||||
|
||||
namespace detail {
|
||||
static constexpr size_t kSmallBuffer{ 4000 };
|
||||
static constexpr size_t kLargeBuffer{ 4000 * 1000 };
|
||||
|
||||
template <int SIZE>
|
||||
class FixedBuffer {
|
||||
protected:
|
||||
FixedBuffer(const FixedBuffer &) = delete;
|
||||
FixedBuffer &operator=(const FixedBuffer &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
FixedBuffer(FixedBuffer &&) noexcept(true) = default;
|
||||
FixedBuffer &operator=(FixedBuffer &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
FixedBuffer() :
|
||||
cur_(data_) {
|
||||
setCookie(cookieStart);
|
||||
}
|
||||
|
||||
~FixedBuffer() {
|
||||
setCookie(cookieEnd);
|
||||
}
|
||||
|
||||
bool append(const char * /*restrict*/ buf, size_t len) {
|
||||
if ((size_t)(avail()) > len) {
|
||||
memcpy(cur_, buf, len);
|
||||
cur_ += len;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *data() const {
|
||||
return data_;
|
||||
}
|
||||
int length() const {
|
||||
return static_cast<int>(cur_ - data_);
|
||||
}
|
||||
|
||||
// write to data_ directly
|
||||
char *current() {
|
||||
return cur_;
|
||||
}
|
||||
int avail() const {
|
||||
return static_cast<int>(end() - cur_);
|
||||
}
|
||||
void add(size_t len) {
|
||||
cur_ += len;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
cur_ = data_;
|
||||
}
|
||||
void zeroBuffer() {
|
||||
memset(data_, 0, sizeof(data_));
|
||||
}
|
||||
|
||||
// for used by GDB
|
||||
const char *debugString();
|
||||
void setCookie(void (*cookie)()) {
|
||||
cookie_ = cookie;
|
||||
}
|
||||
// for used by unit test
|
||||
std::string toString() const {
|
||||
return std::string(data_, length());
|
||||
}
|
||||
// StringPiece toStringPiece() const { return StringPiece(data_, length());
|
||||
// }
|
||||
|
||||
private:
|
||||
const char *end() const {
|
||||
return data_ + sizeof data_;
|
||||
}
|
||||
// Must be outline function for cookies.
|
||||
static void cookieStart();
|
||||
static void cookieEnd();
|
||||
|
||||
void (*cookie_)();
|
||||
char data_[SIZE];
|
||||
char *cur_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class LogStream {
|
||||
using self = LogStream;
|
||||
|
||||
protected:
|
||||
LogStream(const LogStream &) = delete;
|
||||
LogStream &operator=(const LogStream &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
LogStream(LogStream &&) noexcept(true) = default;
|
||||
LogStream &operator=(LogStream &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
using Buffer = detail::FixedBuffer<detail::kSmallBuffer>;
|
||||
|
||||
self &operator<<(bool v) {
|
||||
append(v ? "1" : "0", 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
self &operator<<(short);
|
||||
self &operator<<(unsigned short);
|
||||
self &operator<<(int);
|
||||
self &operator<<(unsigned int);
|
||||
self &operator<<(long);
|
||||
self &operator<<(unsigned long);
|
||||
self &operator<<(const long long &);
|
||||
self &operator<<(const unsigned long long &);
|
||||
|
||||
self &operator<<(const void *);
|
||||
|
||||
self &operator<<(float &v) {
|
||||
*this << static_cast<double>(v);
|
||||
return *this;
|
||||
}
|
||||
self &operator<<(const double &);
|
||||
self &operator<<(const long double &v);
|
||||
|
||||
self &operator<<(char v) {
|
||||
append(&v, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// self& operator<<(signed char);
|
||||
// self& operator<<(unsigned char);
|
||||
template <int N>
|
||||
self &operator<<(const char (&buf)[N]) {
|
||||
assert(strnlen(buf, N) == N - 1);
|
||||
append(buf, N - 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
self &operator<<(char *str) {
|
||||
if (str) {
|
||||
append(str, strlen(str));
|
||||
} else {
|
||||
append("(null)", 6);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
self &operator<<(const char *str) {
|
||||
if (str) {
|
||||
append(str, strlen(str));
|
||||
} else {
|
||||
append("(null)", 6);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
self &operator<<(const unsigned char *str) {
|
||||
return operator<<(reinterpret_cast<const char *>(str));
|
||||
}
|
||||
|
||||
self &operator<<(const std::string &v) {
|
||||
append(v.c_str(), v.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void append(const char *data, size_t len) {
|
||||
if (exBuffer_.empty()) {
|
||||
if (!buffer_.append(data, len)) {
|
||||
exBuffer_.append(buffer_.data(), buffer_.length());
|
||||
exBuffer_.append(data, len);
|
||||
}
|
||||
} else {
|
||||
exBuffer_.append(data, len);
|
||||
}
|
||||
}
|
||||
// const Buffer& buffer() const { return buffer_; }
|
||||
const char *bufferData() const {
|
||||
if (!exBuffer_.empty()) {
|
||||
return exBuffer_.data();
|
||||
}
|
||||
return buffer_.data();
|
||||
}
|
||||
|
||||
size_t bufferLength() const {
|
||||
if (!exBuffer_.empty()) {
|
||||
return exBuffer_.length();
|
||||
}
|
||||
return buffer_.length();
|
||||
}
|
||||
void resetBuffer() {
|
||||
buffer_.reset();
|
||||
exBuffer_.clear();
|
||||
}
|
||||
|
||||
LogStream() {}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void formatInteger(T);
|
||||
|
||||
Buffer buffer_;
|
||||
std::string exBuffer_;
|
||||
};
|
||||
|
||||
class Fmt // : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
Fmt(const char *fmt, T val);
|
||||
|
||||
const char *data() const {
|
||||
return buf_;
|
||||
}
|
||||
int length() const {
|
||||
return length_;
|
||||
}
|
||||
|
||||
private:
|
||||
char buf_[48];
|
||||
int length_;
|
||||
};
|
||||
|
||||
inline LogStream &operator<<(LogStream &s, const Fmt &fmt) {
|
||||
s.append(fmt.data(), fmt.length());
|
||||
return s;
|
||||
}
|
||||
|
@ -1,34 +1,4 @@
|
||||
|
||||
// This file contains code from Trantor - Logger.cc
|
||||
|
||||
// Copyright (c) 2022 Péter Magyar
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include "core/string.h"
|
||||
@ -37,15 +7,6 @@
|
||||
#include <stdio.h>
|
||||
#include "logger.h"
|
||||
#include <thread>
|
||||
#ifndef _WIN32
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <sstream>
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
void RLogger::log_trace(const String &str) {
|
||||
log_trace(str.data());
|
||||
@ -87,161 +48,3 @@ void RLogger::_log_msg_error(const char *p_function, const char *p_file, int p_l
|
||||
void RLogger::_log_index_error(const char *p_function, const char *p_file, int p_line, const int index, const int size, const char *str) {
|
||||
printf("!INDEX ERROR: (%s) %s:%d :: index: %d/%d. %s\n", p_file, p_function, p_line, index, size, str);
|
||||
}
|
||||
|
||||
// helper class for known string length at compile time
|
||||
class T {
|
||||
public:
|
||||
T(const char *str, unsigned len) :
|
||||
str_(str), len_(len) {
|
||||
assert(strlen(str) == len_);
|
||||
}
|
||||
|
||||
const char *str_;
|
||||
const unsigned len_;
|
||||
};
|
||||
|
||||
const char *strerror_tl(int savedErrno) {
|
||||
#ifndef _MSC_VER
|
||||
return strerror(savedErrno);
|
||||
#else
|
||||
static thread_local char errMsg[64];
|
||||
(void)strerror_s<sizeof errMsg>(errMsg, savedErrno);
|
||||
return errMsg;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline LogStream &operator<<(LogStream &s, T v) {
|
||||
s.append(v.str_, v.len_);
|
||||
return s;
|
||||
}
|
||||
|
||||
inline LogStream &operator<<(LogStream &s, const Logger::SourceFile &v) {
|
||||
s.append(v.data_, v.size_);
|
||||
return s;
|
||||
}
|
||||
|
||||
static thread_local uint64_t lastSecond_{ 0 };
|
||||
static thread_local char lastTimeString_[32] = { 0 };
|
||||
#ifdef __linux__
|
||||
static thread_local pid_t threadId_{ 0 };
|
||||
#else
|
||||
static thread_local uint64_t threadId_{ 0 };
|
||||
#endif
|
||||
// static thread_local LogStream logStream_;
|
||||
|
||||
void Logger::formatTime() {
|
||||
uint64_t now = static_cast<uint64_t>(date_.secondsSinceEpoch());
|
||||
uint64_t microSec =
|
||||
static_cast<uint64_t>(date_.microSecondsSinceEpoch() -
|
||||
date_.roundSecond().microSecondsSinceEpoch());
|
||||
if (now != lastSecond_) {
|
||||
lastSecond_ = now;
|
||||
#ifndef _MSC_VER
|
||||
strncpy(lastTimeString_,
|
||||
date_.toFormattedString(false).c_str(),
|
||||
sizeof(lastTimeString_) - 1);
|
||||
#else
|
||||
strncpy_s<sizeof lastTimeString_>(
|
||||
lastTimeString_,
|
||||
date_.toFormattedString(false).c_str(),
|
||||
sizeof(lastTimeString_) - 1);
|
||||
#endif
|
||||
}
|
||||
logStream_ << T(lastTimeString_, 17);
|
||||
char tmp[32];
|
||||
snprintf(tmp,
|
||||
sizeof(tmp),
|
||||
".%06llu UTC ",
|
||||
static_cast<long long unsigned int>(microSec));
|
||||
logStream_ << T(tmp, 12);
|
||||
#ifdef __linux__
|
||||
if (threadId_ == 0)
|
||||
threadId_ = static_cast<pid_t>(::syscall(SYS_gettid));
|
||||
#elif defined __FreeBSD__
|
||||
if (threadId_ == 0) {
|
||||
threadId_ = pthread_getthreadid_np();
|
||||
}
|
||||
#elif defined __OpenBSD__
|
||||
if (threadId_ == 0) {
|
||||
threadId_ = getthrid();
|
||||
}
|
||||
#elif defined _WIN32
|
||||
if (threadId_ == 0) {
|
||||
std::stringstream ss;
|
||||
ss << std::this_thread::get_id();
|
||||
threadId_ = std::stoull(ss.str());
|
||||
}
|
||||
#else
|
||||
if (threadId_ == 0) {
|
||||
pthread_threadid_np(NULL, &threadId_);
|
||||
}
|
||||
#endif
|
||||
logStream_ << threadId_;
|
||||
}
|
||||
static const char *logLevelStr[Logger::LogLevel::kNumberOfLogLevels] = {
|
||||
" TRACE ",
|
||||
" DEBUG ",
|
||||
" INFO ",
|
||||
" WARN ",
|
||||
" ERROR ",
|
||||
" FATAL ",
|
||||
};
|
||||
Logger::Logger(SourceFile file, int line) :
|
||||
sourceFile_(file), fileLine_(line), level_(kInfo) {
|
||||
formatTime();
|
||||
logStream_ << T(logLevelStr[level_], 7);
|
||||
}
|
||||
Logger::Logger(SourceFile file, int line, LogLevel level) :
|
||||
sourceFile_(file), fileLine_(line), level_(level) {
|
||||
formatTime();
|
||||
logStream_ << T(logLevelStr[level_], 7);
|
||||
}
|
||||
Logger::Logger(SourceFile file, int line, LogLevel level, const char *func) :
|
||||
sourceFile_(file), fileLine_(line), level_(level) {
|
||||
formatTime();
|
||||
logStream_ << T(logLevelStr[level_], 7) << "[" << func << "] ";
|
||||
}
|
||||
Logger::Logger(SourceFile file, int line, bool) :
|
||||
sourceFile_(file), fileLine_(line), level_(kFatal) {
|
||||
formatTime();
|
||||
logStream_ << T(logLevelStr[level_], 7);
|
||||
if (errno != 0) {
|
||||
logStream_ << strerror_tl(errno) << " (errno=" << errno << ") ";
|
||||
}
|
||||
}
|
||||
RawLogger::~RawLogger() {
|
||||
if (index_ < 0) {
|
||||
auto &oFunc = Logger::outputFunc_();
|
||||
if (!oFunc)
|
||||
return;
|
||||
oFunc(logStream_.bufferData(), logStream_.bufferLength());
|
||||
} else {
|
||||
auto &oFunc = Logger::outputFunc_(index_);
|
||||
if (!oFunc)
|
||||
return;
|
||||
oFunc(logStream_.bufferData(), logStream_.bufferLength());
|
||||
}
|
||||
}
|
||||
Logger::~Logger() {
|
||||
logStream_ << T(" - ", 3) << sourceFile_ << ':' << fileLine_ << '\n';
|
||||
if (index_ < 0) {
|
||||
auto &oFunc = Logger::outputFunc_();
|
||||
if (!oFunc)
|
||||
return;
|
||||
oFunc(logStream_.bufferData(), logStream_.bufferLength());
|
||||
if (level_ >= kError)
|
||||
Logger::flushFunc_()();
|
||||
} else {
|
||||
auto &oFunc = Logger::outputFunc_(index_);
|
||||
if (!oFunc)
|
||||
return;
|
||||
oFunc(logStream_.bufferData(), logStream_.bufferLength());
|
||||
if (level_ >= kError)
|
||||
Logger::flushFunc_(index_)();
|
||||
}
|
||||
|
||||
// logStream_.resetBuffer();
|
||||
}
|
||||
LogStream &Logger::stream() {
|
||||
return logStream_;
|
||||
}
|
||||
|
@ -1,39 +1,7 @@
|
||||
|
||||
// This file contains code from Trantor - Logger.h
|
||||
|
||||
// Copyright (c) 2022 Péter Magyar
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include "core/math/date.h"
|
||||
#include "log_stream.h"
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
@ -61,352 +29,4 @@ public:
|
||||
static void _log_index_error(const char *p_function, const char *p_file, int p_line, const int index, const int size, const char *str);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class implements log functions.
|
||||
*
|
||||
*/
|
||||
class Logger {
|
||||
protected:
|
||||
Logger(const Logger &) = delete;
|
||||
Logger &operator=(const Logger &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Logger(Logger &&) noexcept(true) = default;
|
||||
Logger &operator=(Logger &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
enum LogLevel {
|
||||
kTrace = 0,
|
||||
kDebug,
|
||||
kInfo,
|
||||
kWarn,
|
||||
kError,
|
||||
kFatal,
|
||||
kNumberOfLogLevels
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Calculate of basename of source files in compile time.
|
||||
*
|
||||
*/
|
||||
class SourceFile {
|
||||
public:
|
||||
template <int N>
|
||||
inline SourceFile(const char (&arr)[N]) :
|
||||
data_(arr), size_(N - 1) {
|
||||
// std::cout<<data_<<std::endl;
|
||||
const char *slash = strrchr(data_, '/'); // builtin function
|
||||
if (slash) {
|
||||
data_ = slash + 1;
|
||||
size_ -= static_cast<int>(data_ - arr);
|
||||
}
|
||||
}
|
||||
|
||||
explicit SourceFile(const char *filename) :
|
||||
data_(filename) {
|
||||
const char *slash = strrchr(filename, '/');
|
||||
if (slash) {
|
||||
data_ = slash + 1;
|
||||
}
|
||||
size_ = static_cast<int>(strlen(data_));
|
||||
}
|
||||
|
||||
const char *data_;
|
||||
int size_;
|
||||
};
|
||||
Logger(SourceFile file, int line);
|
||||
Logger(SourceFile file, int line, LogLevel level);
|
||||
Logger(SourceFile file, int line, bool isSysErr);
|
||||
Logger(SourceFile file, int line, LogLevel level, const char *func);
|
||||
~Logger();
|
||||
Logger &setIndex(int index) {
|
||||
index_ = index;
|
||||
return *this;
|
||||
}
|
||||
LogStream &stream();
|
||||
|
||||
/**
|
||||
* @brief Set the output function.
|
||||
*
|
||||
* @param outputFunc The function to output a log message.
|
||||
* @param flushFunc The function to flush.
|
||||
* @note Logs are output to the standard output by default.
|
||||
*/
|
||||
static void setOutputFunction(
|
||||
std::function<void(const char *msg, const uint64_t len)> outputFunc,
|
||||
std::function<void()> flushFunc,
|
||||
int index = -1) {
|
||||
if (index < 0) {
|
||||
outputFunc_() = outputFunc;
|
||||
flushFunc_() = flushFunc;
|
||||
} else {
|
||||
outputFunc_(index) = outputFunc;
|
||||
flushFunc_(index) = flushFunc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the log level. Logs below the level are not printed.
|
||||
*
|
||||
* @param level
|
||||
*/
|
||||
static void setLogLevel(LogLevel level) {
|
||||
logLevel_() = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current log level.
|
||||
*
|
||||
* @return LogLevel
|
||||
*/
|
||||
static LogLevel logLevel() {
|
||||
return logLevel_();
|
||||
}
|
||||
|
||||
protected:
|
||||
static void defaultOutputFunction(const char *msg, const uint64_t len) {
|
||||
fwrite(msg, 1, len, stdout);
|
||||
}
|
||||
static void defaultFlushFunction() {
|
||||
fflush(stdout);
|
||||
}
|
||||
void formatTime();
|
||||
static LogLevel &logLevel_() {
|
||||
#ifdef RELEASE
|
||||
static LogLevel logLevel = LogLevel::kInfo;
|
||||
#else
|
||||
static LogLevel logLevel = LogLevel::kDebug;
|
||||
#endif
|
||||
return logLevel;
|
||||
}
|
||||
static std::function<void(const char *msg, const uint64_t len)>
|
||||
&outputFunc_() {
|
||||
static std::function<void(const char *msg, const uint64_t len)>
|
||||
outputFunc = Logger::defaultOutputFunction;
|
||||
return outputFunc;
|
||||
}
|
||||
static std::function<void()> &flushFunc_() {
|
||||
static std::function<void()> flushFunc = Logger::defaultFlushFunction;
|
||||
return flushFunc;
|
||||
}
|
||||
static std::function<void(const char *msg, const uint64_t len)>
|
||||
&outputFunc_(size_t index) {
|
||||
static std::vector<
|
||||
std::function<void(const char *msg, const uint64_t len)> >
|
||||
outputFuncs;
|
||||
if (index < outputFuncs.size()) {
|
||||
return outputFuncs[index];
|
||||
}
|
||||
while (index >= outputFuncs.size()) {
|
||||
outputFuncs.emplace_back(outputFunc_());
|
||||
}
|
||||
return outputFuncs[index];
|
||||
}
|
||||
static std::function<void()> &flushFunc_(size_t index) {
|
||||
static std::vector<std::function<void()> > flushFuncs;
|
||||
if (index < flushFuncs.size()) {
|
||||
return flushFuncs[index];
|
||||
}
|
||||
while (index >= flushFuncs.size()) {
|
||||
flushFuncs.emplace_back(flushFunc_());
|
||||
}
|
||||
return flushFuncs[index];
|
||||
}
|
||||
friend class RawLogger;
|
||||
LogStream logStream_;
|
||||
Date date_{ Date::now() };
|
||||
SourceFile sourceFile_;
|
||||
int fileLine_;
|
||||
LogLevel level_;
|
||||
int index_{ -1 };
|
||||
};
|
||||
|
||||
class RawLogger {
|
||||
protected:
|
||||
RawLogger(const RawLogger &) = delete;
|
||||
RawLogger &operator=(const RawLogger &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
RawLogger(RawLogger &&) noexcept(true) = default;
|
||||
RawLogger &operator=(RawLogger &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
RawLogger() {}
|
||||
~RawLogger();
|
||||
RawLogger &setIndex(int index) {
|
||||
index_ = index;
|
||||
return *this;
|
||||
}
|
||||
LogStream &stream() {
|
||||
return logStream_;
|
||||
}
|
||||
|
||||
private:
|
||||
LogStream logStream_;
|
||||
int index_{ -1 };
|
||||
};
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define LOG_TRACE \
|
||||
if (0) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#else
|
||||
#define LOG_TRACE \
|
||||
if (Logger::logLevel() <= Logger::kTrace) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#define LOG_TRACE_TO(index) \
|
||||
if (Logger::logLevel() <= Logger::kTrace) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.setIndex(index) \
|
||||
.stream()
|
||||
|
||||
#endif
|
||||
|
||||
#define LOG_DEBUG \
|
||||
if (Logger::logLevel() <= Logger::kDebug) \
|
||||
Logger(__FILE__, __LINE__, Logger::kDebug, __func__) \
|
||||
.stream()
|
||||
#define LOG_DEBUG_TO(index) \
|
||||
if (Logger::logLevel() <= Logger::kDebug) \
|
||||
Logger(__FILE__, __LINE__, Logger::kDebug, __func__) \
|
||||
.setIndex(index) \
|
||||
.stream()
|
||||
#define LOG_INFO \
|
||||
if (Logger::logLevel() <= Logger::kInfo) \
|
||||
Logger(__FILE__, __LINE__).stream()
|
||||
#define LOG_INFO_TO(index) \
|
||||
if (Logger::logLevel() <= Logger::kInfo) \
|
||||
Logger(__FILE__, __LINE__).setIndex(index).stream()
|
||||
#define LOG_WARN \
|
||||
Logger(__FILE__, __LINE__, Logger::kWarn).stream()
|
||||
#define LOG_WARN_TO(index) \
|
||||
Logger(__FILE__, __LINE__, Logger::kWarn) \
|
||||
.setIndex(index) \
|
||||
.stream()
|
||||
#define LOG_ERROR \
|
||||
Logger(__FILE__, __LINE__, Logger::kError).stream()
|
||||
#define LOG_ERROR_TO(index) \
|
||||
Logger(__FILE__, __LINE__, Logger::kError) \
|
||||
.setIndex(index) \
|
||||
.stream()
|
||||
#define LOG_FATAL \
|
||||
Logger(__FILE__, __LINE__, Logger::kFatal).stream()
|
||||
#define LOG_FATAL_TO(index) \
|
||||
Logger(__FILE__, __LINE__, Logger::kFatal) \
|
||||
.setIndex(index) \
|
||||
.stream()
|
||||
#define LOG_SYSERR Logger(__FILE__, __LINE__, true).stream()
|
||||
#define LOG_SYSERR_TO(index) \
|
||||
Logger(__FILE__, __LINE__, true).setIndex(index).stream()
|
||||
|
||||
#define LOG_RAW RawLogger().stream()
|
||||
#define LOG_RAW_TO(index) RawLogger().setIndex(index).stream()
|
||||
|
||||
#define LOG_TRACE_IF(cond) \
|
||||
if ((Logger::logLevel() <= Logger::kTrace) && (cond)) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#define LOG_DEBUG_IF(cond) \
|
||||
if ((Tensor::Logger::logLevel() <= Tensor::Logger::kDebug) && (cond)) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kDebug, __func__) \
|
||||
.stream()
|
||||
#define LOG_INFO_IF(cond) \
|
||||
if ((Tensor::Logger::logLevel() <= Tensor::Logger::kInfo) && (cond)) \
|
||||
Tensor::Logger(__FILE__, __LINE__).stream()
|
||||
#define LOG_WARN_IF(cond) \
|
||||
if (cond) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kWarn).stream()
|
||||
#define LOG_ERROR_IF(cond) \
|
||||
if (cond) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kError).stream()
|
||||
#define LOG_FATAL_IF(cond) \
|
||||
if (cond) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kFatal).stream()
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DLOG_TRACE \
|
||||
if (0) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#define DLOG_DEBUG \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kDebug, __func__) \
|
||||
.stream()
|
||||
#define DLOG_INFO \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__).stream()
|
||||
#define DLOG_WARN \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kWarn).stream()
|
||||
#define DLOG_ERROR \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kError).stream()
|
||||
#define DLOG_FATAL \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kFatal).stream()
|
||||
|
||||
#define DLOG_TRACE_IF(cond) \
|
||||
if (0) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#define DLOG_DEBUG_IF(cond) \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kDebug, __func__) \
|
||||
.stream()
|
||||
#define DLOG_INFO_IF(cond) \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__).stream()
|
||||
#define DLOG_WARN_IF(cond) \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kWarn).stream()
|
||||
#define DLOG_ERROR_IF(cond) \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kError).stream()
|
||||
#define DLOG_FATAL_IF(cond) \
|
||||
if (0) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kFatal).stream()
|
||||
#else
|
||||
#define DLOG_TRACE \
|
||||
if (Logger::logLevel() <= Logger::kTrace) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#define DLOG_DEBUG \
|
||||
if (Tensor::Logger::logLevel() <= Tensor::Logger::kDebug) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kDebug, __func__) \
|
||||
.stream()
|
||||
#define DLOG_INFO \
|
||||
if (Tensor::Logger::logLevel() <= Tensor::Logger::kInfo) \
|
||||
Tensor::Logger(__FILE__, __LINE__).stream()
|
||||
#define DLOG_WARN \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kWarn).stream()
|
||||
#define DLOG_ERROR \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kError).stream()
|
||||
#define DLOG_FATAL \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kFatal).stream()
|
||||
|
||||
#define DLOG_TRACE_IF(cond) \
|
||||
if ((Logger::logLevel() <= Logger::kTrace) && (cond)) \
|
||||
Logger(__FILE__, __LINE__, Logger::kTrace, __func__) \
|
||||
.stream()
|
||||
#define DLOG_DEBUG_IF(cond) \
|
||||
if ((Tensor::Logger::logLevel() <= Tensor::Logger::kDebug) && (cond)) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kDebug, __func__) \
|
||||
.stream()
|
||||
#define DLOG_INFO_IF(cond) \
|
||||
if ((Tensor::Logger::logLevel() <= Tensor::Logger::kInfo) && (cond)) \
|
||||
Tensor::Logger(__FILE__, __LINE__).stream()
|
||||
#define DLOG_WARN_IF(cond) \
|
||||
if (cond) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kWarn).stream()
|
||||
#define DLOG_ERROR_IF(cond) \
|
||||
if (cond) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kError).stream()
|
||||
#define DLOG_FATAL_IF(cond) \
|
||||
if (cond) \
|
||||
Tensor::Logger(__FILE__, __LINE__, Tensor::Logger::kFatal).stream()
|
||||
#endif
|
||||
|
||||
const char *strerror_tl(int savedErrno);
|
||||
|
||||
#endif
|
||||
|
@ -1,324 +0,0 @@
|
||||
|
||||
// This file is originally from Moduo -> Trantor - EventLoop.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
// Copyright (c) 2010, Shuo Chen. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/containers/lock_free_queue.h"
|
||||
#include "core/math/date.h"
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
class Poller;
|
||||
class TimerQueue;
|
||||
class Channel;
|
||||
using ChannelList = std::vector<Channel *>;
|
||||
using Func = std::function<void()>;
|
||||
using TimerId = uint64_t;
|
||||
enum {
|
||||
InvalidTimerId = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief As the name implies, this class represents an event loop that runs in
|
||||
* a perticular thread. The event loop can handle network I/O events and timers
|
||||
* in asynchronous mode.
|
||||
* @note An event loop object always belongs to a separate thread, and there is
|
||||
* one event loop object at most in a thread. We can call an event loop object
|
||||
* the event loop of the thread it belongs to, or call that thread the thread of
|
||||
* the event loop.
|
||||
*/
|
||||
class EventLoop {
|
||||
protected:
|
||||
EventLoop(const EventLoop &) = delete;
|
||||
EventLoop &operator=(const EventLoop &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
EventLoop(EventLoop &&) noexcept(true) = default;
|
||||
EventLoop &operator=(EventLoop &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
EventLoop();
|
||||
~EventLoop();
|
||||
|
||||
/**
|
||||
* @brief Run the event loop. This method will be blocked until the event
|
||||
* loop exits.
|
||||
*
|
||||
*/
|
||||
void loop();
|
||||
|
||||
/**
|
||||
* @brief Let the event loop quit.
|
||||
*
|
||||
*/
|
||||
void quit();
|
||||
|
||||
/**
|
||||
* @brief Assertion that the current thread is the thread to which the event
|
||||
* loop belongs. If the assertion fails, the program aborts.
|
||||
*/
|
||||
void assertInLoopThread() {
|
||||
if (!isInLoopThread()) {
|
||||
abortNotInLoopThread();
|
||||
}
|
||||
};
|
||||
#ifdef __linux__
|
||||
/**
|
||||
* @brief Make the timer queue works after calling the fork() function.
|
||||
*
|
||||
*/
|
||||
void resetTimerQueue();
|
||||
#endif
|
||||
/**
|
||||
* @brief Make the event loop works after calling the fork() function.
|
||||
*
|
||||
*/
|
||||
void resetAfterFork();
|
||||
|
||||
/**
|
||||
* @brief Return true if the current thread is the thread to which the event
|
||||
* loop belongs.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isInLoopThread() const {
|
||||
return threadId_ == std::this_thread::get_id();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get the event loop of the current thread. Return nullptr if there
|
||||
* is no event loop in the current thread.
|
||||
*
|
||||
* @return EventLoop*
|
||||
*/
|
||||
static EventLoop *getEventLoopOfCurrentThread();
|
||||
|
||||
/**
|
||||
* @brief Run the function f in the thread of the event loop.
|
||||
*
|
||||
* @param f
|
||||
* @note If the current thread is the thread of the event loop, the function
|
||||
* f is executed directly before the method exiting.
|
||||
*/
|
||||
void runInLoop(const Func &f);
|
||||
void runInLoop(Func &&f);
|
||||
|
||||
/**
|
||||
* @brief Run the function f in the thread of the event loop.
|
||||
*
|
||||
* @param f
|
||||
* @note The difference between this method and the runInLoop() method is
|
||||
* that the function f is executed after the method exiting no matter if the
|
||||
* current thread is the thread of the event loop.
|
||||
*/
|
||||
void queueInLoop(const Func &f);
|
||||
void queueInLoop(Func &&f);
|
||||
|
||||
/**
|
||||
* @brief Run a function at a time point.
|
||||
*
|
||||
* @param time The time to run the function.
|
||||
* @param cb The function to run.
|
||||
* @return TimerId The ID of the timer.
|
||||
*/
|
||||
TimerId runAt(const Date &time, const Func &cb);
|
||||
TimerId runAt(const Date &time, Func &&cb);
|
||||
|
||||
/**
|
||||
* @brief Run a function after a period of time.
|
||||
*
|
||||
* @param delay Represent the period of time in seconds.
|
||||
* @param cb The function to run.
|
||||
* @return TimerId The ID of the timer.
|
||||
*/
|
||||
TimerId runAfter(double delay, const Func &cb);
|
||||
TimerId runAfter(double delay, Func &&cb);
|
||||
|
||||
/**
|
||||
* @brief Run a function after a period of time.
|
||||
* @note Users could use chrono literals to represent a time duration
|
||||
* For example:
|
||||
* @code
|
||||
runAfter(5s, task);
|
||||
runAfter(10min, task);
|
||||
@endcode
|
||||
*/
|
||||
TimerId runAfter(const std::chrono::duration<double> &delay, const Func &cb) {
|
||||
return runAfter(delay.count(), cb);
|
||||
}
|
||||
TimerId runAfter(const std::chrono::duration<double> &delay, Func &&cb) {
|
||||
return runAfter(delay.count(), std::move(cb));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Repeatedly run a function every period of time.
|
||||
*
|
||||
* @param interval The duration in seconds.
|
||||
* @param cb The function to run.
|
||||
* @return TimerId The ID of the timer.
|
||||
*/
|
||||
TimerId runEvery(double interval, const Func &cb);
|
||||
TimerId runEvery(double interval, Func &&cb);
|
||||
|
||||
/**
|
||||
* @brief Repeatedly run a function every period of time.
|
||||
* Users could use chrono literals to represent a time duration
|
||||
* For example:
|
||||
* @code
|
||||
runEvery(5s, task);
|
||||
runEvery(10min, task);
|
||||
runEvery(0.1h, task);
|
||||
@endcode
|
||||
*/
|
||||
TimerId runEvery(const std::chrono::duration<double> &interval,
|
||||
const Func &cb) {
|
||||
return runEvery(interval.count(), cb);
|
||||
}
|
||||
TimerId runEvery(const std::chrono::duration<double> &interval, Func &&cb) {
|
||||
return runEvery(interval.count(), std::move(cb));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Invalidate the timer identified by the given ID.
|
||||
*
|
||||
* @param id The ID of the timer.
|
||||
*/
|
||||
void invalidateTimer(TimerId id);
|
||||
|
||||
/**
|
||||
* @brief Move the EventLoop to the current thread, this method must be
|
||||
* called before the loop is running.
|
||||
*
|
||||
*/
|
||||
void moveToCurrentThread();
|
||||
|
||||
/**
|
||||
* @brief Update channel status. This method is usually used internally.
|
||||
*
|
||||
* @param chl
|
||||
*/
|
||||
void updateChannel(Channel *chl);
|
||||
|
||||
/**
|
||||
* @brief Remove a channel from the event loop. This method is usually used
|
||||
* internally.
|
||||
*
|
||||
* @param chl
|
||||
*/
|
||||
void removeChannel(Channel *chl);
|
||||
|
||||
/**
|
||||
* @brief Return the index of the event loop.
|
||||
*
|
||||
* @return size_t
|
||||
*/
|
||||
size_t index() {
|
||||
return index_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the index of the event loop.
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
void setIndex(size_t index) {
|
||||
index_ = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return true if the event loop is running.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isRunning() {
|
||||
return looping_ && (!quit_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the event loop is calling a function.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isCallingFunctions() {
|
||||
return callingFuncs_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run functions when the event loop quits
|
||||
*
|
||||
* @param cb the function to run
|
||||
* @note the function runs on the thread that quits the EventLoop
|
||||
*/
|
||||
void runOnQuit(Func &&cb);
|
||||
void runOnQuit(const Func &cb);
|
||||
|
||||
private:
|
||||
void abortNotInLoopThread();
|
||||
void wakeup();
|
||||
void wakeupRead();
|
||||
bool looping_;
|
||||
std::thread::id threadId_;
|
||||
bool quit_;
|
||||
std::unique_ptr<Poller> poller_;
|
||||
|
||||
ChannelList activeChannels_;
|
||||
Channel *currentActiveChannel_;
|
||||
|
||||
bool eventHandling_;
|
||||
MpscQueue<Func> funcs_;
|
||||
std::unique_ptr<TimerQueue> timerQueue_;
|
||||
MpscQueue<Func> funcsOnQuit_;
|
||||
bool callingFuncs_{ false };
|
||||
#ifdef __linux__
|
||||
int wakeupFd_;
|
||||
std::unique_ptr<Channel> wakeupChannelPtr_;
|
||||
#elif defined _WIN32
|
||||
#else
|
||||
int wakeupFd_[2];
|
||||
std::unique_ptr<Channel> wakeupChannelPtr_;
|
||||
#endif
|
||||
|
||||
void doRunInLoopFuncs();
|
||||
#ifdef _WIN32
|
||||
size_t index_{ size_t(-1) };
|
||||
#else
|
||||
size_t index_{ std::numeric_limits<size_t>::max() };
|
||||
#endif
|
||||
EventLoop **threadLocalLoopPtr_;
|
||||
};
|
@ -1,80 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - EventLoopThread.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "event_loop_thread.h"
|
||||
#include "core/log/logger.h"
|
||||
#ifdef __linux__
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
EventLoopThread::EventLoopThread(const std::string &threadName) :
|
||||
loop_(nullptr),
|
||||
loopThreadName_(threadName),
|
||||
thread_([this]() { loopFuncs(); }) {
|
||||
auto f = promiseForLoopPointer_.get_future();
|
||||
loop_ = f.get();
|
||||
}
|
||||
EventLoopThread::~EventLoopThread() {
|
||||
run();
|
||||
if (loop_) {
|
||||
loop_->quit();
|
||||
}
|
||||
if (thread_.joinable()) {
|
||||
thread_.join();
|
||||
}
|
||||
}
|
||||
// void EventLoopThread::stop() {
|
||||
// if(loop_)
|
||||
// loop_->quit();
|
||||
//}
|
||||
void EventLoopThread::wait() {
|
||||
thread_.join();
|
||||
}
|
||||
void EventLoopThread::loopFuncs() {
|
||||
#ifdef __linux__
|
||||
::prctl(PR_SET_NAME, loopThreadName_.c_str());
|
||||
#endif
|
||||
EventLoop loop;
|
||||
loop.queueInLoop([this]() { promiseForLoop_.set_value(1); });
|
||||
promiseForLoopPointer_.set_value(&loop);
|
||||
auto f = promiseForRun_.get_future();
|
||||
(void)f.get();
|
||||
loop.loop();
|
||||
// LOG_DEBUG << "loop out";
|
||||
loop_ = NULL;
|
||||
}
|
||||
void EventLoopThread::run() {
|
||||
std::call_once(once_, [this]() {
|
||||
auto f = promiseForLoop_.get_future();
|
||||
promiseForRun_.set_value(1);
|
||||
// Make sure the event loop loops before returning.
|
||||
(void)f.get();
|
||||
});
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - EventLoopThread.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "event_loop.h"
|
||||
#include <condition_variable>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
/**
|
||||
* @brief This class represents an event loop thread.
|
||||
*
|
||||
*/
|
||||
class EventLoopThread {
|
||||
protected:
|
||||
EventLoopThread(const EventLoopThread &) = delete;
|
||||
EventLoopThread &operator=(const EventLoopThread &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
EventLoopThread(EventLoopThread &&) noexcept(true) = default;
|
||||
EventLoopThread &operator=(EventLoopThread &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
explicit EventLoopThread(const std::string &threadName = "EventLoopThread");
|
||||
~EventLoopThread();
|
||||
|
||||
/**
|
||||
* @brief Wait for the event loop to exit.
|
||||
* @note This method blocks the current thread until the event loop exits.
|
||||
*/
|
||||
void wait();
|
||||
|
||||
/**
|
||||
* @brief Get the pointer of the event loop of the thread.
|
||||
*
|
||||
* @return EventLoop*
|
||||
*/
|
||||
EventLoop *getLoop() const {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run the event loop of the thread. This method doesn't block the
|
||||
* current thread.
|
||||
*
|
||||
*/
|
||||
void run();
|
||||
|
||||
private:
|
||||
EventLoop *loop_;
|
||||
std::string loopThreadName_;
|
||||
void loopFuncs();
|
||||
std::promise<EventLoop *> promiseForLoopPointer_;
|
||||
std::promise<int> promiseForRun_;
|
||||
std::promise<int> promiseForLoop_;
|
||||
std::once_flag once_;
|
||||
std::thread thread_;
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - EventLoopThreadPool.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "event_loop_thread_pool.h"
|
||||
|
||||
EventLoopThreadPool::EventLoopThreadPool(size_t threadNum,
|
||||
const std::string &name) :
|
||||
loopIndex_(0) {
|
||||
for (size_t i = 0; i < threadNum; ++i) {
|
||||
loopThreadVector_.emplace_back(std::make_shared<EventLoopThread>(name));
|
||||
}
|
||||
}
|
||||
void EventLoopThreadPool::start() {
|
||||
for (unsigned int i = 0; i < loopThreadVector_.size(); ++i) {
|
||||
loopThreadVector_[i]->run();
|
||||
}
|
||||
}
|
||||
// void EventLoopThreadPool::stop(){
|
||||
// for(unsigned int i=0;i<loopThreadVector_.size();i++)
|
||||
// {
|
||||
// loopThreadVector_[i].stop();
|
||||
// }
|
||||
//}
|
||||
void EventLoopThreadPool::wait() {
|
||||
for (unsigned int i = 0; i < loopThreadVector_.size(); ++i) {
|
||||
loopThreadVector_[i]->wait();
|
||||
}
|
||||
}
|
||||
EventLoop *EventLoopThreadPool::getNextLoop() {
|
||||
if (loopThreadVector_.size() > 0) {
|
||||
EventLoop *loop = loopThreadVector_[loopIndex_]->getLoop();
|
||||
++loopIndex_;
|
||||
if (loopIndex_ >= loopThreadVector_.size())
|
||||
loopIndex_ = 0;
|
||||
return loop;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
EventLoop *EventLoopThreadPool::getLoop(size_t id) {
|
||||
if (id < loopThreadVector_.size())
|
||||
return loopThreadVector_[id]->getLoop();
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<EventLoop *> EventLoopThreadPool::getLoops() const {
|
||||
std::vector<EventLoop *> ret;
|
||||
for (auto &loopThread : loopThreadVector_) {
|
||||
ret.push_back(loopThread->getLoop());
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - EventLoopThreadPool.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "event_loop_thread.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief This class represents a pool of EventLoopThread objects
|
||||
*
|
||||
*/
|
||||
class EventLoopThreadPool {
|
||||
protected:
|
||||
EventLoopThreadPool(const EventLoopThreadPool &) = delete;
|
||||
EventLoopThreadPool &operator=(const EventLoopThreadPool &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
EventLoopThreadPool(EventLoopThreadPool &&) noexcept(true) = default;
|
||||
EventLoopThreadPool &operator=(EventLoopThreadPool &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
EventLoopThreadPool() = delete;
|
||||
|
||||
/**
|
||||
* @brief Construct a new event loop thread pool instance.
|
||||
*
|
||||
* @param threadNum The number of threads
|
||||
* @param name The name of the EventLoopThreadPool object.
|
||||
*/
|
||||
EventLoopThreadPool(size_t threadNum,
|
||||
const std::string &name = "EventLoopThreadPool");
|
||||
|
||||
/**
|
||||
* @brief Run all event loops in the pool.
|
||||
* @note This function doesn't block the current thread.
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* @brief Wait for all event loops in the pool to quit.
|
||||
*
|
||||
* @note This function blocks the current thread.
|
||||
*/
|
||||
void wait();
|
||||
|
||||
/**
|
||||
* @brief Return the number of the event loop.
|
||||
*
|
||||
* @return size_t
|
||||
*/
|
||||
size_t size() {
|
||||
return loopThreadVector_.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the next event loop in the pool.
|
||||
*
|
||||
* @return EventLoop*
|
||||
*/
|
||||
EventLoop *getNextLoop();
|
||||
|
||||
/**
|
||||
* @brief Get the event loop in the `id` position in the pool.
|
||||
*
|
||||
* @param id The id of the first event loop is zero. If the id >= the number
|
||||
* of event loops, nullptr is returned.
|
||||
* @return EventLoop*
|
||||
*/
|
||||
EventLoop *getLoop(size_t id);
|
||||
|
||||
/**
|
||||
* @brief Get all event loops in the pool.
|
||||
*
|
||||
* @return std::vector<EventLoop *>
|
||||
*/
|
||||
std::vector<EventLoop *> getLoops() const;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<EventLoopThread> > loopThreadVector_;
|
||||
size_t loopIndex_;
|
||||
};
|
@ -1,69 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Timer.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "timer.h"
|
||||
#include "core/log/logger.h"
|
||||
#include "core/loops/event_loop.h"
|
||||
|
||||
std::atomic<TimerId> Timer::timersCreated_ = ATOMIC_VAR_INIT(InvalidTimerId);
|
||||
Timer::Timer(const TimerCallback &cb,
|
||||
const TimePoint &when,
|
||||
const TimeInterval &interval) :
|
||||
callback_(cb),
|
||||
when_(when),
|
||||
interval_(interval),
|
||||
repeat_(interval.count() > 0),
|
||||
id_(++timersCreated_) {
|
||||
}
|
||||
Timer::Timer(TimerCallback &&cb,
|
||||
const TimePoint &when,
|
||||
const TimeInterval &interval) :
|
||||
callback_(std::move(cb)),
|
||||
when_(when),
|
||||
interval_(interval),
|
||||
repeat_(interval.count() > 0),
|
||||
id_(++timersCreated_) {
|
||||
// LOG_TRACE<<"Timer move contrustor";
|
||||
}
|
||||
void Timer::run() const {
|
||||
callback_();
|
||||
}
|
||||
void Timer::restart(const TimePoint &now) {
|
||||
if (repeat_) {
|
||||
when_ = now + interval_;
|
||||
} else
|
||||
when_ = std::chrono::steady_clock::now();
|
||||
}
|
||||
bool Timer::operator<(const Timer &t) const {
|
||||
return when_ < t.when_;
|
||||
}
|
||||
bool Timer::operator>(const Timer &t) const {
|
||||
return when_ > t.when_;
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Timer.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/net/callbacks.h"
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
using TimerId = uint64_t;
|
||||
using TimePoint = std::chrono::steady_clock::time_point;
|
||||
using TimeInterval = std::chrono::microseconds;
|
||||
|
||||
class Timer {
|
||||
protected:
|
||||
Timer(const Timer &) = delete;
|
||||
Timer &operator=(const Timer &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Timer(Timer &&) noexcept(true) = default;
|
||||
Timer &operator=(Timer &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
Timer(const TimerCallback &cb,
|
||||
const TimePoint &when,
|
||||
const TimeInterval &interval);
|
||||
Timer(TimerCallback &&cb,
|
||||
const TimePoint &when,
|
||||
const TimeInterval &interval);
|
||||
~Timer() {
|
||||
// std::cout<<"Timer unconstract!"<<std::endl;
|
||||
}
|
||||
void run() const;
|
||||
void restart(const TimePoint &now);
|
||||
bool operator<(const Timer &t) const;
|
||||
bool operator>(const Timer &t) const;
|
||||
const TimePoint &when() const {
|
||||
return when_;
|
||||
}
|
||||
bool isRepeat() {
|
||||
return repeat_;
|
||||
}
|
||||
TimerId id() {
|
||||
return id_;
|
||||
}
|
||||
|
||||
private:
|
||||
TimerCallback callback_;
|
||||
TimePoint when_;
|
||||
const TimeInterval interval_;
|
||||
const bool repeat_;
|
||||
const TimerId id_;
|
||||
static std::atomic<TimerId> timersCreated_;
|
||||
};
|
||||
|
@ -1,93 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - TimerQueue.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "timer.h"
|
||||
#include "core/net/callbacks.h"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
|
||||
// class Timer;
|
||||
class EventLoop;
|
||||
class Channel;
|
||||
using TimerPtr = std::shared_ptr<Timer>;
|
||||
struct TimerPtrComparer {
|
||||
bool operator()(const TimerPtr &x, const TimerPtr &y) const {
|
||||
return *x > *y;
|
||||
}
|
||||
};
|
||||
|
||||
class TimerQueue {
|
||||
protected:
|
||||
TimerQueue(const TimerQueue &) = delete;
|
||||
TimerQueue &operator=(const TimerQueue &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
TimerQueue(TimerQueue &&) noexcept(true) = default;
|
||||
TimerQueue &operator=(TimerQueue &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
explicit TimerQueue(EventLoop *loop);
|
||||
~TimerQueue();
|
||||
TimerId addTimer(const TimerCallback &cb,
|
||||
const TimePoint &when,
|
||||
const TimeInterval &interval);
|
||||
TimerId addTimer(TimerCallback &&cb,
|
||||
const TimePoint &when,
|
||||
const TimeInterval &interval);
|
||||
void addTimerInLoop(const TimerPtr &timer);
|
||||
void invalidateTimer(TimerId id);
|
||||
#ifdef __linux__
|
||||
void reset();
|
||||
#else
|
||||
int64_t getTimeout() const;
|
||||
void processTimers();
|
||||
#endif
|
||||
protected:
|
||||
EventLoop *loop_;
|
||||
#ifdef __linux__
|
||||
int timerfd_;
|
||||
std::shared_ptr<Channel> timerfdChannelPtr_;
|
||||
void handleRead();
|
||||
#endif
|
||||
std::priority_queue<TimerPtr, std::vector<TimerPtr>, TimerPtrComparer>
|
||||
timers_;
|
||||
|
||||
bool callingExpiredTimers_;
|
||||
bool insert(const TimerPtr &timePtr);
|
||||
std::vector<TimerPtr> getExpired();
|
||||
void reset(const std::vector<TimerPtr> &expired, const TimePoint &now);
|
||||
std::vector<TimerPtr> getExpired(const TimePoint &now);
|
||||
|
||||
private:
|
||||
std::unordered_set<uint64_t> timerIdSet_;
|
||||
};
|
@ -323,24 +323,6 @@ public:
|
||||
|
||||
return hf;
|
||||
}
|
||||
|
||||
// Taken from Trantor (BSD-style License) - Funcs.h
|
||||
// Copyright (c) 2018 An Tao
|
||||
static _ALWAYS_INLINE_ uint64_t hton64(uint64_t n) {
|
||||
static const int one = 1;
|
||||
static const char sig = *(char *)&one;
|
||||
if (sig == 0)
|
||||
return n; // for big endian machine just return the input
|
||||
char *ptr = reinterpret_cast<char *>(&n);
|
||||
std::reverse(ptr, ptr + sizeof(uint64_t));
|
||||
return n;
|
||||
}
|
||||
|
||||
// Taken from Trantor (BSD-style License) - Funcs.h
|
||||
// Copyright (c) 2018 An Tao
|
||||
static _ALWAYS_INLINE_ uint64_t ntoh64(uint64_t n) {
|
||||
return hton64(n);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef ABS
|
||||
|
@ -1,100 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Acceptor.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "acceptor.h"
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC O_NOINHERIT
|
||||
#endif
|
||||
|
||||
Acceptor::Acceptor(EventLoop *loop,
|
||||
const InetAddress &addr,
|
||||
bool reUseAddr,
|
||||
bool reUsePort)
|
||||
|
||||
:
|
||||
#ifndef _WIN32
|
||||
idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC)),
|
||||
#endif
|
||||
sock_(
|
||||
Socket::createNonblockingSocketOrDie(addr.getSockAddr()->sa_family)),
|
||||
addr_(addr),
|
||||
loop_(loop),
|
||||
acceptChannel_(loop, sock_.fd()) {
|
||||
sock_.setReuseAddr(reUseAddr);
|
||||
sock_.setReusePort(reUsePort);
|
||||
sock_.bindAddress(addr_);
|
||||
acceptChannel_.setReadCallback(std::bind(&Acceptor::readCallback, this));
|
||||
if (addr_.toPort() == 0) {
|
||||
addr_ = InetAddress{ Socket::getLocalAddr(sock_.fd()) };
|
||||
}
|
||||
}
|
||||
Acceptor::~Acceptor() {
|
||||
acceptChannel_.disableAll();
|
||||
acceptChannel_.remove();
|
||||
#ifndef _WIN32
|
||||
::close(idleFd_);
|
||||
#endif
|
||||
}
|
||||
void Acceptor::listen() {
|
||||
loop_->assertInLoopThread();
|
||||
sock_.listen();
|
||||
acceptChannel_.enableReading();
|
||||
}
|
||||
|
||||
void Acceptor::readCallback() {
|
||||
InetAddress peer;
|
||||
int newsock = sock_.accept(&peer);
|
||||
if (newsock >= 0) {
|
||||
if (newConnectionCallback_) {
|
||||
newConnectionCallback_(newsock, peer);
|
||||
} else {
|
||||
#ifndef _WIN32
|
||||
::close(newsock);
|
||||
#else
|
||||
closesocket(newsock);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
LOG_SYSERR << "Accpetor::readCallback";
|
||||
// Read the section named "The special problem of
|
||||
// accept()ing when you can't" in libev's doc.
|
||||
// By Marc Lehmann, author of libev.
|
||||
/// errno is thread safe
|
||||
#ifndef _WIN32
|
||||
if (errno == EMFILE) {
|
||||
::close(idleFd_);
|
||||
idleFd_ = sock_.accept(&peer);
|
||||
::close(idleFd_);
|
||||
idleFd_ = ::open("/dev/null", O_RDONLY | O_CLOEXEC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Acceptor.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "channel.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include "core/net/socket.h"
|
||||
#include "core/loops/event_loop.h"
|
||||
#include <functional>
|
||||
|
||||
// Inherit from socket?
|
||||
// Could be called ServerSocket
|
||||
// New connection callback -> make it a virtual func?
|
||||
|
||||
using NewConnectionCallback = std::function<void(int fd, const InetAddress &)>;
|
||||
class Acceptor {
|
||||
protected:
|
||||
Acceptor(const Acceptor &) = delete;
|
||||
Acceptor &operator=(const Acceptor &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Acceptor(Acceptor &&) noexcept(true) = default;
|
||||
Acceptor &operator=(Acceptor &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
Acceptor(EventLoop *loop,
|
||||
const InetAddress &addr,
|
||||
bool reUseAddr = true,
|
||||
bool reUsePort = true);
|
||||
~Acceptor();
|
||||
const InetAddress &addr() const {
|
||||
return addr_;
|
||||
}
|
||||
void setNewConnectionCallback(const NewConnectionCallback &cb) {
|
||||
newConnectionCallback_ = cb;
|
||||
};
|
||||
void listen();
|
||||
|
||||
protected:
|
||||
#ifndef _WIN32
|
||||
int idleFd_;
|
||||
#endif
|
||||
Socket sock_;
|
||||
InetAddress addr_;
|
||||
EventLoop *loop_;
|
||||
NewConnectionCallback newConnectionCallback_;
|
||||
Channel acceptChannel_;
|
||||
void readCallback();
|
||||
};
|
@ -1,57 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - callbacks.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
enum class SSLError
|
||||
{
|
||||
kSSLHandshakeError,
|
||||
kSSLInvalidCertificate
|
||||
};
|
||||
using TimerCallback = std::function<void()>;
|
||||
|
||||
// the data has been read to (buf, len)
|
||||
class TcpConnection;
|
||||
class MsgBuffer;
|
||||
using TcpConnectionPtr = std::shared_ptr<TcpConnection>;
|
||||
// tcp server and connection callback
|
||||
using RecvMessageCallback =
|
||||
std::function<void(const TcpConnectionPtr &, MsgBuffer *)>;
|
||||
using ConnectionErrorCallback = std::function<void()>;
|
||||
using ConnectionCallback = std::function<void(const TcpConnectionPtr &)>;
|
||||
using CloseCallback = std::function<void(const TcpConnectionPtr &)>;
|
||||
using WriteCompleteCallback = std::function<void(const TcpConnectionPtr &)>;
|
||||
using HighWaterMarkCallback =
|
||||
std::function<void(const TcpConnectionPtr &, const size_t)>;
|
||||
using SSLErrorCallback = std::function<void(SSLError)>;
|
||||
|
@ -1,113 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Channel.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "channel.h"
|
||||
#include "core/loops/event_loop.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Wepoll.h"
|
||||
#define POLLIN EPOLLIN
|
||||
#define POLLPRI EPOLLPRI
|
||||
#define POLLOUT EPOLLOUT
|
||||
#define POLLHUP EPOLLHUP
|
||||
#define POLLNVAL 0
|
||||
#define POLLERR EPOLLERR
|
||||
#else
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
const int Channel::kNoneEvent = 0;
|
||||
|
||||
const int Channel::kReadEvent = POLLIN | POLLPRI;
|
||||
const int Channel::kWriteEvent = POLLOUT;
|
||||
|
||||
Channel::Channel(EventLoop *loop, int fd) :
|
||||
loop_(loop), fd_(fd), events_(0), revents_(0), index_(-1), tied_(false) {
|
||||
}
|
||||
|
||||
void Channel::remove() {
|
||||
assert(events_ == kNoneEvent);
|
||||
addedToLoop_ = false;
|
||||
loop_->removeChannel(this);
|
||||
}
|
||||
|
||||
void Channel::update() {
|
||||
loop_->updateChannel(this);
|
||||
}
|
||||
|
||||
void Channel::handleEvent() {
|
||||
// LOG_TRACE<<"revents_="<<revents_;
|
||||
if (tied_) {
|
||||
std::shared_ptr<void> guard = tie_.lock();
|
||||
if (guard) {
|
||||
handleEventSafely();
|
||||
}
|
||||
} else {
|
||||
handleEventSafely();
|
||||
}
|
||||
}
|
||||
void Channel::handleEventSafely() {
|
||||
if (eventCallback_) {
|
||||
eventCallback_();
|
||||
return;
|
||||
}
|
||||
if ((revents_ & POLLHUP) && !(revents_ & POLLIN)) {
|
||||
// LOG_TRACE<<"handle close";
|
||||
if (closeCallback_)
|
||||
closeCallback_();
|
||||
}
|
||||
if (revents_ & (POLLNVAL | POLLERR)) {
|
||||
// LOG_TRACE<<"handle error";
|
||||
if (errorCallback_)
|
||||
errorCallback_();
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (revents_ & (POLLIN | POLLPRI | POLLRDHUP))
|
||||
#else
|
||||
if (revents_ & (POLLIN | POLLPRI))
|
||||
#endif
|
||||
{
|
||||
// LOG_TRACE<<"handle read";
|
||||
if (readCallback_)
|
||||
readCallback_();
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if ((revents_ & POLLOUT) && !(revents_ & POLLHUP))
|
||||
#else
|
||||
if (revents_ & POLLOUT)
|
||||
#endif
|
||||
{
|
||||
// LOG_TRACE<<"handle write";
|
||||
if (writeCallback_)
|
||||
writeCallback_();
|
||||
}
|
||||
}
|
||||
|
@ -1,306 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Channel.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/log/logger.h"
|
||||
#include <assert.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
class EventLoop;
|
||||
/**
|
||||
* @brief This class is used to implement reactor pattern. A Channel object
|
||||
* manages a socket fd. Users use a Channel object to receive write or read
|
||||
* events on the socket it manages.
|
||||
*
|
||||
*/
|
||||
class Channel {
|
||||
protected:
|
||||
Channel(const Channel &) = delete;
|
||||
Channel &operator=(const Channel &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Channel(Channel &&) noexcept(true) = default;
|
||||
Channel &operator=(Channel &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
using EventCallback = std::function<void()>;
|
||||
/**
|
||||
* @brief Construct a new Channel instance.
|
||||
*
|
||||
* @param loop The event loop in which the channel works.
|
||||
* @param fd The socket fd.
|
||||
*/
|
||||
Channel(EventLoop *loop, int fd);
|
||||
|
||||
/**
|
||||
* @brief Set the read callback.
|
||||
*
|
||||
* @param cb The callback is called when read event occurs on the socket.
|
||||
* @note One should call the enableReading() method to ensure that the
|
||||
* callback would be called when some data is received on the socket.
|
||||
*/
|
||||
void setReadCallback(const EventCallback &cb) {
|
||||
readCallback_ = cb;
|
||||
};
|
||||
void setReadCallback(EventCallback &&cb) {
|
||||
readCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the write callback.
|
||||
*
|
||||
* @param cb The callback is called when write event occurs on the socket.
|
||||
* @note One should call the enableWriting() method to ensure that the
|
||||
* callback would be called when the socket can be written.
|
||||
*/
|
||||
void setWriteCallback(const EventCallback &cb) {
|
||||
writeCallback_ = cb;
|
||||
};
|
||||
void setWriteCallback(EventCallback &&cb) {
|
||||
writeCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the close callback.
|
||||
*
|
||||
* @param cb The callback is called when the socket is closed.
|
||||
*/
|
||||
void setCloseCallback(const EventCallback &cb) {
|
||||
closeCallback_ = cb;
|
||||
}
|
||||
void setCloseCallback(EventCallback &&cb) {
|
||||
closeCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the error callback.
|
||||
*
|
||||
* @param cb The callback is called when an error occurs on the socket.
|
||||
*/
|
||||
void setErrorCallback(const EventCallback &cb) {
|
||||
errorCallback_ = cb;
|
||||
}
|
||||
void setErrorCallback(EventCallback &&cb) {
|
||||
errorCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the event callback.
|
||||
*
|
||||
* @param cb The callback is called when any event occurs on the socket.
|
||||
* @note If the event callback is set to the channel, any other callback
|
||||
* wouldn't be called again.
|
||||
*/
|
||||
void setEventCallback(const EventCallback &cb) {
|
||||
eventCallback_ = cb;
|
||||
}
|
||||
void setEventCallback(EventCallback &&cb) {
|
||||
eventCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the fd of the socket.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int fd() const {
|
||||
return fd_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the events enabled on the socket.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int events() const {
|
||||
return events_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the events that occurred on the socket.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int revents() const {
|
||||
return revents_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether there is no event enabled on the socket.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isNoneEvent() const {
|
||||
return events_ == kNoneEvent;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Disable all events on the socket.
|
||||
*
|
||||
*/
|
||||
void disableAll() {
|
||||
events_ = kNoneEvent;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove the socket from the poller in the event loop.
|
||||
*
|
||||
*/
|
||||
void remove();
|
||||
|
||||
/**
|
||||
* @brief Return the event loop.
|
||||
*
|
||||
* @return EventLoop*
|
||||
*/
|
||||
EventLoop *ownerLoop() {
|
||||
return loop_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable the read event on the socket.
|
||||
*
|
||||
*/
|
||||
void enableReading() {
|
||||
events_ |= kReadEvent;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the read event on the socket.
|
||||
*
|
||||
*/
|
||||
void disableReading() {
|
||||
events_ &= ~kReadEvent;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the write event on the socket.
|
||||
*
|
||||
*/
|
||||
void enableWriting() {
|
||||
events_ |= kWriteEvent;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the write event on the socket.
|
||||
*
|
||||
*/
|
||||
void disableWriting() {
|
||||
events_ &= ~kWriteEvent;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the write event is enabled on the socket.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isWriting() const {
|
||||
return events_ & kWriteEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the read event is enabled on the socket.
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isReading() const {
|
||||
return events_ & kReadEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set and update the events enabled.
|
||||
*
|
||||
* @param events
|
||||
*/
|
||||
void updateEvents(int events) {
|
||||
events_ = events;
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method is used to ensure that the callback owner is valid
|
||||
* when a callback is called.
|
||||
*
|
||||
* @param obj The callback owner. Usually, the owner is also the owner of
|
||||
* the channel.
|
||||
* @note The 'obj' is kept in a weak_ptr object, so this method does not
|
||||
* cause a circular reference problem.
|
||||
*/
|
||||
void tie(const std::shared_ptr<void> &obj) {
|
||||
tie_ = obj;
|
||||
tied_ = true;
|
||||
}
|
||||
|
||||
static const int kNoneEvent;
|
||||
static const int kReadEvent;
|
||||
static const int kWriteEvent;
|
||||
|
||||
private:
|
||||
friend class EventLoop;
|
||||
friend class EpollPoller;
|
||||
friend class KQueue;
|
||||
void update();
|
||||
void handleEvent();
|
||||
void handleEventSafely();
|
||||
int setRevents(int revt) {
|
||||
// LOG_TRACE<<"revents="<<revt;
|
||||
revents_ = revt;
|
||||
return revt;
|
||||
};
|
||||
int index() {
|
||||
return index_;
|
||||
};
|
||||
void setIndex(int index) {
|
||||
index_ = index;
|
||||
};
|
||||
EventLoop *loop_;
|
||||
const int fd_;
|
||||
int events_;
|
||||
int revents_;
|
||||
int index_;
|
||||
bool addedToLoop_{ false };
|
||||
EventCallback readCallback_;
|
||||
EventCallback writeCallback_;
|
||||
EventCallback errorCallback_;
|
||||
EventCallback closeCallback_;
|
||||
EventCallback eventCallback_;
|
||||
std::weak_ptr<void> tie_;
|
||||
bool tied_;
|
||||
};
|
@ -1,326 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - TcpConnectionImpl.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/timing_wheel.h"
|
||||
#include "core/net/tcp_connection.h"
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <array>
|
||||
#include <thread>
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
|
||||
enum class SSLStatus {
|
||||
Handshaking,
|
||||
Connecting,
|
||||
Connected,
|
||||
DisConnecting,
|
||||
DisConnected
|
||||
};
|
||||
|
||||
class SSLContext;
|
||||
class SSLConn;
|
||||
|
||||
std::shared_ptr<SSLContext> newSSLContext(bool useOldTLS, bool validateCert, const std::vector<std::pair<std::string, std::string> > &sslConfCmds);
|
||||
std::shared_ptr<SSLContext> newSSLServerContext(const std::string &certPath, const std::string &keyPath, bool useOldTLS, const std::vector<std::pair<std::string, std::string> > &sslConfCmds);
|
||||
// void initServerSSLContext(const std::shared_ptr<SSLContext> &ctx, const std::string &certPath, const std::string &keyPath);
|
||||
|
||||
#endif
|
||||
|
||||
class Channel;
|
||||
class Socket;
|
||||
class TcpServer;
|
||||
void removeConnection(EventLoop *loop, const TcpConnectionPtr &conn);
|
||||
|
||||
class TcpConnectionImpl : public TcpConnection, public std::enable_shared_from_this<TcpConnectionImpl> {
|
||||
friend class TcpServer;
|
||||
friend class TcpClient;
|
||||
|
||||
friend void removeConnection(EventLoop *loop, const TcpConnectionPtr &conn);
|
||||
|
||||
protected:
|
||||
TcpConnectionImpl(const TcpConnectionImpl &) = delete;
|
||||
TcpConnectionImpl &operator=(const TcpConnectionImpl &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
TcpConnectionImpl(TcpConnectionImpl &&) noexcept(true) = default;
|
||||
TcpConnectionImpl &operator=(TcpConnectionImpl &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
class KickoffEntry {
|
||||
public:
|
||||
explicit KickoffEntry(const std::weak_ptr<TcpConnection> &conn) :
|
||||
conn_(conn) {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
conn_.reset();
|
||||
}
|
||||
|
||||
~KickoffEntry() {
|
||||
auto conn = conn_.lock();
|
||||
if (conn) {
|
||||
conn->forceClose();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::weak_ptr<TcpConnection> conn_;
|
||||
};
|
||||
|
||||
TcpConnectionImpl(EventLoop *loop, int socketfd, const InetAddress &localAddr, const InetAddress &peerAddr);
|
||||
#ifdef USE_OPENSSL
|
||||
TcpConnectionImpl(EventLoop *loop, int socketfd, const InetAddress &localAddr, const InetAddress &peerAddr, const std::shared_ptr<SSLContext> &ctxPtr, bool isServer = true, bool validateCert = true, const std::string &hostname = "");
|
||||
#endif
|
||||
|
||||
virtual ~TcpConnectionImpl();
|
||||
|
||||
virtual void send(const char *msg, size_t len) override;
|
||||
virtual void send(const void *msg, size_t len) override;
|
||||
virtual void send(const std::string &msg) override;
|
||||
virtual void send(std::string &&msg) override;
|
||||
virtual void send(const MsgBuffer &buffer) override;
|
||||
virtual void send(MsgBuffer &&buffer) override;
|
||||
virtual void send(const std::shared_ptr<std::string> &msgPtr) override;
|
||||
virtual void send(const std::shared_ptr<MsgBuffer> &msgPtr) override;
|
||||
virtual void sendFile(const char *fileName, size_t offset = 0, size_t length = 0) override;
|
||||
|
||||
virtual const InetAddress &localAddr() const override {
|
||||
return localAddr_;
|
||||
}
|
||||
|
||||
virtual const InetAddress &peerAddr() const override {
|
||||
return peerAddr_;
|
||||
}
|
||||
|
||||
virtual bool connected() const override {
|
||||
return status_ == ConnStatus::Connected;
|
||||
}
|
||||
|
||||
virtual bool disconnected() const override {
|
||||
return status_ == ConnStatus::Disconnected;
|
||||
}
|
||||
|
||||
// virtual MsgBuffer* getSendBuffer() override{ return &writeBuffer_;}
|
||||
virtual MsgBuffer *getRecvBuffer() override {
|
||||
return &readBuffer_;
|
||||
}
|
||||
|
||||
// set callbacks
|
||||
virtual void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t markLen) override {
|
||||
highWaterMarkCallback_ = cb;
|
||||
highWaterMarkLen_ = markLen;
|
||||
}
|
||||
|
||||
virtual void keepAlive() override {
|
||||
idleTimeout_ = 0;
|
||||
auto entry = kickoffEntry_.lock();
|
||||
if (entry) {
|
||||
entry->reset();
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool isKeepAlive() override {
|
||||
return idleTimeout_ == 0;
|
||||
}
|
||||
|
||||
virtual void setTcpNoDelay(bool on) override;
|
||||
virtual void shutdown() override;
|
||||
virtual void forceClose() override;
|
||||
|
||||
virtual EventLoop *getLoop() override {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
virtual size_t bytesSent() const override {
|
||||
return bytesSent_;
|
||||
}
|
||||
|
||||
virtual size_t bytesReceived() const override {
|
||||
return bytesReceived_;
|
||||
}
|
||||
|
||||
virtual void startClientEncryption(std::function<void()> callback, bool useOldTLS = false, bool validateCert = true, std::string hostname = "", const std::vector<std::pair<std::string, std::string> > &sslConfCmds = {}) override;
|
||||
virtual void startServerEncryption(const std::shared_ptr<SSLContext> &ctx, std::function<void()> callback) override;
|
||||
virtual bool isSSLConnection() const override {
|
||||
return isEncrypted_;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Internal use only.
|
||||
|
||||
std::weak_ptr<KickoffEntry> kickoffEntry_;
|
||||
std::weak_ptr<TimingWheel> timingWheelWeakPtr_;
|
||||
size_t idleTimeout_{ 0 };
|
||||
Date lastTimingWheelUpdateTime_;
|
||||
|
||||
void enableKickingOff(size_t timeout, const std::shared_ptr<TimingWheel> &timingWheel) {
|
||||
assert(timingWheel);
|
||||
assert(timingWheel->getLoop() == loop_);
|
||||
assert(timeout > 0);
|
||||
auto entry = std::make_shared<KickoffEntry>(shared_from_this());
|
||||
kickoffEntry_ = entry;
|
||||
timingWheelWeakPtr_ = timingWheel;
|
||||
idleTimeout_ = timeout;
|
||||
timingWheel->insertEntry(timeout, entry);
|
||||
}
|
||||
|
||||
void extendLife();
|
||||
#ifndef _WIN32
|
||||
void sendFile(int sfd, size_t offset = 0, size_t length = 0);
|
||||
#else
|
||||
void sendFile(FILE *fp, size_t offset = 0, size_t length = 0);
|
||||
#endif
|
||||
void setRecvMsgCallback(const RecvMessageCallback &cb) {
|
||||
recvMsgCallback_ = cb;
|
||||
}
|
||||
|
||||
void setConnectionCallback(const ConnectionCallback &cb) {
|
||||
connectionCallback_ = cb;
|
||||
}
|
||||
|
||||
void setWriteCompleteCallback(const WriteCompleteCallback &cb) {
|
||||
writeCompleteCallback_ = cb;
|
||||
}
|
||||
|
||||
void setCloseCallback(const CloseCallback &cb) {
|
||||
closeCallback_ = cb;
|
||||
}
|
||||
|
||||
void setSSLErrorCallback(const SSLErrorCallback &cb) {
|
||||
sslErrorCallback_ = cb;
|
||||
}
|
||||
|
||||
void connectDestroyed();
|
||||
virtual void connectEstablished();
|
||||
|
||||
protected:
|
||||
struct BufferNode {
|
||||
#ifndef _WIN32
|
||||
int sendFd_{ -1 };
|
||||
off_t offset_;
|
||||
#else
|
||||
FILE *sendFp_{ nullptr };
|
||||
long long offset_;
|
||||
#endif
|
||||
ssize_t fileBytesToSend_;
|
||||
std::shared_ptr<MsgBuffer> msgBuffer_;
|
||||
|
||||
~BufferNode() {
|
||||
#ifndef _WIN32
|
||||
if (sendFd_ >= 0)
|
||||
close(sendFd_);
|
||||
#else
|
||||
if (sendFp_)
|
||||
fclose(sendFp_);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
using BufferNodePtr = std::shared_ptr<BufferNode>;
|
||||
enum class ConnStatus {
|
||||
Disconnected,
|
||||
Connecting,
|
||||
Connected,
|
||||
Disconnecting
|
||||
};
|
||||
|
||||
bool isEncrypted_{ false };
|
||||
EventLoop *loop_;
|
||||
std::unique_ptr<Channel> ioChannelPtr_;
|
||||
std::unique_ptr<Socket> socketPtr_;
|
||||
MsgBuffer readBuffer_;
|
||||
std::list<BufferNodePtr> writeBufferList_;
|
||||
|
||||
void readCallback();
|
||||
void writeCallback();
|
||||
|
||||
InetAddress localAddr_, peerAddr_;
|
||||
ConnStatus status_{ ConnStatus::Connecting };
|
||||
// callbacks
|
||||
RecvMessageCallback recvMsgCallback_;
|
||||
ConnectionCallback connectionCallback_;
|
||||
CloseCallback closeCallback_;
|
||||
WriteCompleteCallback writeCompleteCallback_;
|
||||
HighWaterMarkCallback highWaterMarkCallback_;
|
||||
SSLErrorCallback sslErrorCallback_;
|
||||
|
||||
void handleClose();
|
||||
void handleError();
|
||||
// virtual void sendInLoop(const std::string &msg);
|
||||
|
||||
void sendFileInLoop(const BufferNodePtr &file);
|
||||
#ifndef _WIN32
|
||||
void sendInLoop(const void *buffer, size_t length);
|
||||
ssize_t writeInLoop(const void *buffer, size_t length);
|
||||
#else
|
||||
void sendInLoop(const char *buffer, size_t length);
|
||||
ssize_t writeInLoop(const char *buffer, size_t length);
|
||||
#endif
|
||||
size_t highWaterMarkLen_;
|
||||
std::string name_;
|
||||
|
||||
uint64_t sendNum_{ 0 };
|
||||
std::mutex sendNumMutex_;
|
||||
|
||||
size_t bytesSent_{ 0 };
|
||||
size_t bytesReceived_{ 0 };
|
||||
|
||||
std::unique_ptr<std::vector<char> > fileBufferPtr_;
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
private:
|
||||
void doHandshaking();
|
||||
bool validatePeerCertificate();
|
||||
|
||||
struct SSLEncryption {
|
||||
SSLStatus statusOfSSL_ = SSLStatus::Handshaking;
|
||||
// OpenSSL
|
||||
std::shared_ptr<SSLContext> sslCtxPtr_;
|
||||
std::unique_ptr<SSLConn> sslPtr_;
|
||||
std::unique_ptr<std::array<char, 8192> > sendBufferPtr_;
|
||||
bool isServer_{ false };
|
||||
bool isUpgrade_{ false };
|
||||
std::function<void()> upgradeCallback_;
|
||||
std::string hostname_;
|
||||
};
|
||||
|
||||
std::unique_ptr<SSLEncryption> sslEncryptionPtr_;
|
||||
|
||||
void startClientEncryptionInLoop(std::function<void()> &&callback, bool useOldTLS, bool validateCert, const std::string &hostname, const std::vector<std::pair<std::string, std::string> > &sslConfCmds);
|
||||
void startServerEncryptionInLoop(const std::shared_ptr<SSLContext> &ctx, std::function<void()> &&callback);
|
||||
#endif
|
||||
};
|
||||
|
||||
using TcpConnectionImplPtr = std::shared_ptr<TcpConnectionImpl>;
|
@ -1,112 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Connector.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
// inherit from socket?
|
||||
// Could be called ClientSocket
|
||||
// New connection callback -> make it a virtual func?
|
||||
|
||||
class Connector : public std::enable_shared_from_this<Connector> {
|
||||
protected:
|
||||
Connector(const Connector &) = delete;
|
||||
Connector &operator=(const Connector &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Connector(Connector &&) noexcept(true) = default;
|
||||
Connector &operator=(Connector &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
using NewConnectionCallback = std::function<void(int sockfd)>;
|
||||
using ConnectionErrorCallback = std::function<void()>;
|
||||
|
||||
Connector(EventLoop *loop, const InetAddress &addr, bool retry = true);
|
||||
Connector(EventLoop *loop, InetAddress &&addr, bool retry = true);
|
||||
|
||||
void setNewConnectionCallback(const NewConnectionCallback &cb) {
|
||||
newConnectionCallback_ = cb;
|
||||
}
|
||||
|
||||
void setNewConnectionCallback(NewConnectionCallback &&cb) {
|
||||
newConnectionCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
void setErrorCallback(const ConnectionErrorCallback &cb) {
|
||||
errorCallback_ = cb;
|
||||
}
|
||||
|
||||
void setErrorCallback(ConnectionErrorCallback &&cb) {
|
||||
errorCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
const InetAddress &serverAddress() const {
|
||||
return serverAddr_;
|
||||
}
|
||||
|
||||
void start();
|
||||
void restart();
|
||||
void stop();
|
||||
|
||||
private:
|
||||
NewConnectionCallback newConnectionCallback_;
|
||||
ConnectionErrorCallback errorCallback_;
|
||||
|
||||
enum class Status {
|
||||
Disconnected,
|
||||
Connecting,
|
||||
Connected
|
||||
};
|
||||
|
||||
static constexpr int kMaxRetryDelayMs = 30 * 1000;
|
||||
static constexpr int kInitRetryDelayMs = 500;
|
||||
std::shared_ptr<Channel> channelPtr_;
|
||||
EventLoop *loop_;
|
||||
InetAddress serverAddr_;
|
||||
|
||||
std::atomic_bool connect_{ false };
|
||||
std::atomic<Status> status_{ Status::Disconnected };
|
||||
|
||||
int retryInterval_{ kInitRetryDelayMs };
|
||||
int maxRetryInterval_{ kMaxRetryDelayMs };
|
||||
|
||||
bool retry_;
|
||||
|
||||
void startInLoop();
|
||||
void connect();
|
||||
void connecting(int sockfd);
|
||||
int removeAndResetChannel();
|
||||
void handleWrite();
|
||||
void handleError();
|
||||
void retry(int sockfd);
|
||||
};
|
@ -1,113 +0,0 @@
|
||||
|
||||
// This file is originally from Moduo -> Trantor - InetAddress.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
// Copyright 2010, Shuo Chen. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef MUDUO_NET_INETADDRESS_H
|
||||
#define MUDUO_NET_INETADDRESS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
using sa_family_t = unsigned short;
|
||||
using in_addr_t = uint32_t;
|
||||
using uint16_t = unsigned short;
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class InetAddress {
|
||||
public:
|
||||
InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false);
|
||||
|
||||
InetAddress(const std::string &ip, uint16_t port, bool ipv6 = false);
|
||||
|
||||
explicit InetAddress(const struct sockaddr_in &addr) :
|
||||
addr_(addr), isUnspecified_(false) {
|
||||
}
|
||||
|
||||
explicit InetAddress(const struct sockaddr_in6 &addr) :
|
||||
addr6_(addr), isIpV6_(true), isUnspecified_(false) {
|
||||
}
|
||||
|
||||
sa_family_t family() const {
|
||||
return addr_.sin_family;
|
||||
}
|
||||
|
||||
std::string toIp() const;
|
||||
std::string toIpPort() const;
|
||||
uint16_t toPort() const;
|
||||
|
||||
bool isIpV6() const {
|
||||
return isIpV6_;
|
||||
}
|
||||
|
||||
bool isIntranetIp() const;
|
||||
bool isLoopbackIp() const;
|
||||
|
||||
const struct sockaddr *getSockAddr() const {
|
||||
return static_cast<const struct sockaddr *>((void *)(&addr6_));
|
||||
}
|
||||
|
||||
void setSockAddrInet6(const struct sockaddr_in6 &addr6) {
|
||||
addr6_ = addr6;
|
||||
isIpV6_ = (addr6_.sin6_family == AF_INET6);
|
||||
isUnspecified_ = false;
|
||||
}
|
||||
|
||||
uint32_t ipNetEndian() const;
|
||||
const uint32_t *ip6NetEndian() const;
|
||||
|
||||
uint16_t portNetEndian() const {
|
||||
return addr_.sin_port;
|
||||
}
|
||||
|
||||
void setPortNetEndian(uint16_t port) {
|
||||
addr_.sin_port = port;
|
||||
}
|
||||
|
||||
inline bool isUnspecified() const {
|
||||
return isUnspecified_;
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
struct sockaddr_in addr_;
|
||||
struct sockaddr_in6 addr6_;
|
||||
};
|
||||
|
||||
bool isIpV6_{ false };
|
||||
bool isUnspecified_{ true };
|
||||
};
|
||||
|
||||
#endif // MUDUO_NET_INETADDRESS_H
|
@ -1,61 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - WindowsSupport.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "windows_support.h"
|
||||
#include <winsock2.h>
|
||||
|
||||
// from polipo
|
||||
int win32_read_socket(int fd, void *buf, int n) {
|
||||
int rc = recv(fd, reinterpret_cast<char *>(buf), n, 0);
|
||||
if (rc == SOCKET_ERROR) {
|
||||
_set_errno(WSAGetLastError());
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int readv(int fd, const struct iovec *vector, int count) {
|
||||
int ret = 0; /* Return value */
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
int n = vector[i].iov_len;
|
||||
int rc = win32_read_socket(fd, vector[i].iov_base, n);
|
||||
if (rc == n) {
|
||||
ret += rc;
|
||||
} else {
|
||||
if (rc < 0) {
|
||||
ret = (ret == 0 ? rc : ret);
|
||||
} else {
|
||||
ret += rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - WindowsSupport.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct iovec
|
||||
{
|
||||
void *iov_base; /* Starting address */
|
||||
int iov_len; /* Number of bytes */
|
||||
};
|
||||
|
||||
int readv(int fd, const struct iovec *vector, int count);
|
@ -1,53 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Resolver.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/inet_address.h"
|
||||
|
||||
//make it a reference
|
||||
|
||||
class Resolver
|
||||
{
|
||||
public:
|
||||
using Callback = std::function<void(const InetAddress&)>;
|
||||
|
||||
static std::shared_ptr<Resolver> newResolver(EventLoop* loop = nullptr, size_t timeout = 60);
|
||||
|
||||
virtual void resolve(const std::string& hostname, const Callback& callback) = 0;
|
||||
|
||||
virtual ~Resolver()
|
||||
{
|
||||
}
|
||||
|
||||
static bool isCAresUsed();
|
||||
};
|
@ -1,163 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - AresResolver.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/event_loop_thread.h"
|
||||
#include "core/net/resolver.h"
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
// Resolver will be a ref
|
||||
|
||||
extern "C" {
|
||||
struct hostent;
|
||||
struct ares_channeldata;
|
||||
using ares_channel = struct ares_channeldata *;
|
||||
}
|
||||
|
||||
class AresResolver : public Resolver, public std::enable_shared_from_this<AresResolver> {
|
||||
protected:
|
||||
AresResolver(const AresResolver &) = delete;
|
||||
AresResolver &operator=(const AresResolver &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
AresResolver(AresResolver &&) noexcept(true) = default;
|
||||
AresResolver &operator=(AresResolver &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
AresResolver(EventLoop *loop, size_t timeout);
|
||||
~AresResolver();
|
||||
|
||||
virtual void resolve(const std::string &hostname, const Callback &cb) override {
|
||||
bool cached = false;
|
||||
|
||||
InetAddress inet;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(globalMutex());
|
||||
auto iter = globalCache().find(hostname);
|
||||
if (iter != globalCache().end()) {
|
||||
auto &cachedAddr = iter->second;
|
||||
if (timeout_ == 0 ||
|
||||
cachedAddr.second.after(timeout_) > Date::date()) {
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 0;
|
||||
addr.sin_addr = cachedAddr.first;
|
||||
inet = InetAddress(addr);
|
||||
cached = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cached) {
|
||||
cb(inet);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loop_->isInLoopThread()) {
|
||||
resolveInLoop(hostname, cb);
|
||||
} else {
|
||||
loop_->queueInLoop([thisPtr = shared_from_this(), hostname, cb]() {
|
||||
thisPtr->resolveInLoop(hostname, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct QueryData {
|
||||
AresResolver *owner_;
|
||||
Callback callback_;
|
||||
std::string hostname_;
|
||||
|
||||
QueryData(AresResolver *o, const Callback &cb, const std::string &hostname) :
|
||||
owner_(o), callback_(cb), hostname_(hostname) {
|
||||
}
|
||||
};
|
||||
|
||||
void resolveInLoop(const std::string &hostname, const Callback &cb);
|
||||
void init();
|
||||
|
||||
EventLoop *loop_;
|
||||
ares_channel ctx_{ nullptr };
|
||||
bool timerActive_{ false };
|
||||
using ChannelList = std::map<int, std::unique_ptr<Channel> >;
|
||||
ChannelList channels_;
|
||||
static std::unordered_map<std::string,
|
||||
std::pair<struct in_addr, Date> > &
|
||||
|
||||
globalCache() {
|
||||
static std::unordered_map<std::string, std::pair<struct in_addr, Date> > dnsCache;
|
||||
return dnsCache;
|
||||
}
|
||||
|
||||
static std::mutex &globalMutex() {
|
||||
static std::mutex mutex_;
|
||||
return mutex_;
|
||||
}
|
||||
|
||||
static EventLoop *getLoop() {
|
||||
static EventLoopThread loopThread;
|
||||
loopThread.run();
|
||||
return loopThread.getLoop();
|
||||
}
|
||||
|
||||
const size_t timeout_{ 60 };
|
||||
|
||||
void onRead(int sockfd);
|
||||
void onTimer();
|
||||
void onQueryResult(int status, struct hostent *result, const std::string &hostname, const Callback &callback);
|
||||
void onSockCreate(int sockfd, int type);
|
||||
void onSockStateChange(int sockfd, bool read, bool write);
|
||||
|
||||
static void ares_hostcallback_(void *data, int status, int timeouts, struct hostent *hostent);
|
||||
|
||||
#ifdef _WIN32
|
||||
static int ares_sock_createcallback_(SOCKET sockfd, int type, void *data);
|
||||
#else
|
||||
static int ares_sock_createcallback_(int sockfd, int type, void *data);
|
||||
#endif
|
||||
static void ares_sock_statecallback_(void *data,
|
||||
#ifdef _WIN32
|
||||
SOCKET sockfd,
|
||||
#else
|
||||
int sockfd,
|
||||
#endif
|
||||
int read,
|
||||
int write);
|
||||
|
||||
struct LibraryInitializer {
|
||||
LibraryInitializer();
|
||||
~LibraryInitializer();
|
||||
};
|
||||
|
||||
static LibraryInitializer libraryInitializer_;
|
||||
};
|
@ -1,80 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - NormalResolver.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
#include "core/containers/concurrent_task_queue.h"
|
||||
#include "core/net/resolver.h"
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
//Resolver will be a ref
|
||||
|
||||
constexpr size_t kResolveBufferLength{ 16 * 1024 };
|
||||
|
||||
class NormalResolver : public Resolver, public std::enable_shared_from_this<NormalResolver> {
|
||||
|
||||
protected:
|
||||
NormalResolver(const NormalResolver &) = delete;
|
||||
NormalResolver &operator=(const NormalResolver &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
NormalResolver(NormalResolver &&) noexcept(true) = default;
|
||||
NormalResolver &operator=(NormalResolver &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
virtual void resolve(const std::string &hostname,
|
||||
const Callback &callback) override;
|
||||
explicit NormalResolver(size_t timeout) :
|
||||
timeout_(timeout), resolveBuffer_(kResolveBufferLength) {
|
||||
}
|
||||
virtual ~NormalResolver() {
|
||||
}
|
||||
|
||||
private:
|
||||
static std::unordered_map<std::string, std::pair<InetAddress, Date> > &globalCache() {
|
||||
static std::unordered_map<std::string, std::pair<InetAddress, Date> > dnsCache_;
|
||||
return dnsCache_;
|
||||
}
|
||||
|
||||
static std::mutex &globalMutex() {
|
||||
static std::mutex mutex_;
|
||||
return mutex_;
|
||||
}
|
||||
|
||||
static ConcurrentTaskQueue &concurrentTaskQueue() {
|
||||
static ConcurrentTaskQueue queue(
|
||||
std::thread::hardware_concurrency() < 8 ? 8 : std::thread::hardware_concurrency(),
|
||||
"Dns Queue");
|
||||
return queue;
|
||||
}
|
||||
|
||||
const size_t timeout_;
|
||||
std::vector<char> resolveBuffer_;
|
||||
};
|
@ -1,166 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Socket.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// TODO Re enable logging
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/log/logger.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include <string>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
class Socket {
|
||||
protected:
|
||||
Socket(const Socket &) = delete;
|
||||
Socket &operator=(const Socket &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Socket(Socket &&) noexcept(true) = default;
|
||||
Socket &operator=(Socket &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
static int createNonblockingSocketOrDie(int family) {
|
||||
#ifdef __linux__
|
||||
int sock = ::socket(family,
|
||||
SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
|
||||
IPPROTO_TCP);
|
||||
#else
|
||||
int sock = static_cast<int>(::socket(family, SOCK_STREAM, IPPROTO_TCP));
|
||||
setNonBlockAndCloseOnExec(sock);
|
||||
#endif
|
||||
if (sock < 0) {
|
||||
LOG_SYSERR << "sockets::createNonblockingOrDie";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LOG_TRACE << "sock=" << sock;
|
||||
return sock;
|
||||
}
|
||||
|
||||
static int getSocketError(int sockfd) {
|
||||
int optval;
|
||||
socklen_t optlen = static_cast<socklen_t>(sizeof optval);
|
||||
#ifdef _WIN32
|
||||
if (::getsockopt(
|
||||
sockfd, SOL_SOCKET, SO_ERROR, (char *)&optval, &optlen) < 0)
|
||||
#else
|
||||
if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0)
|
||||
#endif
|
||||
{
|
||||
return errno;
|
||||
} else {
|
||||
return optval;
|
||||
}
|
||||
}
|
||||
|
||||
static int connect(int sockfd, const InetAddress &addr) {
|
||||
if (addr.isIpV6())
|
||||
return ::connect(sockfd, addr.getSockAddr(), static_cast<socklen_t>(sizeof(struct sockaddr_in6)));
|
||||
else
|
||||
return ::connect(sockfd, addr.getSockAddr(), static_cast<socklen_t>(sizeof(struct sockaddr_in)));
|
||||
}
|
||||
|
||||
static bool isSelfConnect(int sockfd);
|
||||
|
||||
explicit Socket(int sockfd) :
|
||||
sockFd_(sockfd) {
|
||||
}
|
||||
|
||||
~Socket();
|
||||
|
||||
/// abort if address in use
|
||||
void bindAddress(const InetAddress &localaddr);
|
||||
/// abort if address in use
|
||||
void listen();
|
||||
int accept(InetAddress *peeraddr);
|
||||
void closeWrite();
|
||||
int read(char *buffer, uint64_t len);
|
||||
|
||||
int fd() {
|
||||
return sockFd_;
|
||||
}
|
||||
|
||||
static struct sockaddr_in6 getLocalAddr(int sockfd);
|
||||
static struct sockaddr_in6 getPeerAddr(int sockfd);
|
||||
|
||||
///
|
||||
/// Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
|
||||
///
|
||||
void setTcpNoDelay(bool on);
|
||||
|
||||
///
|
||||
/// Enable/disable SO_REUSEADDR
|
||||
///
|
||||
void setReuseAddr(bool on);
|
||||
|
||||
///
|
||||
/// Enable/disable SO_REUSEPORT
|
||||
///
|
||||
void setReusePort(bool on);
|
||||
|
||||
///
|
||||
/// Enable/disable SO_KEEPALIVE
|
||||
///
|
||||
void setKeepAlive(bool on);
|
||||
int getSocketError();
|
||||
|
||||
protected:
|
||||
int sockFd_;
|
||||
|
||||
public:
|
||||
// taken from muduo
|
||||
static void setNonBlockAndCloseOnExec(int sockfd) {
|
||||
#ifdef _WIN32
|
||||
// TODO how to set FD_CLOEXEC on windows? is it necessary?
|
||||
u_long arg = 1;
|
||||
auto ret = ioctlsocket(sockfd, (long)FIONBIO, &arg);
|
||||
if (ret) {
|
||||
LOG_ERROR << "ioctlsocket error";
|
||||
}
|
||||
#else
|
||||
// non-block
|
||||
int flags = ::fcntl(sockfd, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
int ret = ::fcntl(sockfd, F_SETFL, flags);
|
||||
// TODO check
|
||||
|
||||
// close-on-exec
|
||||
flags = ::fcntl(sockfd, F_GETFD, 0);
|
||||
flags |= FD_CLOEXEC;
|
||||
ret = ::fcntl(sockfd, F_SETFD, flags);
|
||||
// TODO check
|
||||
|
||||
(void)ret;
|
||||
#endif
|
||||
}
|
||||
};
|
@ -1,162 +0,0 @@
|
||||
|
||||
// This file is originally from Moduo -> Trantor - TcpClient.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
// Copyright 2010, Shuo Chen. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include "tcp_connection.h"
|
||||
#include <signal.h>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
|
||||
class Connector;
|
||||
using ConnectorPtr = std::shared_ptr<Connector>;
|
||||
class SSLContext;
|
||||
|
||||
//maybe:
|
||||
//Reference -> Socket -> ConnectionListener (Channel?) -> Connector (ClientSocket) -> TcpClient -> HTTP...
|
||||
// -> Acceptor (ServerSocket) -> TcpServer -> HTTPServer
|
||||
//Reference -> TcpConnection (with a connectionlistener member) -> TcpConnectionDefault
|
||||
//Also todo move around the core net classes a bit more
|
||||
|
||||
|
||||
//should be ConnectionListener derived
|
||||
//Inherit from Connector (which Could be called ClientSocket)?
|
||||
|
||||
class TcpClient {
|
||||
protected:
|
||||
TcpClient(const TcpClient &) = delete;
|
||||
TcpClient &operator=(const TcpClient &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
TcpClient(TcpClient &&) noexcept(true) = default;
|
||||
TcpClient &operator=(TcpClient &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
TcpClient(EventLoop *loop, const InetAddress &serverAddr, const std::string &nameArg);
|
||||
~TcpClient();
|
||||
|
||||
void connect();
|
||||
void disconnect();
|
||||
|
||||
void stop();
|
||||
|
||||
TcpConnectionPtr connection() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return connection_;
|
||||
}
|
||||
|
||||
EventLoop *getLoop() const {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
bool retry() const {
|
||||
return retry_;
|
||||
}
|
||||
|
||||
void enableRetry() {
|
||||
retry_ = true;
|
||||
}
|
||||
|
||||
const std::string &name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
void setConnectionCallback(const ConnectionCallback &cb) {
|
||||
connectionCallback_ = cb;
|
||||
}
|
||||
void setConnectionCallback(ConnectionCallback &&cb) {
|
||||
connectionCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
void setConnectionErrorCallback(const ConnectionErrorCallback &cb) {
|
||||
connectionErrorCallback_ = cb;
|
||||
}
|
||||
|
||||
void setMessageCallback(const RecvMessageCallback &cb) {
|
||||
messageCallback_ = cb;
|
||||
}
|
||||
void setMessageCallback(RecvMessageCallback &&cb) {
|
||||
messageCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
/// Not thread safe.
|
||||
void setWriteCompleteCallback(const WriteCompleteCallback &cb) {
|
||||
writeCompleteCallback_ = cb;
|
||||
}
|
||||
void setWriteCompleteCallback(WriteCompleteCallback &&cb) {
|
||||
writeCompleteCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
void setSSLErrorCallback(const SSLErrorCallback &cb) {
|
||||
sslErrorCallback_ = cb;
|
||||
}
|
||||
void setSSLErrorCallback(SSLErrorCallback &&cb) {
|
||||
sslErrorCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
void enableSSL(bool useOldTLS = false, bool validateCert = true, std::string hostname = "", const std::vector<std::pair<std::string, std::string> > &sslConfCmds = {});
|
||||
|
||||
private:
|
||||
/// Not thread safe, but in loop
|
||||
void newConnection(int sockfd);
|
||||
/// Not thread safe, but in loop
|
||||
void removeConnection(const TcpConnectionPtr &conn);
|
||||
|
||||
EventLoop *loop_;
|
||||
ConnectorPtr connector_; // avoid revealing Connector
|
||||
const std::string name_;
|
||||
ConnectionCallback connectionCallback_;
|
||||
ConnectionErrorCallback connectionErrorCallback_;
|
||||
RecvMessageCallback messageCallback_;
|
||||
WriteCompleteCallback writeCompleteCallback_;
|
||||
SSLErrorCallback sslErrorCallback_;
|
||||
std::atomic_bool retry_; // atomic
|
||||
std::atomic_bool connect_; // atomic
|
||||
// always in loop thread
|
||||
mutable std::mutex mutex_;
|
||||
TcpConnectionPtr connection_; // @GuardedBy mutex_
|
||||
std::shared_ptr<SSLContext> sslCtxPtr_;
|
||||
bool validateCert_{ false };
|
||||
std::string SSLHostName_;
|
||||
|
||||
#ifndef _WIN32
|
||||
class IgnoreSigPipe {
|
||||
public:
|
||||
IgnoreSigPipe() {
|
||||
::signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
};
|
||||
|
||||
static IgnoreSigPipe initObj;
|
||||
#endif
|
||||
};
|
@ -1,121 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - TcpConnection.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include "core/net/callbacks.h"
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
// add new class TcpConnectionListener or ConnectionListener
|
||||
//set_listener(ConnectionListener)
|
||||
// instead of callbacks
|
||||
|
||||
class SSLContext;
|
||||
std::shared_ptr<SSLContext> newSSLServerContext(const std::string &certPath, const std::string &keyPath, bool useOldTLS = false, const std::vector<std::pair<std::string, std::string> > &sslConfCmds = {});
|
||||
|
||||
class TcpConnection {
|
||||
public:
|
||||
TcpConnection() = default;
|
||||
virtual ~TcpConnection(){};
|
||||
|
||||
virtual void send(const char *msg, size_t len) = 0;
|
||||
virtual void send(const void *msg, size_t len) = 0;
|
||||
virtual void send(const std::string &msg) = 0;
|
||||
virtual void send(std::string &&msg) = 0;
|
||||
virtual void send(const MsgBuffer &buffer) = 0;
|
||||
virtual void send(MsgBuffer &&buffer) = 0;
|
||||
virtual void send(const std::shared_ptr<std::string> &msgPtr) = 0;
|
||||
virtual void send(const std::shared_ptr<MsgBuffer> &msgPtr) = 0;
|
||||
|
||||
virtual void sendFile(const char *fileName, size_t offset = 0, size_t length = 0) = 0;
|
||||
|
||||
virtual const InetAddress &localAddr() const = 0;
|
||||
virtual const InetAddress &peerAddr() const = 0;
|
||||
|
||||
virtual bool connected() const = 0;
|
||||
virtual bool disconnected() const = 0;
|
||||
|
||||
virtual MsgBuffer *getRecvBuffer() = 0;
|
||||
|
||||
|
||||
virtual void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t markLen) = 0;
|
||||
|
||||
virtual void setTcpNoDelay(bool on) = 0;
|
||||
|
||||
virtual void shutdown() = 0;
|
||||
virtual void forceClose() = 0;
|
||||
|
||||
|
||||
virtual EventLoop *getLoop() = 0;
|
||||
|
||||
void setContext(const std::shared_ptr<void> &context) {
|
||||
contextPtr_ = context;
|
||||
}
|
||||
void setContext(std::shared_ptr<void> &&context) {
|
||||
contextPtr_ = std::move(context);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> getContext() const {
|
||||
return std::static_pointer_cast<T>(contextPtr_);
|
||||
}
|
||||
|
||||
bool hasContext() const {
|
||||
return (bool)contextPtr_;
|
||||
}
|
||||
|
||||
void clearContext() {
|
||||
contextPtr_.reset();
|
||||
}
|
||||
|
||||
virtual void keepAlive() = 0;
|
||||
virtual bool isKeepAlive() = 0;
|
||||
|
||||
virtual size_t bytesSent() const = 0;
|
||||
virtual size_t bytesReceived() const = 0;
|
||||
|
||||
virtual bool isSSLConnection() const = 0;
|
||||
|
||||
virtual void startClientEncryption(std::function<void()> callback, bool useOldTLS = false, bool validateCert = true, std::string hostname = "", const std::vector<std::pair<std::string, std::string> > &sslConfCmds = {}) = 0;
|
||||
|
||||
virtual void startServerEncryption(const std::shared_ptr<SSLContext> &ctx, std::function<void()> callback) = 0;
|
||||
|
||||
protected:
|
||||
bool validateCert_ = false;
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> contextPtr_;
|
||||
};
|
||||
|
@ -1,161 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - TcpServer.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/log/logger.h"
|
||||
#include "core/net/callbacks.h"
|
||||
#include "core/loops/event_loop_thread_pool.h"
|
||||
#include "core/loops/timing_wheel.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include "core/net/tcp_connection.h"
|
||||
#include <signal.h>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
class Acceptor;
|
||||
class SSLContext;
|
||||
|
||||
//Inherit from Acceptor (-> Could be called ServerSocket)?
|
||||
|
||||
class TcpServer {
|
||||
protected:
|
||||
TcpServer(const TcpServer &) = delete;
|
||||
TcpServer &operator=(const TcpServer &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
TcpServer(TcpServer &&) noexcept(true) = default;
|
||||
TcpServer &operator=(TcpServer &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
TcpServer(EventLoop *loop, const InetAddress &address, const std::string &name, bool reUseAddr = true, bool reUsePort = true);
|
||||
~TcpServer();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void setIoLoopNum(size_t num) {
|
||||
assert(!started_);
|
||||
loopPoolPtr_ = std::make_shared<EventLoopThreadPool>(num);
|
||||
loopPoolPtr_->start();
|
||||
}
|
||||
|
||||
void setIoLoopThreadPool(const std::shared_ptr<EventLoopThreadPool> &pool) {
|
||||
assert(pool->size() > 0);
|
||||
assert(!started_);
|
||||
loopPoolPtr_ = pool;
|
||||
loopPoolPtr_->start();
|
||||
}
|
||||
|
||||
void setRecvMessageCallback(const RecvMessageCallback &cb) {
|
||||
recvMessageCallback_ = cb;
|
||||
}
|
||||
void setRecvMessageCallback(RecvMessageCallback &&cb) {
|
||||
recvMessageCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
void setConnectionCallback(const ConnectionCallback &cb) {
|
||||
connectionCallback_ = cb;
|
||||
}
|
||||
void setConnectionCallback(ConnectionCallback &&cb) {
|
||||
connectionCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
void setWriteCompleteCallback(const WriteCompleteCallback &cb) {
|
||||
writeCompleteCallback_ = cb;
|
||||
}
|
||||
void setWriteCompleteCallback(WriteCompleteCallback &&cb) {
|
||||
writeCompleteCallback_ = std::move(cb);
|
||||
}
|
||||
|
||||
const std::string &name() const {
|
||||
return serverName_;
|
||||
}
|
||||
|
||||
const std::string ipPort() const;
|
||||
const InetAddress &address() const;
|
||||
|
||||
EventLoop *getLoop() const {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
std::vector<EventLoop *> getIoLoops() const {
|
||||
return loopPoolPtr_->getLoops();
|
||||
}
|
||||
|
||||
void kickoffIdleConnections(size_t timeout) {
|
||||
loop_->runInLoop([this, timeout]() {
|
||||
assert(!started_);
|
||||
idleTimeout_ = timeout;
|
||||
});
|
||||
}
|
||||
|
||||
// certPath The path of the certificate file.
|
||||
// keyPath The path of the private key file.
|
||||
// useOldTLS If true, the TLS 1.0 and 1.1 are supported by the server.
|
||||
// sslConfCmds The commands used to call the SSL_CONF_cmd function in OpenSSL.
|
||||
// Note: It's well known that TLS 1.0 and 1.1 are not considered secure in 2020. And it's a good practice to only use TLS 1.2 and above.
|
||||
void enableSSL(const std::string &certPath, const std::string &keyPath, bool useOldTLS = false, const std::vector<std::pair<std::string, std::string> > &sslConfCmds = {});
|
||||
|
||||
private:
|
||||
EventLoop *loop_;
|
||||
std::unique_ptr<Acceptor> acceptorPtr_;
|
||||
|
||||
void newConnection(int fd, const InetAddress &peer);
|
||||
|
||||
std::string serverName_;
|
||||
std::set<TcpConnectionPtr> connSet_;
|
||||
|
||||
RecvMessageCallback recvMessageCallback_;
|
||||
ConnectionCallback connectionCallback_;
|
||||
WriteCompleteCallback writeCompleteCallback_;
|
||||
|
||||
size_t idleTimeout_{ 0 };
|
||||
std::map<EventLoop *, std::shared_ptr<TimingWheel> > timingWheelMap_;
|
||||
void connectionClosed(const TcpConnectionPtr &connectionPtr);
|
||||
std::shared_ptr<EventLoopThreadPool> loopPoolPtr_;
|
||||
|
||||
#ifndef _WIN32
|
||||
class IgnoreSigPipe {
|
||||
public:
|
||||
IgnoreSigPipe() {
|
||||
::signal(SIGPIPE, SIG_IGN);
|
||||
LOG_TRACE << "Ignore SIGPIPE";
|
||||
}
|
||||
};
|
||||
|
||||
IgnoreSigPipe initObj;
|
||||
#endif
|
||||
|
||||
bool started_{ false };
|
||||
|
||||
// OpenSSL SSL context Object;
|
||||
std::shared_ptr<SSLContext> sslCtxPtr_;
|
||||
};
|
@ -1,49 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Poller.cc
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "poller.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include "poller/epoll_poller.h"
|
||||
#elif defined _WIN32
|
||||
#include "Wepoll.h"
|
||||
#include "poller/epoll_poller.h"
|
||||
#else
|
||||
#include "poller/kqueue.h"
|
||||
#endif
|
||||
|
||||
|
||||
Poller *Poller::newPoller(EventLoop *loop) {
|
||||
#if defined __linux__ || defined _WIN32
|
||||
return new EpollPoller(loop);
|
||||
#else
|
||||
return new KQueue(loop);
|
||||
#endif
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - Poller.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/event_loop.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
class Channel;
|
||||
#ifdef _WIN32
|
||||
using EventCallback = std::function<void(uint64_t)>;
|
||||
#endif
|
||||
class Poller {
|
||||
protected:
|
||||
Poller(const Poller &) = delete;
|
||||
Poller &operator=(const Poller &) = delete;
|
||||
// some uncopyable classes maybe support move constructor....
|
||||
Poller(Poller &&) noexcept(true) = default;
|
||||
Poller &operator=(Poller &&) noexcept(true) = default;
|
||||
|
||||
public:
|
||||
explicit Poller(EventLoop *loop) :
|
||||
ownerLoop_(loop){};
|
||||
virtual ~Poller() {
|
||||
}
|
||||
void assertInLoopThread() {
|
||||
ownerLoop_->assertInLoopThread();
|
||||
}
|
||||
virtual void poll(int timeoutMs, ChannelList *activeChannels) = 0;
|
||||
virtual void updateChannel(Channel *channel) = 0;
|
||||
virtual void removeChannel(Channel *channel) = 0;
|
||||
#ifdef _WIN32
|
||||
virtual void postEvent(uint64_t event) = 0;
|
||||
virtual void setEventCallback(const EventCallback &cb) = 0;
|
||||
#endif
|
||||
virtual void resetAfterFork() {
|
||||
}
|
||||
static Poller *newPoller(EventLoop *loop);
|
||||
|
||||
private:
|
||||
EventLoop *ownerLoop_;
|
||||
};
|
@ -1,75 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - EpollPoller.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/polling/poller.h"
|
||||
|
||||
#if defined __linux__ || defined _WIN32
|
||||
#include <map>
|
||||
#include <memory>
|
||||
using EventList = std::vector<struct epoll_event>;
|
||||
#endif
|
||||
|
||||
class Channel;
|
||||
|
||||
class EpollPoller : public Poller {
|
||||
public:
|
||||
explicit EpollPoller(EventLoop *loop);
|
||||
virtual ~EpollPoller();
|
||||
virtual void poll(int timeoutMs, ChannelList *activeChannels) override;
|
||||
virtual void updateChannel(Channel *channel) override;
|
||||
virtual void removeChannel(Channel *channel) override;
|
||||
#ifdef _WIN32
|
||||
virtual void postEvent(uint64_t event) override;
|
||||
virtual void setEventCallback(const EventCallback &cb) override {
|
||||
eventCallback_ = cb;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined __linux__ || defined _WIN32
|
||||
static const int kInitEventListSize = 16;
|
||||
#ifdef _WIN32
|
||||
void *epollfd_;
|
||||
EventCallback eventCallback_{ [](uint64_t event) {} };
|
||||
#else
|
||||
int epollfd_;
|
||||
#endif
|
||||
EventList events_;
|
||||
void update(int operation, Channel *channel);
|
||||
#ifndef NDEBUG
|
||||
using ChannelMap = std::map<int, Channel *>;
|
||||
ChannelMap channels_;
|
||||
#endif
|
||||
void fillActiveChannels(int numEvents, ChannelList *activeChannels) const;
|
||||
#endif
|
||||
};
|
@ -1,66 +0,0 @@
|
||||
|
||||
// This file is originally from Trantor - KQueue.h
|
||||
|
||||
// Copyright (c) 2016-2021, Tao An. All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Tao An nor the names of other contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/polling/poller.h"
|
||||
|
||||
#if (defined(__unix__) && !defined(__linux__)) || \
|
||||
(defined(__APPLE__) && defined(__MACH__))
|
||||
#define USE_KQUEUE
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
using EventList = std::vector<struct kevent>;
|
||||
#endif
|
||||
|
||||
class Channel;
|
||||
|
||||
class KQueue : public Poller {
|
||||
public:
|
||||
explicit KQueue(EventLoop *loop);
|
||||
virtual ~KQueue();
|
||||
virtual void poll(int timeoutMs, ChannelList *activeChannels) override;
|
||||
virtual void updateChannel(Channel *channel) override;
|
||||
virtual void removeChannel(Channel *channel) override;
|
||||
virtual void resetAfterFork() override;
|
||||
|
||||
private:
|
||||
#ifdef USE_KQUEUE
|
||||
static const int kInitEventListSize = 16;
|
||||
int kqfd_;
|
||||
EventList events_;
|
||||
using ChannelMap = std::unordered_map<int, std::pair<int, Channel *> >;
|
||||
ChannelMap channels_;
|
||||
|
||||
void fillActiveChannels(int numEvents, ChannelList *activeChannels) const;
|
||||
void update(Channel *channel);
|
||||
#endif
|
||||
};
|
@ -10,25 +10,6 @@
|
||||
|
||||
class Utilities {
|
||||
public:
|
||||
// Taken from trantor (MIT License) - Funcs.h
|
||||
// Copyright (c) 2018 An Tao
|
||||
static _ALWAYS_INLINE_ std::vector<std::string> splitString(const std::string &s,
|
||||
const std::string &delimiter,
|
||||
bool acceptEmptyString = false) {
|
||||
if (delimiter.empty())
|
||||
return std::vector<std::string>{};
|
||||
std::vector<std::string> v;
|
||||
size_t last = 0;
|
||||
size_t next = 0;
|
||||
while ((next = s.find(delimiter, last)) != std::string::npos) {
|
||||
if (next > last || acceptEmptyString)
|
||||
v.push_back(s.substr(last, next - last));
|
||||
last = next + delimiter.length();
|
||||
}
|
||||
if (s.length() > last || acceptEmptyString)
|
||||
v.push_back(s.substr(last));
|
||||
return v;
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
@ -10,6 +10,19 @@ env_mod.add_source_files(env_mod.core_sources, "drogon/lib/src/*.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/inc/http/*.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "drogon/lib/src/ssl_funcs/*.cc")
|
||||
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/net/*.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/net/inner/*.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/net/inner/poller/*.cc")
|
||||
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/AsyncFileLogger.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/ConcurrentTaskQueue.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/Date.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/Logger.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/LogStream.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/MsgBuffer.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/SerialTaskQueue.cc")
|
||||
env_mod.add_source_files(env_mod.core_sources, "trantor/utils/TimingWheel.cc")
|
||||
|
||||
# Build it all as a library
|
||||
lib = env_mod.add_library("drogon", env_mod.core_sources)
|
||||
env.Prepend(LIBS=[lib])
|
||||
|
@ -79,6 +79,8 @@ def configure(env):
|
||||
env.Append(CPPPATH=["#web_backends/drogon"])
|
||||
|
||||
env.Append(CPPPATH=["#web_backends/drogon/trantor"])
|
||||
env.Append(CPPPATH=["#web_backends/drogon/trantor/net"])
|
||||
env.Append(CPPPATH=["#web_backends/drogon/trantor/net/inner"])
|
||||
env.Append(CPPPATH=["#web_backends/drogon/trantor/utils"])
|
||||
|
||||
env.Append(LINKFLAGS=["-ldl"])
|
||||
|
@ -51,7 +51,7 @@ using namespace drogon;
|
||||
int main()
|
||||
{
|
||||
app().setLogPath("./")
|
||||
.setLogLevel(Logger::kWarn)
|
||||
.setLogLevel(trantor::Logger::kWarn)
|
||||
.addListener("0.0.0.0", 80)
|
||||
.setThreadNum(16)
|
||||
.enableRunAsDaemon()
|
||||
|
@ -4,7 +4,7 @@ using namespace drogon;
|
||||
int main() {
|
||||
app()
|
||||
.setLogPath("./")
|
||||
.setLogLevel(Logger::kWarn)
|
||||
.setLogLevel(trantor::Logger::kWarn)
|
||||
.addListener("0.0.0.0", 7770)
|
||||
.setThreadNum(0)
|
||||
.registerSyncAdvice([](const HttpRequestPtr &req) -> HttpResponsePtr {
|
||||
|
@ -7,7 +7,7 @@ using namespace drogon;
|
||||
int nth_resp = 0;
|
||||
|
||||
int main() {
|
||||
Logger::setLogLevel(Logger::kTrace);
|
||||
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
|
||||
{
|
||||
auto client = HttpClient::newHttpClient("http://www.baidu.com");
|
||||
auto req = HttpRequest::newHttpRequest();
|
||||
|
@ -64,7 +64,7 @@ void SimpleReverseProxy::preRouting(const HttpRequestPtr &req,
|
||||
if (!clientPtr) {
|
||||
auto &addr = backendAddrs_[index % backendAddrs_.size()];
|
||||
clientPtr = HttpClient::newHttpClient(
|
||||
addr, EventLoop::getEventLoopOfCurrentThread());
|
||||
addr, trantor::EventLoop::getEventLoopOfCurrentThread());
|
||||
clientPtr->setPipeliningDepth(pipeliningDepth_);
|
||||
}
|
||||
req->setPassThrough(true);
|
||||
|
@ -68,7 +68,7 @@ int main(int argc, char *argv[]) {
|
||||
// Quit the application after 15 seconds
|
||||
app().getLoop()->runAfter(15, []() { app().quit(); });
|
||||
|
||||
app().setLogLevel(Logger::kDebug);
|
||||
app().setLogLevel(trantor::Logger::kDebug);
|
||||
app().run();
|
||||
LOG_INFO << "bye!";
|
||||
return 0;
|
||||
|
@ -25,8 +25,8 @@
|
||||
#include <drogon/plugins/Plugin.h>
|
||||
#include <drogon/utils/HttpConstraint.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/resolver.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/Resolver.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
@ -59,7 +59,7 @@ using DefaultHandler =
|
||||
std::function<void(const HttpRequestPtr &,
|
||||
std::function<void(const HttpResponsePtr &)> &&)>;
|
||||
|
||||
class HttpAppFramework : public NonCopyable {
|
||||
class HttpAppFramework : public trantor::NonCopyable {
|
||||
public:
|
||||
virtual ~HttpAppFramework() = default;
|
||||
/// Get the instance of HttpAppFramework
|
||||
@ -104,7 +104,7 @@ public:
|
||||
* User can run some timer tasks or other tasks in this loop;
|
||||
* This method can be call in any thread.
|
||||
*/
|
||||
virtual EventLoop *getLoop() const = 0;
|
||||
virtual trantor::EventLoop *getLoop() const = 0;
|
||||
|
||||
/// Get an IO loop with id. E.g. 0 <= id < #Total thread-loops
|
||||
/**
|
||||
@ -114,7 +114,7 @@ public:
|
||||
* REMARKS : Function assumed the number of threads will not exceed 2^32.
|
||||
* Change to long long for alien computers.
|
||||
*/
|
||||
virtual EventLoop *getIOLoop(size_t id) const = 0;
|
||||
virtual trantor::EventLoop *getIOLoop(size_t id) const = 0;
|
||||
|
||||
/// Set custom 404 page
|
||||
/**
|
||||
@ -191,8 +191,8 @@ public:
|
||||
* Users can use this advice to implement some security policies.
|
||||
*/
|
||||
virtual HttpAppFramework ®isterNewConnectionAdvice(
|
||||
const std::function<bool(const InetAddress &,
|
||||
const InetAddress &)> &advice) = 0;
|
||||
const std::function<bool(const trantor::InetAddress &,
|
||||
const trantor::InetAddress &)> &advice) = 0;
|
||||
|
||||
/**
|
||||
* @brief Register an advice for new HTTP responses.
|
||||
@ -878,7 +878,7 @@ public:
|
||||
* @note
|
||||
* This operation can be performed by an option in the configuration file.
|
||||
*/
|
||||
virtual HttpAppFramework &setLogLevel(Logger::LogLevel level) = 0;
|
||||
virtual HttpAppFramework &setLogLevel(trantor::Logger::LogLevel level) = 0;
|
||||
|
||||
/// Enable the sendfile system call in linux.
|
||||
/**
|
||||
@ -1179,7 +1179,7 @@ public:
|
||||
* When the c-ares library is installed in the system, it runs with the best
|
||||
* performance.
|
||||
*/
|
||||
virtual const std::shared_ptr<Resolver> &getResolver() const = 0;
|
||||
virtual const std::shared_ptr<trantor::Resolver> &getResolver() const = 0;
|
||||
|
||||
/// Return true is drogon supports SSL(https)
|
||||
virtual bool supportSSL() const = 0;
|
||||
@ -1204,11 +1204,11 @@ public:
|
||||
/**
|
||||
* @brief Get the addresses of listeners.
|
||||
*
|
||||
* @return std::vector<InetAddress>
|
||||
* @return std::vector<trantor::InetAddress>
|
||||
* @note This method should be called after calling the app().run(). One
|
||||
* could run this method in an AOP join point (such as the BeginningAdvice).
|
||||
*/
|
||||
virtual std::vector<InetAddress> getListeners() const = 0;
|
||||
virtual std::vector<trantor::InetAddress> getListeners() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Enable ReusePort mode or not. If the mode is enabled, one can run
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <http/HttpTypes.h>
|
||||
#include <drogon/drogon_callbacks.h>
|
||||
|
||||
#include "core/loops/event_loop.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
@ -42,7 +42,7 @@ using HttpClientPtr = std::shared_ptr<HttpClient>;
|
||||
* response callbacks are invoked without fear of accidental deconstruction.
|
||||
*
|
||||
*/
|
||||
class HttpClient : public NonCopyable {
|
||||
class HttpClient : public trantor::NonCopyable {
|
||||
public:
|
||||
/**
|
||||
* @brief Send a request asynchronously to the server
|
||||
@ -178,12 +178,12 @@ public:
|
||||
static HttpClientPtr newHttpClient(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL = false,
|
||||
EventLoop *loop = nullptr,
|
||||
trantor::EventLoop *loop = nullptr,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
|
||||
/// Get the event loop of the client;
|
||||
virtual EventLoop *getLoop() = 0;
|
||||
virtual trantor::EventLoop *getLoop() = 0;
|
||||
|
||||
/// Get the number of bytes sent or received
|
||||
virtual size_t bytesSent() const = 0;
|
||||
@ -221,7 +221,7 @@ public:
|
||||
*
|
||||
*/
|
||||
static HttpClientPtr newHttpClient(const std::string &hostString,
|
||||
EventLoop *loop = nullptr,
|
||||
trantor::EventLoop *loop = nullptr,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "core/log/logger.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
@ -56,7 +56,7 @@ namespace drogon {
|
||||
* @endcode
|
||||
*/
|
||||
template <typename C>
|
||||
class IOThreadStorage : public NonCopyable {
|
||||
class IOThreadStorage : public trantor::NonCopyable {
|
||||
public:
|
||||
using ValueType = C;
|
||||
using InitCallback = std::function<void(ValueType &, size_t)>;
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <http/HttpResponse.h>
|
||||
#include <http/HttpTypes.h>
|
||||
#include <drogon/WebSocketConnection.h>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -66,7 +66,7 @@ public:
|
||||
const WebSocketRequestCallback &callback) = 0;
|
||||
|
||||
/// Get the event loop of the client;
|
||||
virtual EventLoop *getLoop() = 0;
|
||||
virtual trantor::EventLoop *getLoop() = 0;
|
||||
|
||||
/**
|
||||
* @brief Create a websocket client using the given ip and port to connect
|
||||
@ -91,7 +91,7 @@ public:
|
||||
const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL = false,
|
||||
EventLoop *loop = nullptr,
|
||||
trantor::EventLoop *loop = nullptr,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
|
||||
@ -121,7 +121,7 @@ public:
|
||||
*/
|
||||
static WebSocketClientPtr newWebSocketClient(
|
||||
const std::string &hostString,
|
||||
EventLoop *loop = nullptr,
|
||||
trantor::EventLoop *loop = nullptr,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <http/HttpTypes.h>
|
||||
#include "core/net/inet_address.h"
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -111,10 +111,10 @@ public:
|
||||
const WebSocketMessageType type = WebSocketMessageType::Text) = 0;
|
||||
|
||||
/// Return the local IP address and port number of the connection
|
||||
virtual const InetAddress &localAddr() const = 0;
|
||||
virtual const trantor::InetAddress &localAddr() const = 0;
|
||||
|
||||
/// Return the remote IP address and port number of the connection
|
||||
virtual const InetAddress &peerAddr() const = 0;
|
||||
virtual const trantor::InetAddress &peerAddr() const = 0;
|
||||
|
||||
/// Return true if the connection is open
|
||||
virtual bool connected() const = 0;
|
||||
|
@ -14,10 +14,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include "core/math/date.h"
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
|
||||
#include <http/CacheMap.h>
|
||||
#include <http/Cookie.h>
|
||||
|
@ -318,7 +318,7 @@ inline ThreadSafeStream printErr() {
|
||||
return ThreadSafeStream(std::cerr);
|
||||
}
|
||||
|
||||
class CaseBase : public NonCopyable {
|
||||
class CaseBase : public trantor::NonCopyable {
|
||||
public:
|
||||
CaseBase() = default;
|
||||
CaseBase(const std::string &name) :
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <http/HttpRequest.h>
|
||||
#include <http/HttpResponse.h>
|
||||
#include <drogon/plugins/Plugin.h>
|
||||
#include "core/log/async_file_logger.h"
|
||||
#include <trantor/utils/AsyncFileLogger.h>
|
||||
#include <vector>
|
||||
|
||||
namespace drogon {
|
||||
@ -84,89 +84,89 @@ public:
|
||||
void shutdown() override;
|
||||
|
||||
private:
|
||||
AsyncFileLogger asyncFileLogger_;
|
||||
trantor::AsyncFileLogger asyncFileLogger_;
|
||||
int logIndex_{ 0 };
|
||||
bool useLocalTime_{ true };
|
||||
using LogFunction = std::function<void(LogStream &,
|
||||
using LogFunction = std::function<void(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &)>;
|
||||
std::vector<LogFunction> logFunctions_;
|
||||
void logging(LogStream &stream,
|
||||
void logging(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &resp);
|
||||
void createLogFunctions(std::string format);
|
||||
LogFunction newLogFunction(const std::string &placeholder);
|
||||
std::map<std::string, LogFunction> logFunctionMap_;
|
||||
//$request_path
|
||||
static void outputReqPath(LogStream &,
|
||||
static void outputReqPath(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$request_query
|
||||
static void outputReqQuery(LogStream &,
|
||||
static void outputReqQuery(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$request_url
|
||||
static void outputReqURL(LogStream &,
|
||||
static void outputReqURL(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$date
|
||||
void outputDate(LogStream &,
|
||||
void outputDate(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) const;
|
||||
//$request_date
|
||||
void outputReqDate(LogStream &,
|
||||
void outputReqDate(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) const;
|
||||
//$remote_addr
|
||||
static void outputRemoteAddr(LogStream &,
|
||||
static void outputRemoteAddr(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$local_addr
|
||||
static void outputLocalAddr(LogStream &,
|
||||
static void outputLocalAddr(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$request_len $body_bytes_received
|
||||
static void outputReqLength(LogStream &,
|
||||
static void outputReqLength(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$response_len $body_bytes_sent
|
||||
static void outputRespLength(LogStream &,
|
||||
static void outputRespLength(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$method
|
||||
static void outputMethod(LogStream &,
|
||||
static void outputMethod(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$thread
|
||||
static void outputThreadNumber(LogStream &,
|
||||
static void outputThreadNumber(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$http_[header_name]
|
||||
static void outputReqHeader(LogStream &stream,
|
||||
static void outputReqHeader(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const std::string &headerName);
|
||||
//$cookie_[cookie_name]
|
||||
static void outputReqCookie(LogStream &stream,
|
||||
static void outputReqCookie(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const std::string &cookie);
|
||||
//$upstream_http_[header_name]
|
||||
static void outputRespHeader(LogStream &stream,
|
||||
static void outputRespHeader(trantor::LogStream &stream,
|
||||
const drogon::HttpResponsePtr &resp,
|
||||
const std::string &headerName);
|
||||
//$status
|
||||
static void outputStatusString(LogStream &,
|
||||
static void outputStatusString(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$status_code
|
||||
static void outputStatusCode(LogStream &,
|
||||
static void outputStatusCode(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$processing_time
|
||||
static void outputProcessingTime(LogStream &,
|
||||
static void outputProcessingTime(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
//$upstream_http_content-type $upstream_http_content_type
|
||||
static void outputRespContentType(LogStream &,
|
||||
static void outputRespContentType(trantor::LogStream &,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &);
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <memory>
|
||||
|
||||
@ -29,7 +29,7 @@ enum class PluginStatus {
|
||||
* @brief The abstract base class for plugins.
|
||||
*
|
||||
*/
|
||||
class PluginBase : public NonCopyable {
|
||||
class PluginBase : public trantor::NonCopyable {
|
||||
public:
|
||||
/// This method must be called by drogon.
|
||||
void initialize() {
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include "core/math/date.h"
|
||||
#include "core/utilities.h"
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <trantor/utils/Funcs.h>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@ -60,7 +60,7 @@ std::vector<char> hexToBinaryVector(const char *ptr,
|
||||
inline std::vector<std::string> splitString(const std::string &str,
|
||||
const std::string &separator,
|
||||
bool acceptEmptyString = false) {
|
||||
return Utilities::splitString(str, separator, acceptEmptyString);
|
||||
return trantor::splitString(str, separator, acceptEmptyString);
|
||||
}
|
||||
|
||||
std::set<std::string> splitStringToSet(
|
||||
@ -131,13 +131,13 @@ std::string brotliDecompress(const char *data,
|
||||
@endcode
|
||||
*/
|
||||
char *getHttpFullDate(
|
||||
const Date &date = Date::now());
|
||||
const trantor::Date &date = trantor::Date::now());
|
||||
|
||||
/// Get the Date object according to the http full date string
|
||||
/// Get the trantor::Date object according to the http full date string
|
||||
/**
|
||||
* Returns Date(std::numeric_limits<int64_t>::max()) upon failure.
|
||||
* Returns trantor::Date(std::numeric_limits<int64_t>::max()) upon failure.
|
||||
*/
|
||||
Date getHttpDate(const std::string &httpFullDateString);
|
||||
trantor::Date getHttpDate(const std::string &httpFullDateString);
|
||||
|
||||
/// Get a formatted string
|
||||
std::string formattedString(const char *format, ...);
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#endif
|
||||
|
||||
#include "core/log/log_stream.h"
|
||||
#include <trantor/utils/LogStream.h>
|
||||
|
||||
namespace drogon {
|
||||
#if __cplusplus >= 201703L || (defined _MSC_VER && _MSC_VER > 1900)
|
||||
@ -29,11 +29,12 @@ using std::string_view;
|
||||
using boost::string_view;
|
||||
#endif
|
||||
} // namespace drogon
|
||||
|
||||
namespace trantor {
|
||||
inline LogStream &operator<<(LogStream &ls, const drogon::string_view &v) {
|
||||
ls.append(v.data(), v.length());
|
||||
return ls;
|
||||
}
|
||||
} // namespace trantor
|
||||
|
||||
#if __cplusplus < 201703L && !(defined _MSC_VER && _MSC_VER > 1900)
|
||||
namespace std {
|
||||
|
@ -15,7 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <drogon/utils/any.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "CacheFile.h"
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#ifdef _WIN32
|
||||
#include <mman.h>
|
||||
#else
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace drogon {
|
||||
class CacheFile : public NonCopyable {
|
||||
class CacheFile : public trantor::NonCopyable {
|
||||
public:
|
||||
explicit CacheFile(const std::string &path, bool autoDelete = true);
|
||||
~CacheFile();
|
||||
|
@ -15,8 +15,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
#include <future>
|
||||
@ -79,7 +79,7 @@ public:
|
||||
* The max delay of the CacheMap is about
|
||||
* tickInterval*(bucketsNumPerWheel^wheelsNum) seconds.
|
||||
*/
|
||||
CacheMap(EventLoop *loop,
|
||||
CacheMap(trantor::EventLoop *loop,
|
||||
float tickInterval = TICK_INTERVAL,
|
||||
size_t wheelsNum = WHEELS_NUM,
|
||||
size_t bucketsNumPerWheel = BUCKET_NUM_PER_WHEEL) :
|
||||
@ -134,7 +134,7 @@ public:
|
||||
for (auto iter = wheels_.rbegin(); iter != wheels_.rend(); ++iter) {
|
||||
iter->clear();
|
||||
}
|
||||
//LOG_TRACE << "CacheMap destruct!";
|
||||
LOG_TRACE << "CacheMap destruct!";
|
||||
}
|
||||
struct MapValue {
|
||||
MapValue(const T2 &value,
|
||||
@ -327,9 +327,9 @@ public:
|
||||
/**
|
||||
* @brief Get the event loop object
|
||||
*
|
||||
* @return EventLoop*
|
||||
* @return trantor::EventLoop*
|
||||
*/
|
||||
EventLoop *getLoop() {
|
||||
trantor::EventLoop *getLoop() {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
@ -377,8 +377,8 @@ private:
|
||||
|
||||
std::mutex mtx_;
|
||||
std::mutex bucketMutex_;
|
||||
TimerId timerId_;
|
||||
EventLoop *loop_;
|
||||
trantor::TimerId timerId_;
|
||||
trantor::EventLoop *loop_;
|
||||
|
||||
float tickInterval_;
|
||||
size_t wheelsNumber_;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "core/math/date.h"
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
@ -42,7 +42,7 @@ public:
|
||||
*
|
||||
* @param date The expiration date
|
||||
*/
|
||||
void setExpiresDate(const Date &date) {
|
||||
void setExpiresDate(const trantor::Date &date) {
|
||||
expiresDate_ = date;
|
||||
}
|
||||
|
||||
@ -114,14 +114,14 @@ public:
|
||||
/**
|
||||
* @brief Get the expiration date of the cookie
|
||||
*/
|
||||
const Date &expiresDate() const {
|
||||
const trantor::Date &expiresDate() const {
|
||||
return expiresDate_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the expiration date of the cookie
|
||||
*/
|
||||
const Date &getExpiresDate() const {
|
||||
const trantor::Date &getExpiresDate() const {
|
||||
return expiresDate_;
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Date expiresDate_{ (std::numeric_limits<int64_t>::max)() };
|
||||
trantor::Date expiresDate_{ (std::numeric_limits<int64_t>::max)() };
|
||||
bool httpOnly_{ true };
|
||||
bool secure_{ false };
|
||||
std::string domain_;
|
||||
|
@ -21,8 +21,8 @@
|
||||
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <json/json.h>
|
||||
#include "core/net/inet_address.h"
|
||||
#include "core/math/date.h"
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@ -248,20 +248,20 @@ public:
|
||||
virtual const std::string &getParameter(const std::string &key) const = 0;
|
||||
|
||||
/// Return the remote IP address and port
|
||||
virtual const InetAddress &peerAddr() const = 0;
|
||||
const InetAddress &getPeerAddr() const {
|
||||
virtual const trantor::InetAddress &peerAddr() const = 0;
|
||||
const trantor::InetAddress &getPeerAddr() const {
|
||||
return peerAddr();
|
||||
}
|
||||
|
||||
/// Return the local IP address and port
|
||||
virtual const InetAddress &localAddr() const = 0;
|
||||
const InetAddress &getLocalAddr() const {
|
||||
virtual const trantor::InetAddress &localAddr() const = 0;
|
||||
const trantor::InetAddress &getLocalAddr() const {
|
||||
return localAddr();
|
||||
}
|
||||
|
||||
/// Return the creation timestamp set by the framework.
|
||||
virtual const Date &creationDate() const = 0;
|
||||
const Date &getCreationDate() const {
|
||||
virtual const trantor::Date &creationDate() const = 0;
|
||||
const trantor::Date &getCreationDate() const {
|
||||
return creationDate();
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ void HttpRequestImpl::parseParameters() const {
|
||||
}
|
||||
}
|
||||
|
||||
void HttpRequestImpl::appendToBuffer(MsgBuffer *output) const {
|
||||
void HttpRequestImpl::appendToBuffer(trantor::MsgBuffer *output) const {
|
||||
switch (method_) {
|
||||
case Get:
|
||||
output->append("GET ");
|
||||
|
@ -20,10 +20,10 @@
|
||||
#include <http/HttpRequest.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <stdio.h>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/inet_address.h"
|
||||
#include "core/log/logger.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@ -35,8 +35,8 @@ class HttpRequestImpl : public HttpRequest {
|
||||
public:
|
||||
friend class HttpRequestParser;
|
||||
|
||||
explicit HttpRequestImpl(EventLoop *loop) :
|
||||
creationDate_(Date::now()), loop_(loop) {
|
||||
explicit HttpRequestImpl(trantor::EventLoop *loop) :
|
||||
creationDate_(trantor::Date::now()), loop_(loop) {
|
||||
}
|
||||
void reset() {
|
||||
method_ = Invalid;
|
||||
@ -62,7 +62,7 @@ public:
|
||||
keepAlive_ = true;
|
||||
jsonParsingErrorPtr_.reset();
|
||||
}
|
||||
EventLoop *getLoop() {
|
||||
trantor::EventLoop *getLoop() {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
@ -174,27 +174,27 @@ public:
|
||||
return query_;
|
||||
}
|
||||
|
||||
virtual const InetAddress &peerAddr() const override {
|
||||
virtual const trantor::InetAddress &peerAddr() const override {
|
||||
return peer_;
|
||||
}
|
||||
|
||||
virtual const InetAddress &localAddr() const override {
|
||||
virtual const trantor::InetAddress &localAddr() const override {
|
||||
return local_;
|
||||
}
|
||||
|
||||
virtual const Date &creationDate() const override {
|
||||
virtual const trantor::Date &creationDate() const override {
|
||||
return creationDate_;
|
||||
}
|
||||
|
||||
void setCreationDate(const Date &date) {
|
||||
void setCreationDate(const trantor::Date &date) {
|
||||
creationDate_ = date;
|
||||
}
|
||||
|
||||
void setPeerAddr(const InetAddress &peer) {
|
||||
void setPeerAddr(const trantor::InetAddress &peer) {
|
||||
peer_ = peer;
|
||||
}
|
||||
|
||||
void setLocalAddr(const InetAddress &local) {
|
||||
void setLocalAddr(const trantor::InetAddress &local) {
|
||||
local_ = local;
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ public:
|
||||
return passThrough_;
|
||||
}
|
||||
|
||||
void appendToBuffer(MsgBuffer *output) const;
|
||||
void appendToBuffer(trantor::MsgBuffer *output) const;
|
||||
|
||||
virtual const SessionPtr &session() const override {
|
||||
return sessionPtr_;
|
||||
@ -419,9 +419,9 @@ private:
|
||||
mutable std::shared_ptr<Json::Value> jsonPtr_;
|
||||
SessionPtr sessionPtr_;
|
||||
mutable AttributesPtr attributesPtr_;
|
||||
InetAddress peer_;
|
||||
InetAddress local_;
|
||||
Date creationDate_;
|
||||
trantor::InetAddress peer_;
|
||||
trantor::InetAddress local_;
|
||||
trantor::Date creationDate_;
|
||||
std::unique_ptr<CacheFile> cacheFilePtr_;
|
||||
mutable std::unique_ptr<std::string> jsonParsingErrorPtr_;
|
||||
std::unique_ptr<std::string> expectPtr_;
|
||||
@ -431,7 +431,7 @@ private:
|
||||
|
||||
protected:
|
||||
std::string content_;
|
||||
EventLoop *loop_;
|
||||
trantor::EventLoop *loop_;
|
||||
mutable ContentType contentType_{ CT_TEXT_PLAIN };
|
||||
mutable bool flagForParsingContentType_{ false };
|
||||
std::string contentTypeString_;
|
||||
|
@ -18,14 +18,14 @@
|
||||
#include "HttpResponseImpl.h"
|
||||
#include "HttpUtils.h"
|
||||
#include <http/HttpTypes.h>
|
||||
#include "core/log/logger.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
|
||||
HttpRequestParser::HttpRequestParser(const TcpConnectionPtr &connPtr) :
|
||||
HttpRequestParser::HttpRequestParser(const trantor::TcpConnectionPtr &connPtr) :
|
||||
status_(HttpRequestParseStatus::kExpectMethod),
|
||||
loop_(connPtr->getLoop()),
|
||||
conn_(connPtr) {
|
||||
@ -99,7 +99,7 @@ void HttpRequestParser::reset() {
|
||||
auto req = std::move(requestsPool_.back());
|
||||
requestsPool_.pop_back();
|
||||
request_ = std::move(req);
|
||||
request_->setCreationDate(Date::now());
|
||||
request_->setCreationDate(trantor::Date::now());
|
||||
}
|
||||
}
|
||||
// Return false if any error
|
||||
|
@ -16,14 +16,14 @@
|
||||
|
||||
#include "../src/impl_forwards.h"
|
||||
#include <http/HttpTypes.h>
|
||||
#include "core/net/tcp_connection.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
|
||||
namespace drogon {
|
||||
class HttpRequestParser : public NonCopyable,
|
||||
class HttpRequestParser : public trantor::NonCopyable,
|
||||
public std::enable_shared_from_this<HttpRequestParser> {
|
||||
public:
|
||||
enum class HttpRequestParseStatus {
|
||||
@ -37,10 +37,10 @@ public:
|
||||
kGotAll,
|
||||
};
|
||||
|
||||
explicit HttpRequestParser(const TcpConnectionPtr &connPtr);
|
||||
explicit HttpRequestParser(const trantor::TcpConnectionPtr &connPtr);
|
||||
|
||||
// return false if any error
|
||||
bool parseRequest(MsgBuffer *buf);
|
||||
bool parseRequest(trantor::MsgBuffer *buf);
|
||||
|
||||
bool gotAll() const {
|
||||
return status_ == HttpRequestParseStatus::kGotAll;
|
||||
@ -88,7 +88,7 @@ public:
|
||||
size_t numberOfRequestsParsed() const {
|
||||
return requestsCounter_;
|
||||
}
|
||||
MsgBuffer &getBuffer() {
|
||||
trantor::MsgBuffer &getBuffer() {
|
||||
return sendBuffer_;
|
||||
}
|
||||
std::vector<std::pair<HttpResponsePtr, bool> > &getResponseBuffer() {
|
||||
@ -114,16 +114,16 @@ private:
|
||||
void shutdownConnection(HttpStatusCode code);
|
||||
bool processRequestLine(const char *begin, const char *end);
|
||||
HttpRequestParseStatus status_;
|
||||
EventLoop *loop_;
|
||||
trantor::EventLoop *loop_;
|
||||
HttpRequestImplPtr request_;
|
||||
bool firstRequest_{ true };
|
||||
WebSocketConnectionImplPtr websockConnPtr_;
|
||||
std::deque<std::pair<HttpRequestPtr, std::pair<HttpResponsePtr, bool> > >
|
||||
requestPipelining_;
|
||||
size_t requestsCounter_{ 0 };
|
||||
std::weak_ptr<TcpConnection> conn_;
|
||||
std::weak_ptr<trantor::TcpConnection> conn_;
|
||||
bool stopWorking_{ false };
|
||||
MsgBuffer sendBuffer_;
|
||||
trantor::MsgBuffer sendBuffer_;
|
||||
std::unique_ptr<std::vector<std::pair<HttpResponsePtr, bool> > >
|
||||
responseBuffer_;
|
||||
std::unique_ptr<std::vector<HttpRequestImplPtr> > requestBuffer_;
|
||||
|
@ -101,8 +101,8 @@ public:
|
||||
}
|
||||
|
||||
/// Get the creation timestamp of the response.
|
||||
virtual const Date &creationDate() const = 0;
|
||||
const Date &getCreationDate() const {
|
||||
virtual const trantor::Date &creationDate() const = 0;
|
||||
const trantor::Date &getCreationDate() const {
|
||||
return creationDate();
|
||||
}
|
||||
|
||||
|
@ -18,14 +18,14 @@
|
||||
#include <drogon/HttpViewData.h>
|
||||
#include <drogon/IOThreadStorage.h>
|
||||
#include <sys/stat.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#ifdef _WIN32
|
||||
#define stat _stati64
|
||||
#endif
|
||||
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
|
||||
namespace drogon {
|
||||
@ -98,7 +98,7 @@ void HttpResponseImpl::generateBodyFromJson() const {
|
||||
}
|
||||
|
||||
HttpResponsePtr HttpResponse::newNotFoundResponse() {
|
||||
auto loop = EventLoop::getEventLoopOfCurrentThread();
|
||||
auto loop = trantor::EventLoop::getEventLoopOfCurrentThread();
|
||||
auto &resp = HttpAppFrameworkImpl::instance().getCustom404Page();
|
||||
if (resp) {
|
||||
if (loop && loop->index() < app().getThreadNum()) {
|
||||
@ -243,7 +243,7 @@ HttpResponsePtr HttpResponse::newFileResponse(const std::string &fullPath, const
|
||||
return resp;
|
||||
}
|
||||
|
||||
void HttpResponseImpl::makeHeaderString(MsgBuffer &buffer) {
|
||||
void HttpResponseImpl::makeHeaderString(trantor::MsgBuffer &buffer) {
|
||||
buffer.ensureWritableBytes(128);
|
||||
int len{ 0 };
|
||||
if (version_ == Version::kHttp11) {
|
||||
@ -320,7 +320,7 @@ void HttpResponseImpl::makeHeaderString(MsgBuffer &buffer) {
|
||||
buffer.append("\r\n");
|
||||
}
|
||||
}
|
||||
void HttpResponseImpl::renderToBuffer(MsgBuffer &buffer) {
|
||||
void HttpResponseImpl::renderToBuffer(trantor::MsgBuffer &buffer) {
|
||||
if (expriedTime_ >= 0) {
|
||||
auto strPtr = renderToBuffer();
|
||||
buffer.append(strPtr->peek(), strPtr->readableBytes());
|
||||
@ -344,7 +344,7 @@ void HttpResponseImpl::renderToBuffer(MsgBuffer &buffer) {
|
||||
if (!passThrough_ &&
|
||||
drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) {
|
||||
buffer.append("date: ");
|
||||
buffer.append(utils::getHttpFullDate(Date::date()),
|
||||
buffer.append(utils::getHttpFullDate(trantor::Date::date()),
|
||||
httpFullDateStringLength);
|
||||
buffer.append("\r\n\r\n");
|
||||
} else {
|
||||
@ -353,12 +353,12 @@ void HttpResponseImpl::renderToBuffer(MsgBuffer &buffer) {
|
||||
if (bodyPtr_)
|
||||
buffer.append(bodyPtr_->data(), bodyPtr_->length());
|
||||
}
|
||||
std::shared_ptr<MsgBuffer> HttpResponseImpl::renderToBuffer() {
|
||||
std::shared_ptr<trantor::MsgBuffer> HttpResponseImpl::renderToBuffer() {
|
||||
if (expriedTime_ >= 0) {
|
||||
if (!passThrough_ &&
|
||||
drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) {
|
||||
if (datePos_ != static_cast<size_t>(-1)) {
|
||||
auto now = Date::now();
|
||||
auto now = trantor::Date::now();
|
||||
bool isDateChanged =
|
||||
((now.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC) !=
|
||||
httpStringDate_);
|
||||
@ -369,7 +369,7 @@ std::shared_ptr<MsgBuffer> HttpResponseImpl::renderToBuffer() {
|
||||
auto newDate = utils::getHttpFullDate(now);
|
||||
|
||||
httpString_ =
|
||||
std::make_shared<MsgBuffer>(*httpString_);
|
||||
std::make_shared<trantor::MsgBuffer>(*httpString_);
|
||||
memcpy((void *)&(*httpString_)[datePos_],
|
||||
newDate,
|
||||
httpFullDateStringLength);
|
||||
@ -383,7 +383,7 @@ std::shared_ptr<MsgBuffer> HttpResponseImpl::renderToBuffer() {
|
||||
return httpString_;
|
||||
}
|
||||
}
|
||||
auto httpString = std::make_shared<MsgBuffer>(256);
|
||||
auto httpString = std::make_shared<trantor::MsgBuffer>(256);
|
||||
if (!fullHeaderString_) {
|
||||
makeHeaderString(*httpString);
|
||||
} else {
|
||||
@ -402,7 +402,7 @@ std::shared_ptr<MsgBuffer> HttpResponseImpl::renderToBuffer() {
|
||||
drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) {
|
||||
httpString->append("date: ");
|
||||
auto datePos = httpString->readableBytes();
|
||||
httpString->append(utils::getHttpFullDate(Date::date()),
|
||||
httpString->append(utils::getHttpFullDate(trantor::Date::date()),
|
||||
httpFullDateStringLength);
|
||||
httpString->append("\r\n\r\n");
|
||||
datePos_ = datePos;
|
||||
@ -420,9 +420,9 @@ std::shared_ptr<MsgBuffer> HttpResponseImpl::renderToBuffer() {
|
||||
return httpString;
|
||||
}
|
||||
|
||||
std::shared_ptr<MsgBuffer> HttpResponseImpl::
|
||||
std::shared_ptr<trantor::MsgBuffer> HttpResponseImpl::
|
||||
renderHeaderForHeadMethod() {
|
||||
auto httpString = std::make_shared<MsgBuffer>(256);
|
||||
auto httpString = std::make_shared<trantor::MsgBuffer>(256);
|
||||
if (!fullHeaderString_) {
|
||||
makeHeaderString(*httpString);
|
||||
} else {
|
||||
@ -440,7 +440,7 @@ std::shared_ptr<MsgBuffer> HttpResponseImpl::
|
||||
if (!passThrough_ &&
|
||||
drogon::HttpAppFrameworkImpl::instance().sendDateHeader()) {
|
||||
httpString->append("date: ");
|
||||
httpString->append(utils::getHttpFullDate(Date::date()),
|
||||
httpString->append(utils::getHttpFullDate(trantor::Date::date()),
|
||||
httpFullDateStringLength);
|
||||
httpString->append("\r\n\r\n");
|
||||
} else {
|
||||
|
@ -19,9 +19,9 @@
|
||||
#include <http/HttpResponse.h>
|
||||
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include "core/net/inet_address.h"
|
||||
#include "core/math/date.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
@ -34,12 +34,12 @@ class HttpResponseImpl : public HttpResponse {
|
||||
|
||||
public:
|
||||
HttpResponseImpl() :
|
||||
creationDate_(Date::now()) {
|
||||
creationDate_(trantor::Date::now()) {
|
||||
}
|
||||
HttpResponseImpl(HttpStatusCode code, ContentType type) :
|
||||
statusCode_(code),
|
||||
statusMessage_(statusCodeToString(code)),
|
||||
creationDate_(Date::now()),
|
||||
creationDate_(trantor::Date::now()),
|
||||
contentType_(type),
|
||||
flagForParsingContentType_(true),
|
||||
contentTypeString_(webContentTypeToString(type)) {
|
||||
@ -51,7 +51,7 @@ public:
|
||||
return statusCode_;
|
||||
}
|
||||
|
||||
const Date &creationDate() const override {
|
||||
const trantor::Date &creationDate() const override {
|
||||
return creationDate_;
|
||||
}
|
||||
|
||||
@ -199,9 +199,9 @@ public:
|
||||
void redirect(const std::string &url) {
|
||||
headers_["location"] = url;
|
||||
}
|
||||
std::shared_ptr<MsgBuffer> renderToBuffer();
|
||||
void renderToBuffer(MsgBuffer &buffer);
|
||||
std::shared_ptr<MsgBuffer> renderHeaderForHeadMethod();
|
||||
std::shared_ptr<trantor::MsgBuffer> renderToBuffer();
|
||||
void renderToBuffer(trantor::MsgBuffer &buffer);
|
||||
std::shared_ptr<trantor::MsgBuffer> renderHeaderForHeadMethod();
|
||||
void clear() override;
|
||||
|
||||
void setExpiredTime(ssize_t expiredTime) override {
|
||||
@ -266,7 +266,7 @@ public:
|
||||
sendfileName_ = filename;
|
||||
}
|
||||
void makeHeaderString() {
|
||||
fullHeaderString_ = std::make_shared<MsgBuffer>(128);
|
||||
fullHeaderString_ = std::make_shared<trantor::MsgBuffer>(128);
|
||||
makeHeaderString(*fullHeaderString_);
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ public:
|
||||
~HttpResponseImpl() override = default;
|
||||
|
||||
protected:
|
||||
void makeHeaderString(MsgBuffer &headerString);
|
||||
void makeHeaderString(trantor::MsgBuffer &headerString);
|
||||
|
||||
private:
|
||||
void setBody(const char *body, size_t len) override {
|
||||
@ -327,7 +327,7 @@ private:
|
||||
HttpStatusCode statusCode_{ kUnknown };
|
||||
string_view statusMessage_;
|
||||
|
||||
Date creationDate_;
|
||||
trantor::Date creationDate_;
|
||||
Version version_{ Version::kHttp11 };
|
||||
bool closeConnection_{ false };
|
||||
mutable std::shared_ptr<HttpMessageBody> bodyPtr_;
|
||||
@ -335,8 +335,8 @@ private:
|
||||
std::string sendfileName_;
|
||||
mutable std::shared_ptr<Json::Value> jsonPtr_;
|
||||
|
||||
std::shared_ptr<MsgBuffer> fullHeaderString_;
|
||||
mutable std::shared_ptr<MsgBuffer> httpString_;
|
||||
std::shared_ptr<trantor::MsgBuffer> fullHeaderString_;
|
||||
mutable std::shared_ptr<trantor::MsgBuffer> httpString_;
|
||||
mutable size_t datePos_{ static_cast<size_t>(-1) };
|
||||
mutable int64_t httpStringDate_{ -1 };
|
||||
mutable bool flagForParsingJson_{ false };
|
||||
|
@ -14,10 +14,10 @@
|
||||
|
||||
#include "HttpResponseParser.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include "core/log/logger.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
|
||||
void HttpResponseParser::reset() {
|
||||
@ -28,7 +28,7 @@ void HttpResponseParser::reset() {
|
||||
currentChunkLength_ = 0;
|
||||
}
|
||||
|
||||
HttpResponseParser::HttpResponseParser(const TcpConnectionPtr &connPtr) :
|
||||
HttpResponseParser::HttpResponseParser(const trantor::TcpConnectionPtr &connPtr) :
|
||||
status_(HttpResponseParseStatus::kExpectResponseLine),
|
||||
responsePtr_(new HttpResponseImpl),
|
||||
conn_(connPtr) {
|
||||
|
@ -15,14 +15,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "../src/impl_forwards.h"
|
||||
#include "core/net/tcp_connection.h"
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
|
||||
namespace drogon {
|
||||
class HttpResponseParser : public NonCopyable {
|
||||
class HttpResponseParser : public trantor::NonCopyable {
|
||||
public:
|
||||
enum class HttpResponseParseStatus {
|
||||
kExpectResponseLine,
|
||||
@ -35,12 +35,12 @@ public:
|
||||
kGotAll,
|
||||
};
|
||||
|
||||
explicit HttpResponseParser(const TcpConnectionPtr &connPtr);
|
||||
explicit HttpResponseParser(const trantor::TcpConnectionPtr &connPtr);
|
||||
|
||||
// default copy-ctor, dtor and assignment are fine
|
||||
|
||||
// return false if any error
|
||||
bool parseResponse(MsgBuffer *buf);
|
||||
bool parseResponse(trantor::MsgBuffer *buf);
|
||||
bool parseResponseOnClose();
|
||||
|
||||
bool gotAll() const {
|
||||
@ -65,7 +65,7 @@ private:
|
||||
bool parseResponseForHeadMethod_{ false };
|
||||
size_t leftBodyLength_{ 0 };
|
||||
size_t currentChunkLength_{ 0 };
|
||||
std::weak_ptr<TcpConnection> conn_;
|
||||
std::weak_ptr<trantor::TcpConnection> conn_;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "HttpUtils.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace drogon {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "HttpTypes.h"
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include "core/containers/msg_buffer.h"
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <string>
|
||||
|
||||
namespace drogon {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include <drogon/utils/any.h>
|
||||
#include <drogon/utils/optional.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
SessionManager::SessionManager(EventLoop *loop, size_t timeout) :
|
||||
SessionManager::SessionManager(trantor::EventLoop *loop, size_t timeout) :
|
||||
loop_(loop), timeout_(timeout) {
|
||||
if (timeout_ > 0) {
|
||||
size_t wheelNum = 1;
|
||||
|
@ -16,16 +16,16 @@
|
||||
|
||||
#include "CacheMap.h"
|
||||
#include "Session.h"
|
||||
#include "core/loops/event_loop.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace drogon {
|
||||
class SessionManager : public NonCopyable {
|
||||
class SessionManager : public trantor::NonCopyable {
|
||||
public:
|
||||
SessionManager(EventLoop *loop, size_t timeout);
|
||||
SessionManager(trantor::EventLoop *loop, size_t timeout);
|
||||
~SessionManager() {
|
||||
sessionMapPtr_.reset();
|
||||
}
|
||||
@ -34,7 +34,7 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<CacheMap<std::string, SessionPtr> > sessionMapPtr_;
|
||||
EventLoop *loop_;
|
||||
trantor::EventLoop *loop_;
|
||||
size_t timeout_;
|
||||
};
|
||||
} // namespace drogon
|
||||
|
@ -35,13 +35,13 @@ void AccessLogger::initAndStart(const Json::Value &config) {
|
||||
logFunctionMap_ = { { "$request_path", outputReqPath },
|
||||
{ "$path", outputReqPath },
|
||||
{ "$date",
|
||||
[this](LogStream &stream,
|
||||
[this](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
outputDate(stream, req, resp);
|
||||
} },
|
||||
{ "$request_date",
|
||||
[this](LogStream &stream,
|
||||
[this](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
outputReqDate(stream, req, resp);
|
||||
@ -85,7 +85,7 @@ void AccessLogger::initAndStart(const Json::Value &config) {
|
||||
asyncFileLogger_.setFileName(fileName, extension, logPath);
|
||||
asyncFileLogger_.startLogging();
|
||||
logIndex_ = config.get("log_index", 0).asInt();
|
||||
Logger::setOutputFunction(
|
||||
trantor::Logger::setOutputFunction(
|
||||
[&](const char *msg, const uint64_t len) {
|
||||
asyncFileLogger_.output(msg, len);
|
||||
},
|
||||
@ -106,7 +106,7 @@ void AccessLogger::initAndStart(const Json::Value &config) {
|
||||
void AccessLogger::shutdown() {
|
||||
}
|
||||
|
||||
void AccessLogger::logging(LogStream &stream,
|
||||
void AccessLogger::logging(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
for (auto &func : logFunctions_) {
|
||||
@ -128,7 +128,7 @@ void AccessLogger::createLogFunctions(std::string format) {
|
||||
if (std::regex_search(format, m, e)) {
|
||||
if (!rawString.empty()) {
|
||||
logFunctions_.emplace_back(
|
||||
[rawString](LogStream &stream,
|
||||
[rawString](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << rawString;
|
||||
@ -150,14 +150,14 @@ void AccessLogger::createLogFunctions(std::string format) {
|
||||
if (!rawString.empty()) {
|
||||
logFunctions_.emplace_back(
|
||||
[rawString =
|
||||
std::move(rawString)](LogStream &stream,
|
||||
std::move(rawString)](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << rawString << "\n";
|
||||
});
|
||||
} else {
|
||||
logFunctions_.emplace_back(
|
||||
[](LogStream &stream,
|
||||
[](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) { stream << "\n"; });
|
||||
}
|
||||
@ -172,7 +172,7 @@ AccessLogger::LogFunction AccessLogger::newLogFunction(
|
||||
if (placeholder.find("$http_") == 0 && placeholder.size() > 6) {
|
||||
auto headerName = placeholder.substr(6);
|
||||
return [headerName =
|
||||
std::move(headerName)](LogStream &stream,
|
||||
std::move(headerName)](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
outputReqHeader(stream, req, headerName);
|
||||
@ -181,7 +181,7 @@ AccessLogger::LogFunction AccessLogger::newLogFunction(
|
||||
if (placeholder.find("$cookie_") == 0 && placeholder.size() > 8) {
|
||||
auto cookieName = placeholder.substr(8);
|
||||
return [cookieName =
|
||||
std::move(cookieName)](LogStream &stream,
|
||||
std::move(cookieName)](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
outputReqCookie(stream, req, cookieName);
|
||||
@ -190,36 +190,36 @@ AccessLogger::LogFunction AccessLogger::newLogFunction(
|
||||
if (placeholder.find("$upstream_http_") == 0 && placeholder.size() > 15) {
|
||||
auto headerName = placeholder.substr(15);
|
||||
return [headerName = std::move(
|
||||
headerName)](LogStream &stream,
|
||||
headerName)](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
outputRespHeader(stream, resp, headerName);
|
||||
};
|
||||
}
|
||||
return [placeholder](LogStream &stream,
|
||||
return [placeholder](trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << placeholder;
|
||||
};
|
||||
}
|
||||
|
||||
void AccessLogger::outputReqPath(LogStream &stream,
|
||||
void AccessLogger::outputReqPath(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << req->path();
|
||||
}
|
||||
|
||||
void AccessLogger::outputDate(LogStream &stream,
|
||||
void AccessLogger::outputDate(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) const {
|
||||
if (useLocalTime_) {
|
||||
stream << Date::now().toFormattedStringLocal(true);
|
||||
stream << trantor::Date::now().toFormattedStringLocal(true);
|
||||
} else {
|
||||
stream << Date::now().toFormattedString(true);
|
||||
stream << trantor::Date::now().toFormattedString(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AccessLogger::outputReqDate(LogStream &stream,
|
||||
void AccessLogger::outputReqDate(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) const {
|
||||
if (useLocalTime_) {
|
||||
@ -230,13 +230,13 @@ void AccessLogger::outputReqDate(LogStream &stream,
|
||||
}
|
||||
|
||||
//$request_query
|
||||
void AccessLogger::outputReqQuery(LogStream &stream,
|
||||
void AccessLogger::outputReqQuery(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << req->query();
|
||||
}
|
||||
//$request_url
|
||||
void AccessLogger::outputReqURL(LogStream &stream,
|
||||
void AccessLogger::outputReqURL(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
auto &query = req->query();
|
||||
@ -247,36 +247,36 @@ void AccessLogger::outputReqURL(LogStream &stream,
|
||||
}
|
||||
}
|
||||
|
||||
void AccessLogger::outputRemoteAddr(LogStream &stream,
|
||||
void AccessLogger::outputRemoteAddr(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << req->peerAddr().toIpPort();
|
||||
}
|
||||
|
||||
void AccessLogger::outputLocalAddr(LogStream &stream,
|
||||
void AccessLogger::outputLocalAddr(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << req->localAddr().toIpPort();
|
||||
}
|
||||
|
||||
void AccessLogger::outputReqLength(LogStream &stream,
|
||||
void AccessLogger::outputReqLength(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << req->body().length();
|
||||
}
|
||||
|
||||
void AccessLogger::outputRespLength(LogStream &stream,
|
||||
void AccessLogger::outputRespLength(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
stream << resp->body().length();
|
||||
}
|
||||
void AccessLogger::outputMethod(LogStream &stream,
|
||||
void AccessLogger::outputMethod(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
stream << req->methodString();
|
||||
}
|
||||
|
||||
void AccessLogger::outputThreadNumber(LogStream &stream,
|
||||
void AccessLogger::outputThreadNumber(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
#ifdef __linux__
|
||||
@ -310,45 +310,45 @@ void AccessLogger::outputThreadNumber(LogStream &stream,
|
||||
}
|
||||
|
||||
//$http_[header_name]
|
||||
void AccessLogger::outputReqHeader(LogStream &stream,
|
||||
void AccessLogger::outputReqHeader(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const std::string &headerName) {
|
||||
stream << headerName << ": " << req->getHeader(headerName);
|
||||
}
|
||||
|
||||
//$cookie_[cookie_name]
|
||||
void AccessLogger::outputReqCookie(LogStream &stream,
|
||||
void AccessLogger::outputReqCookie(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const std::string &cookie) {
|
||||
stream << "(cookie)" << cookie << "=" << req->getCookie(cookie);
|
||||
}
|
||||
|
||||
//$upstream_http_[header_name]
|
||||
void AccessLogger::outputRespHeader(LogStream &stream,
|
||||
void AccessLogger::outputRespHeader(trantor::LogStream &stream,
|
||||
const drogon::HttpResponsePtr &resp,
|
||||
const std::string &headerName) {
|
||||
stream << headerName << ": " << resp->getHeader(headerName);
|
||||
}
|
||||
|
||||
//$status
|
||||
void AccessLogger::outputStatusString(LogStream &stream,
|
||||
void AccessLogger::outputStatusString(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
int code = resp->getStatusCode();
|
||||
stream << code << " " << statusCodeToString(code);
|
||||
}
|
||||
//$status_code
|
||||
void AccessLogger::outputStatusCode(LogStream &stream,
|
||||
void AccessLogger::outputStatusCode(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
stream << resp->getStatusCode();
|
||||
}
|
||||
//$processing_time
|
||||
void AccessLogger::outputProcessingTime(LogStream &stream,
|
||||
void AccessLogger::outputProcessingTime(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &req,
|
||||
const drogon::HttpResponsePtr &) {
|
||||
auto start = req->creationDate();
|
||||
auto end = Date::now();
|
||||
auto end = trantor::Date::now();
|
||||
auto duration =
|
||||
end.microSecondsSinceEpoch() - start.microSecondsSinceEpoch();
|
||||
auto seconds = static_cast<double>(duration) / 1000000.0;
|
||||
@ -356,7 +356,7 @@ void AccessLogger::outputProcessingTime(LogStream &stream,
|
||||
}
|
||||
|
||||
//$upstream_http_content-type $upstream_http_content_type
|
||||
void AccessLogger::outputRespContentType(LogStream &stream,
|
||||
void AccessLogger::outputRespContentType(trantor::LogStream &stream,
|
||||
const drogon::HttpRequestPtr &,
|
||||
const drogon::HttpResponsePtr &resp) {
|
||||
auto typeStr = webContentTypeToString(resp->contentType());
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <json/json.h>
|
||||
#include "core/log/async_file_logger.h"
|
||||
#include <trantor/utils/AsyncFileLogger.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include <fstream>
|
||||
@ -365,8 +365,8 @@ HttpAppFramework &HttpAppFrameworkImpl::setLogPath(
|
||||
return *this;
|
||||
}
|
||||
HttpAppFramework &HttpAppFrameworkImpl::setLogLevel(
|
||||
Logger::LogLevel level) {
|
||||
Logger::setLogLevel(level);
|
||||
trantor::Logger::LogLevel level) {
|
||||
trantor::Logger::setLogLevel(level);
|
||||
return *this;
|
||||
}
|
||||
HttpAppFramework &HttpAppFrameworkImpl::setSSLConfigCommands(
|
||||
@ -386,7 +386,7 @@ void HttpAppFrameworkImpl::run() {
|
||||
getLoop()->moveToCurrentThread();
|
||||
}
|
||||
LOG_TRACE << "Start to run...";
|
||||
AsyncFileLogger asyncFileLogger;
|
||||
trantor::AsyncFileLogger asyncFileLogger;
|
||||
// Create dirs for cache files
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
char dirName[4];
|
||||
@ -443,7 +443,7 @@ void HttpAppFrameworkImpl::run() {
|
||||
asyncFileLogger.setFileName(baseName, ".log", logPath_);
|
||||
asyncFileLogger.startLogging();
|
||||
|
||||
Logger::setOutputFunction(
|
||||
trantor::Logger::setOutputFunction(
|
||||
[&](const char *msg, const uint64_t len) {
|
||||
asyncFileLogger.output(msg, len);
|
||||
},
|
||||
@ -518,7 +518,7 @@ void HttpAppFrameworkImpl::run() {
|
||||
getLoop()->loop();
|
||||
}
|
||||
|
||||
void HttpAppFrameworkImpl::onConnection(const TcpConnectionPtr &conn) {
|
||||
void HttpAppFrameworkImpl::onConnection(const trantor::TcpConnectionPtr &conn) {
|
||||
static std::mutex mtx;
|
||||
LOG_TRACE << "connect!!!" << maxConnectionNum_
|
||||
<< " num=" << connectionNum_.load();
|
||||
@ -737,13 +737,13 @@ void HttpAppFrameworkImpl::onAsyncRequest(
|
||||
}*/
|
||||
}
|
||||
|
||||
EventLoop *HttpAppFrameworkImpl::getLoop() const {
|
||||
//static EventLoop loop;
|
||||
trantor::EventLoop *HttpAppFrameworkImpl::getLoop() const {
|
||||
//static trantor::EventLoop loop;
|
||||
//return &loop;]
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EventLoop *HttpAppFrameworkImpl::getIOLoop(size_t id) const {
|
||||
trantor::EventLoop *HttpAppFrameworkImpl::getIOLoop(size_t id) const {
|
||||
assert(listenerManagerPtr_);
|
||||
return listenerManagerPtr_->getIOLoop(id);
|
||||
}
|
||||
@ -781,7 +781,7 @@ void HttpAppFrameworkImpl::forward(
|
||||
clientPtr = iter->second;
|
||||
} else {
|
||||
clientPtr = std::make_shared<HttpClientImpl>(
|
||||
EventLoop::getEventLoopOfCurrentThread() ? EventLoop::getEventLoopOfCurrentThread() : getLoop(),
|
||||
trantor::EventLoop::getEventLoopOfCurrentThread() ? trantor::EventLoop::getEventLoopOfCurrentThread() : getLoop(),
|
||||
hostString);
|
||||
clientsMap[hostString] = clientPtr;
|
||||
}
|
||||
@ -815,7 +815,7 @@ const HttpResponsePtr &HttpAppFrameworkImpl::getCustom404Page() {
|
||||
if (!custom404_) {
|
||||
return custom404_;
|
||||
}
|
||||
auto loop = EventLoop::getEventLoopOfCurrentThread();
|
||||
auto loop = trantor::EventLoop::getEventLoopOfCurrentThread();
|
||||
if (loop && loop->index() < app().getThreadNum()) {
|
||||
// If the current thread is an IO thread
|
||||
static IOThreadStorage<HttpResponsePtr> thread404Pages;
|
||||
@ -869,7 +869,7 @@ const std::function<HttpResponsePtr(HttpStatusCode)>
|
||||
return customErrorHandler_;
|
||||
}
|
||||
|
||||
std::vector<InetAddress> HttpAppFrameworkImpl::getListeners() const {
|
||||
std::vector<trantor::InetAddress> HttpAppFrameworkImpl::getListeners() const {
|
||||
return listenerManagerPtr_->getListeners();
|
||||
}
|
||||
HttpAppFramework &HttpAppFrameworkImpl::setDefaultHandler(
|
||||
|
@ -114,8 +114,8 @@ public:
|
||||
}
|
||||
|
||||
HttpAppFramework ®isterNewConnectionAdvice(
|
||||
const std::function<bool(const InetAddress &,
|
||||
const InetAddress &)> &advice)
|
||||
const std::function<bool(const trantor::InetAddress &,
|
||||
const trantor::InetAddress &)> &advice)
|
||||
override {
|
||||
newConnectionAdvices_.emplace_back(advice);
|
||||
return *this;
|
||||
@ -222,8 +222,8 @@ public:
|
||||
const std::string &getUploadPath() const override {
|
||||
return uploadPath_;
|
||||
}
|
||||
const std::shared_ptr<Resolver> &getResolver() const override {
|
||||
static auto resolver = Resolver::newResolver(getLoop());
|
||||
const std::shared_ptr<trantor::Resolver> &getResolver() const override {
|
||||
static auto resolver = trantor::Resolver::newResolver(getLoop());
|
||||
return resolver;
|
||||
}
|
||||
HttpAppFramework &setUploadPath(const std::string &uploadPath) override;
|
||||
@ -255,7 +255,7 @@ public:
|
||||
HttpAppFramework &setLogPath(const std::string &logPath,
|
||||
const std::string &logfileBaseName,
|
||||
size_t logfileSize) override;
|
||||
HttpAppFramework &setLogLevel(Logger::LogLevel level) override;
|
||||
HttpAppFramework &setLogLevel(trantor::Logger::LogLevel level) override;
|
||||
HttpAppFramework &enableSendfile(bool sendFile) override {
|
||||
useSendfile_ = sendFile;
|
||||
return *this;
|
||||
@ -365,9 +365,9 @@ public:
|
||||
const noexcept override {
|
||||
return floatPrecisionInJson_;
|
||||
}
|
||||
EventLoop *getLoop() const override;
|
||||
trantor::EventLoop *getLoop() const override;
|
||||
|
||||
EventLoop *getIOLoop(size_t id) const override;
|
||||
trantor::EventLoop *getIOLoop(size_t id) const override;
|
||||
|
||||
void quit() override;
|
||||
|
||||
@ -396,7 +396,7 @@ public:
|
||||
return serverHeader_;
|
||||
}
|
||||
|
||||
std::vector<InetAddress> getListeners() const override;
|
||||
std::vector<trantor::InetAddress> getListeners() const override;
|
||||
inline static HttpAppFrameworkImpl &instance() {
|
||||
static HttpAppFrameworkImpl instance;
|
||||
return instance;
|
||||
@ -417,7 +417,7 @@ public:
|
||||
}
|
||||
|
||||
size_t getCurrentThreadIndex() const override {
|
||||
auto *loop = EventLoop::getEventLoopOfCurrentThread();
|
||||
auto *loop = trantor::EventLoop::getEventLoopOfCurrentThread();
|
||||
if (loop) {
|
||||
return loop->index();
|
||||
}
|
||||
@ -466,7 +466,7 @@ private:
|
||||
const HttpRequestImplPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const WebSocketConnectionImplPtr &wsConnPtr);
|
||||
void onConnection(const TcpConnectionPtr &conn);
|
||||
void onConnection(const trantor::TcpConnectionPtr &conn);
|
||||
|
||||
void findSessionForRequest(const HttpRequestImplPtr &req);
|
||||
|
||||
@ -539,8 +539,8 @@ private:
|
||||
bool enableDateHeader_{ true };
|
||||
bool reusePort_{ false };
|
||||
std::vector<std::function<void()> > beginningAdvices_;
|
||||
std::vector<std::function<bool(const InetAddress &,
|
||||
const InetAddress &)> >
|
||||
std::vector<std::function<bool(const trantor::InetAddress &,
|
||||
const trantor::InetAddress &)> >
|
||||
newConnectionAdvices_;
|
||||
std::vector<std::function<void(const HttpResponsePtr &)> >
|
||||
responseCreationAdvices_;
|
||||
|
@ -21,16 +21,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
using namespace std::placeholders;
|
||||
|
||||
namespace trantor {
|
||||
const static size_t kDefaultDNSTimeout{ 600 };
|
||||
|
||||
}
|
||||
void HttpClientImpl::createTcpClient() {
|
||||
LOG_TRACE << "New TcpClient," << serverAddr_.toIpPort();
|
||||
tcpClientPtr_ =
|
||||
std::make_shared<TcpClient>(loop_, serverAddr_, "httpClient");
|
||||
std::make_shared<trantor::TcpClient>(loop_, serverAddr_, "httpClient");
|
||||
|
||||
#ifdef OPENSSL_FOUND
|
||||
if (useSSL_) {
|
||||
@ -43,7 +43,7 @@ void HttpClientImpl::createTcpClient() {
|
||||
std::weak_ptr<HttpClientImpl> weakPtr = thisPtr;
|
||||
|
||||
tcpClientPtr_->setConnectionCallback(
|
||||
[weakPtr](const TcpConnectionPtr &connPtr) {
|
||||
[weakPtr](const trantor::TcpConnectionPtr &connPtr) {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (!thisPtr)
|
||||
return;
|
||||
@ -89,8 +89,8 @@ void HttpClientImpl::createTcpClient() {
|
||||
thisPtr->onError(ReqResult::BadServerAddress);
|
||||
});
|
||||
tcpClientPtr_->setMessageCallback(
|
||||
[weakPtr](const TcpConnectionPtr &connPtr,
|
||||
MsgBuffer *msg) {
|
||||
[weakPtr](const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *msg) {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (thisPtr) {
|
||||
thisPtr->onRecvMessage(connPtr, msg);
|
||||
@ -100,9 +100,9 @@ void HttpClientImpl::createTcpClient() {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (!thisPtr)
|
||||
return;
|
||||
if (err == SSLError::kSSLHandshakeError)
|
||||
if (err == trantor::SSLError::kSSLHandshakeError)
|
||||
thisPtr->onError(ReqResult::HandshakeError);
|
||||
else if (err == SSLError::kSSLInvalidCertificate)
|
||||
else if (err == trantor::SSLError::kSSLInvalidCertificate)
|
||||
thisPtr->onError(ReqResult::InvalidCertificate);
|
||||
else {
|
||||
LOG_FATAL << "Invalid value for SSLError";
|
||||
@ -112,8 +112,8 @@ void HttpClientImpl::createTcpClient() {
|
||||
tcpClientPtr_->connect();
|
||||
}
|
||||
|
||||
HttpClientImpl::HttpClientImpl(EventLoop *loop,
|
||||
const InetAddress &addr,
|
||||
HttpClientImpl::HttpClientImpl(trantor::EventLoop *loop,
|
||||
const trantor::InetAddress &addr,
|
||||
bool useSSL,
|
||||
bool useOldTLS,
|
||||
bool validateCert) :
|
||||
@ -124,7 +124,7 @@ HttpClientImpl::HttpClientImpl(EventLoop *loop,
|
||||
useOldTLS_(useOldTLS) {
|
||||
}
|
||||
|
||||
HttpClientImpl::HttpClientImpl(EventLoop *loop,
|
||||
HttpClientImpl::HttpClientImpl(trantor::EventLoop *loop,
|
||||
const std::string &hostString,
|
||||
bool useOldTLS,
|
||||
bool validateCert) :
|
||||
@ -285,7 +285,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
||||
}
|
||||
for (auto &cookie : validCookies_) {
|
||||
if ((cookie.expiresDate().microSecondsSinceEpoch() == 0 ||
|
||||
cookie.expiresDate() > Date::now()) &&
|
||||
cookie.expiresDate() > trantor::Date::now()) &&
|
||||
(cookie.path().empty() || req->path().find(cookie.path()) == 0)) {
|
||||
req->addCookie(cookie.key(), cookie.value());
|
||||
}
|
||||
@ -316,13 +316,13 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
||||
dns_ = true;
|
||||
if (!resolverPtr_) {
|
||||
resolverPtr_ =
|
||||
Resolver::newResolver(loop_,
|
||||
trantor::Resolver::newResolver(loop_,
|
||||
kDefaultDNSTimeout);
|
||||
}
|
||||
resolverPtr_->resolve(
|
||||
domain_,
|
||||
[thisPtr = shared_from_this(),
|
||||
hasIpv6Address](const InetAddress &addr) {
|
||||
hasIpv6Address](const trantor::InetAddress &addr) {
|
||||
thisPtr->loop_->runInLoop([thisPtr,
|
||||
addr,
|
||||
hasIpv6Address]() {
|
||||
@ -394,9 +394,9 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClientImpl::sendReq(const TcpConnectionPtr &connPtr,
|
||||
void HttpClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr,
|
||||
const HttpRequestPtr &req) {
|
||||
MsgBuffer buffer;
|
||||
trantor::MsgBuffer buffer;
|
||||
assert(req);
|
||||
auto implPtr = static_cast<HttpRequestImpl *>(req.get());
|
||||
implPtr->appendToBuffer(&buffer);
|
||||
@ -409,7 +409,7 @@ void HttpClientImpl::sendReq(const TcpConnectionPtr &connPtr,
|
||||
void HttpClientImpl::handleResponse(
|
||||
const HttpResponseImplPtr &resp,
|
||||
std::pair<HttpRequestPtr, HttpReqCallback> &&reqAndCb,
|
||||
const TcpConnectionPtr &connPtr) {
|
||||
const trantor::TcpConnectionPtr &connPtr) {
|
||||
assert(!pipeliningCallbacks_.empty());
|
||||
auto &type = resp->getHeaderBy("content-type");
|
||||
auto &coding = resp->getHeaderBy("content-encoding");
|
||||
@ -452,8 +452,8 @@ void HttpClientImpl::handleResponse(
|
||||
}
|
||||
}
|
||||
}
|
||||
void HttpClientImpl::onRecvMessage(const TcpConnectionPtr &connPtr,
|
||||
MsgBuffer *msg) {
|
||||
void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *msg) {
|
||||
auto responseParser = connPtr->getContext<HttpResponseParser>();
|
||||
|
||||
// LOG_TRACE << "###:" << msg->readableBytes();
|
||||
@ -488,20 +488,20 @@ void HttpClientImpl::onRecvMessage(const TcpConnectionPtr &connPtr,
|
||||
HttpClientPtr HttpClient::newHttpClient(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL,
|
||||
EventLoop *loop,
|
||||
trantor::EventLoop *loop,
|
||||
bool useOldTLS,
|
||||
bool validateCert) {
|
||||
bool isIpv6 = ip.find(':') == std::string::npos ? false : true;
|
||||
return std::make_shared<HttpClientImpl>(
|
||||
loop == nullptr ? HttpAppFrameworkImpl::instance().getLoop() : loop,
|
||||
InetAddress(ip, port, isIpv6),
|
||||
trantor::InetAddress(ip, port, isIpv6),
|
||||
useSSL,
|
||||
useOldTLS,
|
||||
validateCert);
|
||||
}
|
||||
|
||||
HttpClientPtr HttpClient::newHttpClient(const std::string &hostString,
|
||||
EventLoop *loop,
|
||||
trantor::EventLoop *loop,
|
||||
bool useOldTLS,
|
||||
bool validateCert) {
|
||||
return std::make_shared<HttpClientImpl>(
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include "impl_forwards.h"
|
||||
#include <http/Cookie.h>
|
||||
#include <drogon/HttpClient.h>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/resolver.h"
|
||||
#include "core/net/tcp_client.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/Resolver.h>
|
||||
#include <trantor/net/TcpClient.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
@ -29,12 +29,12 @@ namespace drogon {
|
||||
class HttpClientImpl final : public HttpClient,
|
||||
public std::enable_shared_from_this<HttpClientImpl> {
|
||||
public:
|
||||
HttpClientImpl(EventLoop *loop,
|
||||
const InetAddress &addr,
|
||||
HttpClientImpl(trantor::EventLoop *loop,
|
||||
const trantor::InetAddress &addr,
|
||||
bool useSSL = false,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
HttpClientImpl(EventLoop *loop,
|
||||
HttpClientImpl(trantor::EventLoop *loop,
|
||||
const std::string &hostString,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
@ -44,7 +44,7 @@ public:
|
||||
void sendRequest(const HttpRequestPtr &req,
|
||||
HttpReqCallback &&callback,
|
||||
double timeout = 0) override;
|
||||
EventLoop *getLoop() override {
|
||||
trantor::EventLoop *getLoop() override {
|
||||
return loop_;
|
||||
}
|
||||
void setPipeliningDepth(size_t depth) override {
|
||||
@ -75,12 +75,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<TcpClient> tcpClientPtr_;
|
||||
EventLoop *loop_;
|
||||
InetAddress serverAddr_;
|
||||
std::shared_ptr<trantor::TcpClient> tcpClientPtr_;
|
||||
trantor::EventLoop *loop_;
|
||||
trantor::InetAddress serverAddr_;
|
||||
bool useSSL_;
|
||||
bool validateCert_;
|
||||
void sendReq(const TcpConnectionPtr &connPtr,
|
||||
void sendReq(const trantor::TcpConnectionPtr &connPtr,
|
||||
const HttpRequestPtr &req);
|
||||
void sendRequestInLoop(const HttpRequestPtr &req,
|
||||
HttpReqCallback &&callback);
|
||||
@ -90,11 +90,11 @@ private:
|
||||
void handleCookies(const HttpResponseImplPtr &resp);
|
||||
void handleResponse(const HttpResponseImplPtr &resp,
|
||||
std::pair<HttpRequestPtr, HttpReqCallback> &&reqAndCb,
|
||||
const TcpConnectionPtr &connPtr);
|
||||
const trantor::TcpConnectionPtr &connPtr);
|
||||
void createTcpClient();
|
||||
std::queue<std::pair<HttpRequestPtr, HttpReqCallback> > pipeliningCallbacks_;
|
||||
std::list<std::pair<HttpRequestPtr, HttpReqCallback> > requestsBuffer_;
|
||||
void onRecvMessage(const TcpConnectionPtr &, MsgBuffer *);
|
||||
void onRecvMessage(const trantor::TcpConnectionPtr &, trantor::MsgBuffer *);
|
||||
void onError(ReqResult result);
|
||||
std::string domain_;
|
||||
size_t pipeliningDepth_{ 0 };
|
||||
@ -103,7 +103,7 @@ private:
|
||||
size_t bytesSent_{ 0 };
|
||||
size_t bytesReceived_{ 0 };
|
||||
bool dns_{ false };
|
||||
std::shared_ptr<Resolver> resolverPtr_;
|
||||
std::shared_ptr<trantor::Resolver> resolverPtr_;
|
||||
bool useOldTLS_{ false };
|
||||
std::string userAgent_{ "DrogonClient" };
|
||||
};
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <http/HttpRequest.h>
|
||||
#include <http/HttpResponse.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <functional>
|
||||
|
||||
#if COZ_PROFILING
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace drogon;
|
||||
|
||||
using namespace trantor;
|
||||
namespace drogon {
|
||||
static HttpResponsePtr getCompressedResponse(const HttpRequestImplPtr &req,
|
||||
const HttpResponsePtr &response,
|
||||
@ -127,7 +127,7 @@ static void defaultWebSockAsyncCallback(
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
static void defaultConnectionCallback(const TcpConnectionPtr &) {
|
||||
static void defaultConnectionCallback(const trantor::TcpConnectionPtr &) {
|
||||
return;
|
||||
}
|
||||
} // namespace drogon
|
||||
@ -218,7 +218,7 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf) {
|
||||
requestParser->requestImpl()->setPeerAddr(conn->peerAddr());
|
||||
requestParser->requestImpl()->setLocalAddr(conn->localAddr());
|
||||
requestParser->requestImpl()->setCreationDate(
|
||||
Date::date());
|
||||
trantor::Date::date());
|
||||
requestParser->requestImpl()->setSecure(
|
||||
conn->isSSLConnection());
|
||||
if (requestParser->firstReq() &&
|
||||
@ -457,7 +457,7 @@ void HttpServer::sendResponse(const TcpConnectionPtr &conn,
|
||||
void HttpServer::sendResponses(
|
||||
const TcpConnectionPtr &conn,
|
||||
const std::vector<std::pair<HttpResponsePtr, bool> > &responses,
|
||||
MsgBuffer &buffer) {
|
||||
trantor::MsgBuffer &buffer) {
|
||||
conn->getLoop()->assertInLoopThread();
|
||||
if (responses.empty())
|
||||
return;
|
||||
|
@ -15,18 +15,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "impl_forwards.h"
|
||||
#include "core/net/tcp_server.h"
|
||||
#include "core/net/callbacks.h"
|
||||
#include <trantor/net/TcpServer.h>
|
||||
#include <trantor/net/callbacks.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace drogon {
|
||||
class HttpServer : NonCopyable {
|
||||
class HttpServer : trantor::NonCopyable {
|
||||
public:
|
||||
HttpServer(EventLoop *loop,
|
||||
const InetAddress &listenAddr,
|
||||
HttpServer(trantor::EventLoop *loop,
|
||||
const trantor::InetAddress &listenAddr,
|
||||
const std::string &name,
|
||||
const std::vector<
|
||||
std::function<HttpResponsePtr(const HttpRequestPtr &)> >
|
||||
@ -37,7 +37,7 @@ public:
|
||||
|
||||
~HttpServer();
|
||||
|
||||
EventLoop *getLoop() const {
|
||||
trantor::EventLoop *getLoop() const {
|
||||
return server_.getLoop();
|
||||
}
|
||||
|
||||
@ -48,11 +48,11 @@ public:
|
||||
void setNewWebsocketCallback(const WebSocketNewAsyncCallback &cb) {
|
||||
newWebsocketCallback_ = cb;
|
||||
}
|
||||
void setConnectionCallback(const ConnectionCallback &cb) {
|
||||
void setConnectionCallback(const trantor::ConnectionCallback &cb) {
|
||||
connectionCallback_ = cb;
|
||||
}
|
||||
void setIoLoopThreadPool(
|
||||
const std::shared_ptr<EventLoopThreadPool> &pool) {
|
||||
const std::shared_ptr<trantor::EventLoopThreadPool> &pool) {
|
||||
server_.setIoLoopThreadPool(pool);
|
||||
}
|
||||
void setIoLoopNum(int numThreads) {
|
||||
@ -61,10 +61,10 @@ public:
|
||||
void kickoffIdleConnections(size_t timeout) {
|
||||
server_.kickoffIdleConnections(timeout);
|
||||
}
|
||||
EventLoop *getLoop() {
|
||||
trantor::EventLoop *getLoop() {
|
||||
return server_.getLoop();
|
||||
}
|
||||
std::vector<EventLoop *> getIoLoops() {
|
||||
std::vector<trantor::EventLoop *> getIoLoops() {
|
||||
return server_.getIoLoops();
|
||||
}
|
||||
void start();
|
||||
@ -78,27 +78,27 @@ public:
|
||||
server_.enableSSL(certPath, keyPath, useOldTLS, sslConfCmds);
|
||||
}
|
||||
|
||||
const InetAddress &address() const {
|
||||
const trantor::InetAddress &address() const {
|
||||
return server_.address();
|
||||
}
|
||||
|
||||
private:
|
||||
void onConnection(const TcpConnectionPtr &conn);
|
||||
void onMessage(const TcpConnectionPtr &, MsgBuffer *);
|
||||
void onRequests(const TcpConnectionPtr &,
|
||||
void onConnection(const trantor::TcpConnectionPtr &conn);
|
||||
void onMessage(const trantor::TcpConnectionPtr &, trantor::MsgBuffer *);
|
||||
void onRequests(const trantor::TcpConnectionPtr &,
|
||||
const std::vector<HttpRequestImplPtr> &,
|
||||
const std::shared_ptr<HttpRequestParser> &);
|
||||
void sendResponse(const TcpConnectionPtr &,
|
||||
void sendResponse(const trantor::TcpConnectionPtr &,
|
||||
const HttpResponsePtr &,
|
||||
bool isHeadMethod);
|
||||
void sendResponses(
|
||||
const TcpConnectionPtr &conn,
|
||||
const trantor::TcpConnectionPtr &conn,
|
||||
const std::vector<std::pair<HttpResponsePtr, bool> > &responses,
|
||||
MsgBuffer &buffer);
|
||||
TcpServer server_;
|
||||
trantor::MsgBuffer &buffer);
|
||||
trantor::TcpServer server_;
|
||||
HttpAsyncCallback httpAsyncCallback_;
|
||||
WebSocketNewAsyncCallback newWebsocketCallback_;
|
||||
ConnectionCallback connectionCallback_;
|
||||
trantor::ConnectionCallback connectionCallback_;
|
||||
const std::vector<std::function<HttpResponsePtr(const HttpRequestPtr &)> >
|
||||
&syncAdvices_;
|
||||
const std::vector<
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/file.h>
|
||||
#include <sys/wait.h>
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
namespace drogon {
|
||||
#ifndef _WIN32
|
||||
class DrogonFileLocker : public NonCopyable {
|
||||
class DrogonFileLocker : public trantor::NonCopyable {
|
||||
public:
|
||||
DrogonFileLocker() {
|
||||
fd_ = open("/tmp/drogon.lock", O_TRUNC | O_CREAT, 0666);
|
||||
@ -45,7 +45,7 @@ private:
|
||||
#endif
|
||||
} // namespace drogon
|
||||
|
||||
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
|
||||
void ListenerManager::addListener(
|
||||
@ -65,7 +65,7 @@ void ListenerManager::addListener(
|
||||
ip, port, useSSL, certFile, keyFile, useOldTLS, sslConfCmds);
|
||||
}
|
||||
|
||||
std::vector<EventLoop *> ListenerManager::createListeners(EventLoop *event_loop,
|
||||
std::vector<trantor::EventLoop *> ListenerManager::createListeners(trantor::EventLoop *event_loop,
|
||||
const HttpAsyncCallback &httpCallback,
|
||||
const WebSocketNewAsyncCallback &webSocketCallback,
|
||||
const ConnectionCallback &connectionCallback,
|
||||
@ -224,7 +224,7 @@ void ListenerManager::startListening() {
|
||||
}
|
||||
}
|
||||
|
||||
EventLoop *ListenerManager::getIOLoop(size_t id) const {
|
||||
trantor::EventLoop *ListenerManager::getIOLoop(size_t id) const {
|
||||
auto const n = listeningloopThreads_.size();
|
||||
if (0 == n) {
|
||||
LOG_WARN << "Please call getIOLoop() after drogon::app().run()";
|
||||
@ -275,8 +275,8 @@ void ListenerManager::stopListening() {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<InetAddress> ListenerManager::getListeners() const {
|
||||
std::vector<InetAddress> listeners;
|
||||
std::vector<trantor::InetAddress> ListenerManager::getListeners() const {
|
||||
std::vector<trantor::InetAddress> listeners;
|
||||
for (auto &server : servers_) {
|
||||
listeners.emplace_back(server->address());
|
||||
}
|
||||
|
@ -15,17 +15,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "impl_forwards.h"
|
||||
#include "core/loops/event_loop_thread_pool.h"
|
||||
#include "core/net/callbacks.h"
|
||||
#include <trantor/net/EventLoopThreadPool.h>
|
||||
#include <trantor/net/callbacks.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace trantor {
|
||||
class InetAddress;
|
||||
|
||||
}
|
||||
namespace drogon {
|
||||
class ListenerManager : public NonCopyable {
|
||||
class ListenerManager : public trantor::NonCopyable {
|
||||
public:
|
||||
void addListener(const std::string &ip,
|
||||
uint16_t port,
|
||||
@ -35,10 +35,10 @@ public:
|
||||
bool useOldTLS = false,
|
||||
const std::vector<std::pair<std::string, std::string> >
|
||||
&sslConfCmds = {});
|
||||
std::vector<EventLoop *> createListeners(EventLoop *event_loop,
|
||||
std::vector<trantor::EventLoop *> createListeners(trantor::EventLoop *event_loop,
|
||||
const HttpAsyncCallback &httpCallback,
|
||||
const WebSocketNewAsyncCallback &webSocketCallback,
|
||||
const ConnectionCallback &connectionCallback,
|
||||
const trantor::ConnectionCallback &connectionCallback,
|
||||
size_t connectionTimeout,
|
||||
const std::string &globalCertFile,
|
||||
const std::string &globalKeyFile,
|
||||
@ -51,12 +51,12 @@ public:
|
||||
const HttpResponsePtr &)> >
|
||||
&preSendingAdvices);
|
||||
void startListening();
|
||||
std::vector<InetAddress> getListeners() const;
|
||||
std::vector<trantor::InetAddress> getListeners() const;
|
||||
~ListenerManager() = default;
|
||||
|
||||
EventLoop *getIOLoop(size_t id) const;
|
||||
trantor::EventLoop *getIOLoop(size_t id) const;
|
||||
void stopListening();
|
||||
std::vector<EventLoop *> ioLoops_;
|
||||
std::vector<trantor::EventLoop *> ioLoops_;
|
||||
|
||||
private:
|
||||
struct ListenerInfo {
|
||||
@ -86,9 +86,9 @@ private:
|
||||
};
|
||||
std::vector<ListenerInfo> listeners_;
|
||||
std::vector<std::shared_ptr<HttpServer> > servers_;
|
||||
std::vector<std::shared_ptr<EventLoopThread> >
|
||||
std::vector<std::shared_ptr<trantor::EventLoopThread> >
|
||||
listeningloopThreads_;
|
||||
std::shared_ptr<EventLoopThreadPool> ioLoopThreadPoolPtr_;
|
||||
std::shared_ptr<trantor::EventLoopThreadPool> ioLoopThreadPoolPtr_;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "PluginsManager.h"
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
namespace drogon {
|
||||
using PluginBasePtr = std::unique_ptr<PluginBase>;
|
||||
|
||||
class PluginsManager : NonCopyable {
|
||||
class PluginsManager : trantor::NonCopyable {
|
||||
public:
|
||||
void initializeAllPlugins(
|
||||
const Json::Value &configs,
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <unistd.h>
|
||||
#include <fstream>
|
||||
static void forEachFileIn(
|
||||
|
@ -15,7 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "core/loops/event_loop_thread.h"
|
||||
#include <trantor/net/EventLoopThread.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -38,7 +38,7 @@
|
||||
#endif
|
||||
|
||||
namespace drogon {
|
||||
class SharedLibManager : public NonCopyable {
|
||||
class SharedLibManager : public trantor::NonCopyable {
|
||||
public:
|
||||
SharedLibManager(const std::vector<std::string> &libPaths,
|
||||
const std::string &outputPath);
|
||||
@ -57,7 +57,7 @@ private:
|
||||
void *loadLib(const std::string &soFile, void *oldHld);
|
||||
bool shouldCompileLib(const std::string &soFile,
|
||||
const struct stat &sourceStat);
|
||||
TimerId timeId_;
|
||||
EventLoopThread workingThread_;
|
||||
trantor::TimerId timeId_;
|
||||
trantor::EventLoopThread workingThread_;
|
||||
};
|
||||
} // namespace drogon
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
void StaticFileRouter::init(const std::vector<EventLoop *> &ioloops) {
|
||||
void StaticFileRouter::init(const std::vector<trantor::EventLoop *> &ioloops) {
|
||||
// Max timeout up to about 70 days;
|
||||
staticFilesCacheMap_ = decltype(staticFilesCacheMap_)(
|
||||
new IOThreadStorage<std::unique_ptr<CacheMap<std::string, char> > >);
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
void setBrStatic(bool useBrStatic) {
|
||||
brStaticFlag_ = useBrStatic;
|
||||
}
|
||||
void init(const std::vector<EventLoop *> &ioloops);
|
||||
void init(const std::vector<trantor::EventLoop *> &ioloops);
|
||||
|
||||
void sendStaticFileResponse(
|
||||
const std::string &filePath,
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "TaskTimeoutFlag.h"
|
||||
using namespace drogon;
|
||||
|
||||
TaskTimeoutFlag::TaskTimeoutFlag(EventLoop *loop,
|
||||
TaskTimeoutFlag::TaskTimeoutFlag(trantor::EventLoop *loop,
|
||||
const std::chrono::duration<double> &timeout,
|
||||
std::function<void()> timeoutCallback) :
|
||||
loop_(loop), timeout_(timeout), timeoutFunc_(timeoutCallback) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
#include "core/loops/event_loop.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
@ -19,10 +19,10 @@
|
||||
#include <memory>
|
||||
|
||||
namespace drogon {
|
||||
class TaskTimeoutFlag : public NonCopyable,
|
||||
class TaskTimeoutFlag : public trantor::NonCopyable,
|
||||
public std::enable_shared_from_this<TaskTimeoutFlag> {
|
||||
public:
|
||||
TaskTimeoutFlag(EventLoop *loop,
|
||||
TaskTimeoutFlag(trantor::EventLoop *loop,
|
||||
const std::chrono::duration<double> &timeout,
|
||||
std::function<void()> timeoutCallback);
|
||||
bool done();
|
||||
@ -30,7 +30,7 @@ public:
|
||||
|
||||
private:
|
||||
std::atomic<bool> isDone_{ false };
|
||||
EventLoop *loop_;
|
||||
trantor::EventLoop *loop_;
|
||||
std::chrono::duration<double> timeout_;
|
||||
std::function<void()> timeoutFunc_;
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include "core/log/logger.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#ifdef OPENSSL_FOUND
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rand.h>
|
||||
@ -838,7 +838,7 @@ std::string gzipDecompress(const char *data, const size_t ndata) {
|
||||
}
|
||||
}
|
||||
|
||||
char *getHttpFullDate(const Date &date) {
|
||||
char *getHttpFullDate(const trantor::Date &date) {
|
||||
static thread_local int64_t lastSecond = 0;
|
||||
static thread_local char lastTimeString[128] = { 0 };
|
||||
auto nowSecond = date.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC;
|
||||
@ -851,7 +851,7 @@ char *getHttpFullDate(const Date &date) {
|
||||
sizeof(lastTimeString));
|
||||
return lastTimeString;
|
||||
}
|
||||
Date getHttpDate(const std::string &httpFullDateString) {
|
||||
trantor::Date getHttpDate(const std::string &httpFullDateString) {
|
||||
static const std::array<const char *, 4> formats = {
|
||||
// RFC822 (default)
|
||||
"%a, %d %b %Y %H:%M:%S",
|
||||
@ -866,11 +866,11 @@ Date getHttpDate(const std::string &httpFullDateString) {
|
||||
for (const char *format : formats) {
|
||||
if (strptime(httpFullDateString.c_str(), format, &tmptm) != NULL) {
|
||||
auto epoch = timegm(&tmptm);
|
||||
return Date(epoch * MICRO_SECONDS_PRE_SEC);
|
||||
return trantor::Date(epoch * MICRO_SECONDS_PRE_SEC);
|
||||
}
|
||||
}
|
||||
LOG_WARN << "invalid datetime format: '" << httpFullDateString << "'";
|
||||
return Date((std::numeric_limits<int64_t>::max)());
|
||||
return trantor::Date((std::numeric_limits<int64_t>::max)());
|
||||
}
|
||||
std::string formattedString(const char *format, ...) {
|
||||
std::string strBuffer(128, 0);
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "WebSocketConnectionImpl.h"
|
||||
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include "core/net/inet_address.h"
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#ifdef OPENSSL_FOUND
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
@ -29,7 +29,7 @@
|
||||
#endif
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
using namespace trantor;
|
||||
|
||||
WebSocketClientImpl::~WebSocketClientImpl() {
|
||||
}
|
||||
@ -39,7 +39,7 @@ WebSocketConnectionPtr WebSocketClientImpl::getConnection() {
|
||||
void WebSocketClientImpl::createTcpClient() {
|
||||
LOG_TRACE << "New TcpClient," << serverAddr_.toIpPort();
|
||||
tcpClientPtr_ =
|
||||
std::make_shared<TcpClient>(loop_, serverAddr_, "httpClient");
|
||||
std::make_shared<trantor::TcpClient>(loop_, serverAddr_, "httpClient");
|
||||
if (useSSL_) {
|
||||
tcpClientPtr_->enableSSL(useOldTLS_, validateCert_, domain_);
|
||||
}
|
||||
@ -47,7 +47,7 @@ void WebSocketClientImpl::createTcpClient() {
|
||||
std::weak_ptr<WebSocketClientImpl> weakPtr = thisPtr;
|
||||
|
||||
tcpClientPtr_->setConnectionCallback(
|
||||
[weakPtr](const TcpConnectionPtr &connPtr) {
|
||||
[weakPtr](const trantor::TcpConnectionPtr &connPtr) {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (!thisPtr)
|
||||
return;
|
||||
@ -74,8 +74,8 @@ void WebSocketClientImpl::createTcpClient() {
|
||||
thisPtr->loop_->runAfter(1.0, [thisPtr]() { thisPtr->reconnect(); });
|
||||
});
|
||||
tcpClientPtr_->setMessageCallback(
|
||||
[weakPtr](const TcpConnectionPtr &connPtr,
|
||||
MsgBuffer *msg) {
|
||||
[weakPtr](const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *msg) {
|
||||
auto thisPtr = weakPtr.lock();
|
||||
if (thisPtr) {
|
||||
thisPtr->onRecvMessage(connPtr, msg);
|
||||
@ -124,12 +124,12 @@ void WebSocketClientImpl::connectToServerInLoop() {
|
||||
if (serverAddr_.ipNetEndian() == 0 && !hasIpv6Address && !domain_.empty() &&
|
||||
serverAddr_.portNetEndian() != 0) {
|
||||
if (!resolver_) {
|
||||
resolver_ = Resolver::newResolver(loop_);
|
||||
resolver_ = trantor::Resolver::newResolver(loop_);
|
||||
}
|
||||
resolver_->resolve(
|
||||
domain_,
|
||||
[thisPtr = shared_from_this(),
|
||||
hasIpv6Address](const InetAddress &addr) {
|
||||
hasIpv6Address](const trantor::InetAddress &addr) {
|
||||
thisPtr->loop_->runInLoop([thisPtr, addr, hasIpv6Address]() {
|
||||
auto port = thisPtr->serverAddr_.portNetEndian();
|
||||
thisPtr->serverAddr_ = addr;
|
||||
@ -163,15 +163,15 @@ void WebSocketClientImpl::connectToServerInLoop() {
|
||||
}
|
||||
|
||||
void WebSocketClientImpl::onRecvWsMessage(
|
||||
const TcpConnectionPtr &connPtr,
|
||||
MsgBuffer *msgBuffer) {
|
||||
const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *msgBuffer) {
|
||||
assert(websockConnPtr_);
|
||||
websockConnPtr_->onNewMessage(connPtr, msgBuffer);
|
||||
}
|
||||
|
||||
void WebSocketClientImpl::onRecvMessage(
|
||||
const TcpConnectionPtr &connPtr,
|
||||
MsgBuffer *msgBuffer) {
|
||||
const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *msgBuffer) {
|
||||
if (upgraded_) {
|
||||
onRecvWsMessage(connPtr, msgBuffer);
|
||||
return;
|
||||
@ -244,8 +244,8 @@ void WebSocketClientImpl::reconnect() {
|
||||
connectToServerInLoop();
|
||||
}
|
||||
|
||||
WebSocketClientImpl::WebSocketClientImpl(EventLoop *loop,
|
||||
const InetAddress &addr,
|
||||
WebSocketClientImpl::WebSocketClientImpl(trantor::EventLoop *loop,
|
||||
const trantor::InetAddress &addr,
|
||||
bool useSSL,
|
||||
bool useOldTLS,
|
||||
bool validateCert) :
|
||||
@ -256,7 +256,7 @@ WebSocketClientImpl::WebSocketClientImpl(EventLoop *loop,
|
||||
validateCert_(validateCert) {
|
||||
}
|
||||
|
||||
WebSocketClientImpl::WebSocketClientImpl(EventLoop *loop,
|
||||
WebSocketClientImpl::WebSocketClientImpl(trantor::EventLoop *loop,
|
||||
const std::string &hostString,
|
||||
bool useOldTLS,
|
||||
bool validateCert) :
|
||||
@ -325,8 +325,8 @@ WebSocketClientImpl::WebSocketClientImpl(EventLoop *loop,
|
||||
LOG_TRACE << "userSSL=" << useSSL_ << " domain=" << domain_;
|
||||
}
|
||||
|
||||
void WebSocketClientImpl::sendReq(const TcpConnectionPtr &connPtr) {
|
||||
MsgBuffer buffer;
|
||||
void WebSocketClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr) {
|
||||
trantor::MsgBuffer buffer;
|
||||
assert(upgradeRequest_);
|
||||
auto implPtr = static_cast<HttpRequestImpl *>(upgradeRequest_.get());
|
||||
implPtr->appendToBuffer(&buffer);
|
||||
@ -356,13 +356,13 @@ void WebSocketClientImpl::connectToServer(
|
||||
WebSocketClientPtr WebSocketClient::newWebSocketClient(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL,
|
||||
EventLoop *loop,
|
||||
trantor::EventLoop *loop,
|
||||
bool useOldTLS,
|
||||
bool validateCert) {
|
||||
bool isIpv6 = ip.find(':') == std::string::npos ? false : true;
|
||||
return std::make_shared<WebSocketClientImpl>(
|
||||
loop == nullptr ? HttpAppFrameworkImpl::instance().getLoop() : loop,
|
||||
InetAddress(ip, port, isIpv6),
|
||||
trantor::InetAddress(ip, port, isIpv6),
|
||||
useSSL,
|
||||
useOldTLS,
|
||||
validateCert);
|
||||
@ -370,7 +370,7 @@ WebSocketClientPtr WebSocketClient::newWebSocketClient(const std::string &ip,
|
||||
|
||||
WebSocketClientPtr WebSocketClient::newWebSocketClient(
|
||||
const std::string &hostString,
|
||||
EventLoop *loop,
|
||||
trantor::EventLoop *loop,
|
||||
bool useOldTLS,
|
||||
bool validateCert) {
|
||||
return std::make_shared<WebSocketClientImpl>(
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
#include "impl_forwards.h"
|
||||
#include <drogon/WebSocketClient.h>
|
||||
#include "core/loops/event_loop.h"
|
||||
#include "core/net/tcp_client.h"
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/TcpClient.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
|
||||
#include <memory>
|
||||
@ -47,17 +47,17 @@ public:
|
||||
void connectToServer(const HttpRequestPtr &request,
|
||||
const WebSocketRequestCallback &callback) override;
|
||||
|
||||
EventLoop *getLoop() override {
|
||||
trantor::EventLoop *getLoop() override {
|
||||
return loop_;
|
||||
}
|
||||
|
||||
WebSocketClientImpl(EventLoop *loop,
|
||||
const InetAddress &addr,
|
||||
WebSocketClientImpl(trantor::EventLoop *loop,
|
||||
const trantor::InetAddress &addr,
|
||||
bool useSSL = false,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
|
||||
WebSocketClientImpl(EventLoop *loop,
|
||||
WebSocketClientImpl(trantor::EventLoop *loop,
|
||||
const std::string &hostString,
|
||||
bool useOldTLS = false,
|
||||
bool validateCert = true);
|
||||
@ -65,9 +65,9 @@ public:
|
||||
~WebSocketClientImpl() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<TcpClient> tcpClientPtr_;
|
||||
EventLoop *loop_;
|
||||
InetAddress serverAddr_;
|
||||
std::shared_ptr<trantor::TcpClient> tcpClientPtr_;
|
||||
trantor::EventLoop *loop_;
|
||||
trantor::InetAddress serverAddr_;
|
||||
std::string domain_;
|
||||
bool useSSL_{ false };
|
||||
bool useOldTLS_{ false };
|
||||
@ -89,13 +89,13 @@ private:
|
||||
WebSocketConnectionImplPtr websockConnPtr_;
|
||||
|
||||
void connectToServerInLoop();
|
||||
void sendReq(const TcpConnectionPtr &connPtr);
|
||||
void onRecvMessage(const TcpConnectionPtr &, MsgBuffer *);
|
||||
void onRecvWsMessage(const TcpConnectionPtr &,
|
||||
MsgBuffer *);
|
||||
void sendReq(const trantor::TcpConnectionPtr &connPtr);
|
||||
void onRecvMessage(const trantor::TcpConnectionPtr &, trantor::MsgBuffer *);
|
||||
void onRecvWsMessage(const trantor::TcpConnectionPtr &,
|
||||
trantor::MsgBuffer *);
|
||||
void reconnect();
|
||||
void createTcpClient();
|
||||
std::shared_ptr<Resolver> resolver_;
|
||||
std::shared_ptr<trantor::Resolver> resolver_;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user