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:
Relintai 2022-02-12 10:42:45 +01:00
parent c679ad05f4
commit 75c5145370
211 changed files with 8864 additions and 6660 deletions

View File

@ -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")

View File

@ -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);
};

View File

@ -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_;
};

View File

@ -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([]() {
});
}

View File

@ -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};
};

View File

@ -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() {
}
};

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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_;
}

View File

@ -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

View File

@ -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_;
};

View File

@ -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();
});
}

View File

@ -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_;
};

View File

@ -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;
}

View File

@ -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_;
};

View File

@ -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_;
}

View File

@ -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_;
};

View File

@ -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_;
};

View File

@ -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

View File

@ -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
}
}

View File

@ -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();
};

View File

@ -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)>;

View File

@ -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_();
}
}

View File

@ -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_;
};

View File

@ -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>;

View File

@ -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);
};

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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();
};

View File

@ -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_;
};

View File

@ -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_;
};

View File

@ -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
}
};

View File

@ -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
};

View File

@ -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_;
};

View File

@ -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_;
};

View File

@ -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
}

View File

@ -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_;
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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:
};

View File

@ -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])

View File

@ -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"])

View File

@ -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()

View File

@ -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 {

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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 &registerNewConnectionAdvice(
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

View File

@ -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);

View File

@ -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>

View File

@ -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)>;

View File

@ -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);

View File

@ -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;

View File

@ -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>

View File

@ -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) :

View File

@ -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 &);
};

View File

@ -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() {

View File

@ -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, ...);

View File

@ -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 {

View File

@ -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>

View File

@ -13,7 +13,7 @@
*/
#include "CacheFile.h"
#include "core/log/logger.h"
#include <trantor/utils/Logger.h>
#ifdef _WIN32
#include <mman.h>
#else

View File

@ -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();

View File

@ -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_;

View File

@ -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_;

View File

@ -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();
}

View File

@ -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 ");

View File

@ -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_;

View File

@ -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

View File

@ -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_;

View File

@ -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();
}

View File

@ -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 {

View File

@ -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 };

View File

@ -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) {

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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>

View File

@ -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;

View File

@ -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

View File

@ -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());

View File

@ -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(

View File

@ -114,8 +114,8 @@ public:
}
HttpAppFramework &registerNewConnectionAdvice(
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_;

View File

@ -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>(

View File

@ -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" };
};

View File

@ -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;

View File

@ -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<

View File

@ -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());
}

View File

@ -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

View File

@ -13,7 +13,7 @@
*/
#include "PluginsManager.h"
#include "core/log/logger.h"
#include <trantor/utils/Logger.h>
using namespace drogon;

View File

@ -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,

View File

@ -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(

View File

@ -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

View File

@ -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> > >);

View File

@ -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,

View File

@ -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) {

View File

@ -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_;
};

View File

@ -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);

View File

@ -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>(

View File

@ -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