diff --git a/modules/trantor/SCsub b/modules/trantor/SCsub deleted file mode 100644 index 53b7f1a..0000000 --- a/modules/trantor/SCsub +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -Import("env_mod") -Import("env") - -env_mod.core_sources = [] - -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") - -#windows only -#env_mod.add_source_files(env_mod.core_sources, "third_party/wepoll/*.c") -#env_mod.add_source_files(env_mod.core_sources, "trantor/utils/WindowsSupport.cc") - -# Build it all as a library -lib = env_mod.add_library("trantor", env_mod.core_sources) -env.Prepend(LIBS=[lib]) diff --git a/modules/trantor/detect.py b/modules/trantor/detect.py deleted file mode 100644 index 93eece8..0000000 --- a/modules/trantor/detect.py +++ /dev/null @@ -1,34 +0,0 @@ -import os -import platform -import sys - - -def is_active(): - return True - - -def get_name(): - return "trantor" - - -def can_build(): - return False - - -def get_opts(): - return [] - -def get_flags(): - - return [] - - -def configure(env): - #env.Append(CXX=["-std=c++17"]) - - env.Prepend(CPPPATH=["#modules/trantor"]) - env.Prepend(CPPPATH=["#modules/trantor/trantor/net"]) - env.Prepend(CPPPATH=["#modules/trantor/trantor/net/inner"]) - env.Prepend(CPPPATH=["#modules/trantor/trantor/utils"]) - - diff --git a/modules/trantor/trantor/HEAD b/modules/trantor/trantor/HEAD deleted file mode 100644 index b47dacd..0000000 --- a/modules/trantor/trantor/HEAD +++ /dev/null @@ -1 +0,0 @@ -255976d89866d556efd24264f65765f3e02bc32b \ No newline at end of file diff --git a/modules/trantor/trantor/License b/modules/trantor/trantor/License deleted file mode 100644 index 277f5cd..0000000 --- a/modules/trantor/trantor/License +++ /dev/null @@ -1,57 +0,0 @@ -// Trantor - A non-blocking I/O based TCP network library, using C++14/17, -// Copyright (c) 2016-2021, Tao An. All rights reserved. -// https://github.com/an-tao/trantor -// -// 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. - -// Muduo - A reactor-based C++ network library for Linux -// Copyright (c) 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// 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 Shuo Chen 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. diff --git a/modules/trantor/trantor/README.md b/modules/trantor/trantor/README.md deleted file mode 100755 index a76aa4e..0000000 --- a/modules/trantor/trantor/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# TRANTOR - -[![Build Status](https://travis-ci.org/an-tao/trantor.svg?branch=master)](https://travis-ci.org/an-tao/trantor) -[![Build status](https://ci.appveyor.com/api/projects/status/yn8xunsubn37pi1u/branch/master?svg=true)](https://ci.appveyor.com/project/an-tao/trantor/branch/master) -[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/an-tao/trantor.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/an-tao/trantor/context:cpp) - - -## Overview -A non-blocking I/O cross-platform TCP network library, using C++14. -Drawing on the design of Muduo Library - -## suported platforms -- Linux -- MacOS -- UNIX(BSD) -- Windows - -## Feature highlights -- non-blocking I/O -- cross-platform -- Thread pool -- Lock free design -- Support SSL -- Server and Client - - -## Build -```shell -git clone https://github.com/an-tao/trantor.git -cd trantor -cmake -Bbuild -H. -cd build -make -j -``` - -## Licensing -Trantor - A non-blocking I/O based TCP network library, using C++14. - -Copyright (c) 2016-2021, Tao An. All rights reserved. - -https://github.com/an-tao/trantor - -For more information see [License](License) - -## Community -[Gitter](https://gitter.im/drogon-web/community) - -## Documentation -[DocsForge](https://trantor.docsforge.com/) diff --git a/modules/trantor/trantor/exports.h b/modules/trantor/trantor/exports.h deleted file mode 100644 index 9f5f910..0000000 --- a/modules/trantor/trantor/exports.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef TRANTOR_EXPORT_H -#define TRANTOR_EXPORT_H - -#ifdef TRANTOR_STATIC_DEFINE -# define TRANTOR_EXPORT -# define TRANTOR_NO_EXPORT -#else -# ifndef TRANTOR_EXPORT -# ifdef trantor_EXPORTS - /* We are building this library */ -# define TRANTOR_EXPORT -# else - /* We are using this library */ -# define TRANTOR_EXPORT -# endif -# endif - -# ifndef TRANTOR_NO_EXPORT -# define TRANTOR_NO_EXPORT -# endif -#endif - -#ifndef TRANTOR_DEPRECATED -# define TRANTOR_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#ifndef TRANTOR_DEPRECATED_EXPORT -# define TRANTOR_DEPRECATED_EXPORT TRANTOR_EXPORT TRANTOR_DEPRECATED -#endif - -#ifndef TRANTOR_DEPRECATED_NO_EXPORT -# define TRANTOR_DEPRECATED_NO_EXPORT TRANTOR_NO_EXPORT TRANTOR_DEPRECATED -#endif - -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef TRANTOR_NO_DEPRECATED -# define TRANTOR_NO_DEPRECATED -# endif -#endif - -#endif /* TRANTOR_EXPORT_H */ diff --git a/modules/trantor/trantor/net/Channel.cc b/modules/trantor/trantor/net/Channel.cc deleted file mode 100644 index eaceea1..0000000 --- a/modules/trantor/trantor/net/Channel.cc +++ /dev/null @@ -1,110 +0,0 @@ -/** - * - * Channel.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "Channel.h" -#include -#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 -#endif -#include -namespace trantor -{ -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_="< 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_(); - } -} - -} // namespace trantor diff --git a/modules/trantor/trantor/net/Channel.h b/modules/trantor/trantor/net/Channel.h deleted file mode 100644 index 7060ee5..0000000 --- a/modules/trantor/trantor/net/Channel.h +++ /dev/null @@ -1,314 +0,0 @@ -/** - * - * @file Channel.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -namespace trantor -{ -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 TRANTOR_EXPORT Channel : NonCopyable -{ - public: - using EventCallback = std::function; - /** - * @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 &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="< tie_; - bool tied_; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/EventLoop.cc b/modules/trantor/trantor/net/EventLoop.cc deleted file mode 100644 index 8a60a03..0000000 --- a/modules/trantor/trantor/net/EventLoop.cc +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Shuo Chen (chenshuo at chenshuo dot com) - -// Taken from Muduo and modified -// Copyright 2016, Tao An. All rights reserved. -// https://github.com/an-tao/trantor -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#include -#include - -#include "Poller.h" -#include "TimerQueue.h" -#include "Channel.h" - -#include -#include -#ifdef _WIN32 -#include -using ssize_t = long long; -#else -#include -#endif -#include -#ifdef __linux__ -#include -#endif -#include -#ifndef _WIN32 -#include -#endif -#include -#include -#include - -namespace trantor -{ -#ifdef __linux__ -int createEventfd() -{ - int evtfd = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - if (evtfd < 0) - { - std::cout << "Failed in eventfd" << std::endl; - abort(); - } - - return evtfd; -} -const int kPollTimeMs = 10000; -#endif -thread_local EventLoop *t_loopInThisThread = nullptr; - -EventLoop::EventLoop() - : looping_(false), - threadId_(std::this_thread::get_id()), - quit_(false), - poller_(Poller::newPoller(this)), - currentActiveChannel_(nullptr), - eventHandling_(false), - timerQueue_(new TimerQueue(this)), -#ifdef __linux__ - wakeupFd_(createEventfd()), - wakeupChannelPtr_(new Channel(this, wakeupFd_)), -#endif - threadLocalLoopPtr_(&t_loopInThisThread) -{ - if (t_loopInThisThread) - { - LOG_FATAL << "There is already an EventLoop in this thread"; - exit(-1); - } - t_loopInThisThread = this; -#ifdef __linux__ - wakeupChannelPtr_->setReadCallback(std::bind(&EventLoop::wakeupRead, this)); - wakeupChannelPtr_->enableReading(); -#elif !defined _WIN32 - auto r = pipe(wakeupFd_); - (void)r; - assert(!r); - fcntl(wakeupFd_[0], F_SETFL, O_NONBLOCK | O_CLOEXEC); - fcntl(wakeupFd_[1], F_SETFL, O_NONBLOCK | O_CLOEXEC); - wakeupChannelPtr_ = - std::unique_ptr(new Channel(this, wakeupFd_[0])); - wakeupChannelPtr_->setReadCallback(std::bind(&EventLoop::wakeupRead, this)); - wakeupChannelPtr_->enableReading(); -#else - poller_->setEventCallback([](uint64_t event) { assert(event == 1); }); -#endif -} -#ifdef __linux__ -void EventLoop::resetTimerQueue() -{ - assertInLoopThread(); - assert(!looping_); - timerQueue_->reset(); -} -#endif -void EventLoop::resetAfterFork() -{ - poller_->resetAfterFork(); -} -EventLoop::~EventLoop() -{ - quit(); - assert(!looping_); - t_loopInThisThread = nullptr; -#ifdef __linux__ - close(wakeupFd_); -#elif defined _WIN32 -#else - close(wakeupFd_[0]); - close(wakeupFd_[1]); -#endif -} -EventLoop *EventLoop::getEventLoopOfCurrentThread() -{ - return t_loopInThisThread; -} -void EventLoop::updateChannel(Channel *channel) -{ - assert(channel->ownerLoop() == this); - assertInLoopThread(); - poller_->updateChannel(channel); -} -void EventLoop::removeChannel(Channel *channel) -{ - assert(channel->ownerLoop() == this); - assertInLoopThread(); - if (eventHandling_) - { - assert(currentActiveChannel_ == channel || - std::find(activeChannels_.begin(), - activeChannels_.end(), - channel) == activeChannels_.end()); - } - poller_->removeChannel(channel); -} -void EventLoop::quit() -{ - quit_ = true; - - Func f; - while (funcsOnQuit_.dequeue(f)) - { - f(); - } - - // There is a chance that loop() just executes while(!quit_) and exits, - // then EventLoop destructs, then we are accessing an invalid object. - // Can be fixed using mutex_ in both places. - if (!isInLoopThread()) - { - wakeup(); - } -} -void EventLoop::loop() -{ - assert(!looping_); - assertInLoopThread(); - looping_ = true; - quit_ = false; - - while (!quit_) - { - activeChannels_.clear(); -#ifdef __linux__ - poller_->poll(kPollTimeMs, &activeChannels_); -#else - poller_->poll(static_cast(timerQueue_->getTimeout()), - &activeChannels_); - timerQueue_->processTimers(); -#endif - // TODO sort channel by priority - // std::cout<<"after ->poll()"<handleEvent(); - } - currentActiveChannel_ = NULL; - eventHandling_ = false; - // std::cout << "looping" << endl; - doRunInLoopFuncs(); - } - looping_ = false; -} -void EventLoop::abortNotInLoopThread() -{ - LOG_FATAL << "It is forbidden to run loop on threads other than event-loop " - "thread"; - exit(1); -} -void EventLoop::runInLoop(const Func &cb) -{ - if (isInLoopThread()) - { - cb(); - } - else - { - queueInLoop(cb); - } -} -void EventLoop::runInLoop(Func &&cb) -{ - if (isInLoopThread()) - { - cb(); - } - else - { - queueInLoop(std::move(cb)); - } -} -void EventLoop::queueInLoop(const Func &cb) -{ - funcs_.enqueue(cb); - if (!isInLoopThread() || !looping_) - { - wakeup(); - } -} -void EventLoop::queueInLoop(Func &&cb) -{ - funcs_.enqueue(std::move(cb)); - if (!isInLoopThread() || !looping_) - { - wakeup(); - } -} - -TimerId EventLoop::runAt(const Date &time, const Func &cb) -{ - auto microSeconds = - time.microSecondsSinceEpoch() - Date::now().microSecondsSinceEpoch(); - std::chrono::steady_clock::time_point tp = - std::chrono::steady_clock::now() + - std::chrono::microseconds(microSeconds); - return timerQueue_->addTimer(cb, tp, std::chrono::microseconds(0)); -} -TimerId EventLoop::runAt(const Date &time, Func &&cb) -{ - auto microSeconds = - time.microSecondsSinceEpoch() - Date::now().microSecondsSinceEpoch(); - std::chrono::steady_clock::time_point tp = - std::chrono::steady_clock::now() + - std::chrono::microseconds(microSeconds); - return timerQueue_->addTimer(std::move(cb), - tp, - std::chrono::microseconds(0)); -} -TimerId EventLoop::runAfter(double delay, const Func &cb) -{ - return runAt(Date::date().after(delay), cb); -} -TimerId EventLoop::runAfter(double delay, Func &&cb) -{ - return runAt(Date::date().after(delay), std::move(cb)); -} -TimerId EventLoop::runEvery(double interval, const Func &cb) -{ - std::chrono::microseconds dur( - static_cast(interval * 1000000)); - auto tp = std::chrono::steady_clock::now() + dur; - return timerQueue_->addTimer(cb, tp, dur); -} -TimerId EventLoop::runEvery(double interval, Func &&cb) -{ - std::chrono::microseconds dur( - static_cast(interval * 1000000)); - auto tp = std::chrono::steady_clock::now() + dur; - return timerQueue_->addTimer(std::move(cb), tp, dur); -} -void EventLoop::invalidateTimer(TimerId id) -{ - if (isRunning() && timerQueue_) - timerQueue_->invalidateTimer(id); -} -void EventLoop::doRunInLoopFuncs() -{ - callingFuncs_ = true; - { - // the destructor for the Func may itself insert a new entry into the - // queue - while (!funcs_.empty()) - { - Func func; - while (funcs_.dequeue(func)) - { - func(); - } - } - } - callingFuncs_ = false; -} -void EventLoop::wakeup() -{ - // if (!looping_) - // return; - uint64_t tmp = 1; -#ifdef __linux__ - int ret = write(wakeupFd_, &tmp, sizeof(tmp)); - (void)ret; -#elif defined _WIN32 - poller_->postEvent(1); -#else - int ret = write(wakeupFd_[1], &tmp, sizeof(tmp)); - (void)ret; -#endif -} -void EventLoop::wakeupRead() -{ - ssize_t ret = 0; -#ifdef __linux__ - uint64_t tmp; - ret = read(wakeupFd_, &tmp, sizeof(tmp)); -#elif defined _WIN32 -#else - uint64_t tmp; - ret = read(wakeupFd_[0], &tmp, sizeof(tmp)); -#endif - if (ret < 0) - LOG_SYSERR << "wakeup read error"; -} - -void EventLoop::moveToCurrentThread() -{ - if (isRunning()) - { - LOG_FATAL << "EventLoop cannot be moved when running"; - exit(-1); - } - if (isInLoopThread()) - { - LOG_WARN << "This EventLoop is already in the current thread"; - return; - } - if (t_loopInThisThread) - { - LOG_FATAL << "There is already an EventLoop in this thread, you cannot " - "move another in"; - exit(-1); - } - *threadLocalLoopPtr_ = nullptr; - t_loopInThisThread = this; - threadLocalLoopPtr_ = &t_loopInThisThread; - threadId_ = std::this_thread::get_id(); -} - -void EventLoop::runOnQuit(Func &&cb) -{ - funcsOnQuit_.enqueue(std::move(cb)); -} - -void EventLoop::runOnQuit(const Func &cb) -{ - funcsOnQuit_.enqueue(cb); -} - -} // namespace trantor diff --git a/modules/trantor/trantor/net/EventLoop.h b/modules/trantor/trantor/net/EventLoop.h deleted file mode 100644 index d28f6b8..0000000 --- a/modules/trantor/trantor/net/EventLoop.h +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Shuo Chen (chenshuo at chenshuo dot com) - -// Taken from Muduo and modified -// Copyright 2016, Tao An. All rights reserved. -// https://github.com/an-tao/trantor -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -class Poller; -class TimerQueue; -class Channel; -using ChannelList = std::vector; -using Func = std::function; -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 TRANTOR_EXPORT EventLoop : NonCopyable -{ - 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 &delay, const Func &cb) - { - return runAfter(delay.count(), cb); - } - TimerId runAfter(const std::chrono::duration &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 &interval, - const Func &cb) - { - return runEvery(interval.count(), cb); - } - TimerId runEvery(const std::chrono::duration &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_; - - ChannelList activeChannels_; - Channel *currentActiveChannel_; - - bool eventHandling_; - MpscQueue funcs_; - std::unique_ptr timerQueue_; - MpscQueue funcsOnQuit_; - bool callingFuncs_{false}; -#ifdef __linux__ - int wakeupFd_; - std::unique_ptr wakeupChannelPtr_; -#elif defined _WIN32 -#else - int wakeupFd_[2]; - std::unique_ptr wakeupChannelPtr_; -#endif - - void doRunInLoopFuncs(); -#ifdef _WIN32 - size_t index_{size_t(-1)}; -#else - size_t index_{std::numeric_limits::max()}; -#endif - EventLoop **threadLocalLoopPtr_; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/EventLoopThread.cc b/modules/trantor/trantor/net/EventLoopThread.cc deleted file mode 100644 index 39ee02e..0000000 --- a/modules/trantor/trantor/net/EventLoopThread.cc +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * @file EventLoopThread.cc - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include -#ifdef __linux__ -#include -#endif - -using namespace trantor; -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(); - }); -} diff --git a/modules/trantor/trantor/net/EventLoopThread.h b/modules/trantor/trantor/net/EventLoopThread.h deleted file mode 100644 index 4d9caa1..0000000 --- a/modules/trantor/trantor/net/EventLoopThread.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * @file EventLoopThread.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -/** - * @brief This class represents an event loop thread. - * - */ -class TRANTOR_EXPORT EventLoopThread : NonCopyable -{ - 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 promiseForLoopPointer_; - std::promise promiseForRun_; - std::promise promiseForLoop_; - std::once_flag once_; - std::thread thread_; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/EventLoopThreadPool.cc b/modules/trantor/trantor/net/EventLoopThreadPool.cc deleted file mode 100644 index c96927b..0000000 --- a/modules/trantor/trantor/net/EventLoopThreadPool.cc +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * EventLoopThreadPool.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -using namespace trantor; -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(name)); - } -} -void EventLoopThreadPool::start() -{ - for (unsigned int i = 0; i < loopThreadVector_.size(); ++i) - { - loopThreadVector_[i]->run(); - } -} -// void EventLoopThreadPool::stop(){ -// for(unsigned int i=0;iwait(); - } -} -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 EventLoopThreadPool::getLoops() const -{ - std::vector ret; - for (auto &loopThread : loopThreadVector_) - { - ret.push_back(loopThread->getLoop()); - } - return ret; -} \ No newline at end of file diff --git a/modules/trantor/trantor/net/EventLoopThreadPool.h b/modules/trantor/trantor/net/EventLoopThreadPool.h deleted file mode 100644 index 6332169..0000000 --- a/modules/trantor/trantor/net/EventLoopThreadPool.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * - * @file EventLoopThreadPool.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include - -namespace trantor -{ -/** - * @brief This class represents a pool of EventLoopThread objects - * - */ -class TRANTOR_EXPORT EventLoopThreadPool : NonCopyable -{ - 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 - */ - std::vector getLoops() const; - - private: - std::vector> loopThreadVector_; - size_t loopIndex_; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/InetAddress.cc b/modules/trantor/trantor/net/InetAddress.cc deleted file mode 100644 index 18b952a..0000000 --- a/modules/trantor/trantor/net/InetAddress.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Shuo Chen (chenshuo at chenshuo dot com) - -#include - -#include -//#include - -#ifdef _WIN32 -struct in6_addr_uint -{ - union - { - u_char Byte[16]; - u_short Word[8]; - uint32_t __s6_addr32[4]; - } uext; -}; -#else -#include // memset -#include -#include -#endif - -// INADDR_ANY use (type)value casting. -static const in_addr_t kInaddrAny = INADDR_ANY; -static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK; - -// /* Structure describing an Internet socket address. */ -// struct sockaddr_in { -// sa_family_t sin_family; /* address family: AF_INET */ -// uint16_t sin_port; /* port in network byte order */ -// struct in_addr sin_addr; /* internet address */ -// }; - -// /* Internet address. */ -// typedef uint32_t in_addr_t; -// struct in_addr { -// in_addr_t s_addr; /* address in network byte order */ -// }; - -// struct sockaddr_in6 { -// sa_family_t sin6_family; /* address family: AF_INET6 */ -// uint16_t sin6_port; /* port in network byte order */ -// uint32_t sin6_flowinfo; /* IPv6 flow information */ -// struct in6_addr sin6_addr; /* IPv6 address */ -// uint32_t sin6_scope_id; /* IPv6 scope-id */ -// }; - -using namespace trantor; - -/* -#ifdef __linux__ -#if !(__GNUC_PREREQ(4, 6)) -#pragma GCC diagnostic ignored "-Winvalid-offsetof" -#endif -#endif -*/ - -InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6) - : isIpV6_(ipv6) -{ - if (ipv6) - { - memset(&addr6_, 0, sizeof(addr6_)); - addr6_.sin6_family = AF_INET6; - in6_addr ip = loopbackOnly ? in6addr_loopback : in6addr_any; - addr6_.sin6_addr = ip; - addr6_.sin6_port = htons(port); - } - else - { - memset(&addr_, 0, sizeof(addr_)); - addr_.sin_family = AF_INET; - in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny; - addr_.sin_addr.s_addr = htonl(ip); - addr_.sin_port = htons(port); - } - isUnspecified_ = false; -} - -InetAddress::InetAddress(const std::string &ip, uint16_t port, bool ipv6) - : isIpV6_(ipv6) -{ - if (ipv6) - { - memset(&addr6_, 0, sizeof(addr6_)); - addr6_.sin6_family = AF_INET6; - addr6_.sin6_port = htons(port); - if (::inet_pton(AF_INET6, ip.c_str(), &addr6_.sin6_addr) <= 0) - { - return; - } - } - else - { - memset(&addr_, 0, sizeof(addr_)); - addr_.sin_family = AF_INET; - addr_.sin_port = htons(port); - if (::inet_pton(AF_INET, ip.c_str(), &addr_.sin_addr) <= 0) - { - return; - } - } - isUnspecified_ = false; -} - -std::string InetAddress::toIpPort() const -{ - char buf[64] = ""; - uint16_t port = ntohs(addr_.sin_port); - snprintf(buf, sizeof(buf), ":%u", port); - return toIp() + std::string(buf); -} -bool InetAddress::isIntranetIp() const -{ - if (addr_.sin_family == AF_INET) - { - uint32_t ip_addr = ntohl(addr_.sin_addr.s_addr); - if ((ip_addr >= 0x0A000000 && ip_addr <= 0x0AFFFFFF) || - (ip_addr >= 0xAC100000 && ip_addr <= 0xAC1FFFFF) || - (ip_addr >= 0xC0A80000 && ip_addr <= 0xC0A8FFFF) || - ip_addr == 0x7f000001) - - { - return true; - } - } - else - { - auto addrP = ip6NetEndian(); - // Loopback ip - if (*addrP == 0 && *(addrP + 1) == 0 && *(addrP + 2) == 0 && - ntohl(*(addrP + 3)) == 1) - return true; - // Privated ip is prefixed by FEC0::/10 or FE80::/10, need testing - auto i32 = (ntohl(*addrP) & 0xffc00000); - if (i32 == 0xfec00000 || i32 == 0xfe800000) - return true; - if (*addrP == 0 && *(addrP + 1) == 0 && ntohl(*(addrP + 2)) == 0xffff) - { - // the IPv6 version of an IPv4 IP address - uint32_t ip_addr = ntohl(*(addrP + 3)); - if ((ip_addr >= 0x0A000000 && ip_addr <= 0x0AFFFFFF) || - (ip_addr >= 0xAC100000 && ip_addr <= 0xAC1FFFFF) || - (ip_addr >= 0xC0A80000 && ip_addr <= 0xC0A8FFFF) || - ip_addr == 0x7f000001) - - { - return true; - } - } - } - return false; -} - -bool InetAddress::isLoopbackIp() const -{ - if (!isIpV6()) - { - uint32_t ip_addr = ntohl(addr_.sin_addr.s_addr); - if (ip_addr == 0x7f000001) - { - return true; - } - } - else - { - auto addrP = ip6NetEndian(); - if (*addrP == 0 && *(addrP + 1) == 0 && *(addrP + 2) == 0 && - ntohl(*(addrP + 3)) == 1) - return true; - // the IPv6 version of an IPv4 loopback address - if (*addrP == 0 && *(addrP + 1) == 0 && ntohl(*(addrP + 2)) == 0xffff && - ntohl(*(addrP + 3)) == 0x7f000001) - return true; - } - return false; -} - -std::string InetAddress::toIp() const -{ - char buf[64]; - if (addr_.sin_family == AF_INET) - { -#if defined _MSC_VER && _MSC_VER >= 1900 - ::inet_ntop(AF_INET, (PVOID)&addr_.sin_addr, buf, sizeof(buf)); -#else - ::inet_ntop(AF_INET, &addr_.sin_addr, buf, sizeof(buf)); -#endif - } - else if (addr_.sin_family == AF_INET6) - { -#if defined _MSC_VER && _MSC_VER >= 1900 - ::inet_ntop(AF_INET6, (PVOID)&addr6_.sin6_addr, buf, sizeof(buf)); -#else - ::inet_ntop(AF_INET6, &addr6_.sin6_addr, buf, sizeof(buf)); -#endif - } - - return buf; -} - -uint32_t InetAddress::ipNetEndian() const -{ - // assert(family() == AF_INET); - return addr_.sin_addr.s_addr; -} - -const uint32_t *InetAddress::ip6NetEndian() const -{ -// assert(family() == AF_INET6); -#ifdef __linux__ - return addr6_.sin6_addr.s6_addr32; -#elif defined _WIN32 - // TODO is this OK ? - const struct in6_addr_uint *addr_temp = - reinterpret_cast(&addr6_.sin6_addr); - return (*addr_temp).uext.__s6_addr32; -#else - return addr6_.sin6_addr.__u6_addr.__u6_addr32; -#endif -} -uint16_t InetAddress::toPort() const -{ - return ntohs(portNetEndian()); -} diff --git a/modules/trantor/trantor/net/InetAddress.h b/modules/trantor/trantor/net/InetAddress.h deleted file mode 100644 index 1750bb5..0000000 --- a/modules/trantor/trantor/net/InetAddress.h +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Shuo Chen (chenshuo at chenshuo dot com) -// -// This is a public header file, it must only include public header files. - -// Taken from Muduo and modified -// Copyright 2016, Tao An. All rights reserved. -// https://github.com/an-tao/trantor -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#ifndef MUDUO_NET_INETADDRESS_H -#define MUDUO_NET_INETADDRESS_H - -#include -#include - -#ifdef _WIN32 -#include -using sa_family_t = unsigned short; -using in_addr_t = uint32_t; -using uint16_t = unsigned short; -#else -#include -#include -#include -#endif -#include -#include -#include -namespace trantor -{ -/** - * @brief Wrapper of sockaddr_in. This is an POD interface class. - * - */ -class TRANTOR_EXPORT InetAddress -{ - public: - /** - * @brief Constructs an endpoint with given port number. Mostly used in - * TcpServer listening. - * - * @param port - * @param loopbackOnly - * @param ipv6 - */ - InetAddress(uint16_t port = 0, - bool loopbackOnly = false, - bool ipv6 = false); - - /** - * @brief Constructs an endpoint with given ip and port. - * - * @param ip A IPv4 or IPv6 address. - * @param port - * @param ipv6 - */ - InetAddress(const std::string &ip, uint16_t port, bool ipv6 = false); - - /** - * @brief Constructs an endpoint with given struct `sockaddr_in`. Mostly - * used when accepting new connections - * - * @param addr - */ - explicit InetAddress(const struct sockaddr_in &addr) - : addr_(addr), isUnspecified_(false) - { - } - - /** - * @brief Constructs an IPv6 endpoint with given struct `sockaddr_in6`. - * Mostly used when accepting new connections - * - * @param addr - */ - explicit InetAddress(const struct sockaddr_in6 &addr) - : addr6_(addr), isIpV6_(true), isUnspecified_(false) - { - } - - /** - * @brief Return the sin_family of the endpoint. - * - * @return sa_family_t - */ - sa_family_t family() const - { - return addr_.sin_family; - } - - /** - * @brief Return the IP string of the endpoint. - * - * @return std::string - */ - std::string toIp() const; - - /** - * @brief Return the IP and port string of the endpoint. - * - * @return std::string - */ - std::string toIpPort() const; - - /** - * @brief Return the port number of the endpoint. - * - * @return uint16_t - */ - uint16_t toPort() const; - - /** - * @brief Check if the endpoint is IPv4 or IPv6. - * - * @return true - * @return false - */ - bool isIpV6() const - { - return isIpV6_; - } - - /** - * @brief Return true if the endpoint is an intranet endpoint. - * - * @return true - * @return false - */ - bool isIntranetIp() const; - - /** - * @brief Return true if the endpoint is a loopback endpoint. - * - * @return true - * @return false - */ - bool isLoopbackIp() const; - - /** - * @brief Get the pointer to the sockaddr struct. - * - * @return const struct sockaddr* - */ - const struct sockaddr *getSockAddr() const - { - return static_cast((void *)(&addr6_)); - } - - /** - * @brief Set the sockaddr_in6 struct in the endpoint. - * - * @param addr6 - */ - void setSockAddrInet6(const struct sockaddr_in6 &addr6) - { - addr6_ = addr6; - isIpV6_ = (addr6_.sin6_family == AF_INET6); - isUnspecified_ = false; - } - - /** - * @brief Return the integer value of the IP(v4) in net endian byte order. - * - * @return uint32_t - */ - uint32_t ipNetEndian() const; - - /** - * @brief Return the pointer to the integer value of the IP(v6) in net - * endian byte order. - * - * @return const uint32_t* - */ - const uint32_t *ip6NetEndian() const; - - /** - * @brief Return the port number in net endian byte order. - * - * @return uint16_t - */ - uint16_t portNetEndian() const - { - return addr_.sin_port; - } - - /** - * @brief Set the port number in net endian byte order. - * - * @param port - */ - void setPortNetEndian(uint16_t port) - { - addr_.sin_port = port; - } - - /** - * @brief Return true if the address is not initalized. - */ - inline bool isUnspecified() const - { - return isUnspecified_; - } - - private: - union - { - struct sockaddr_in addr_; - struct sockaddr_in6 addr6_; - }; - bool isIpV6_{false}; - bool isUnspecified_{true}; -}; - -} // namespace trantor - -#endif // MUDUO_NET_INETADDRESS_H diff --git a/modules/trantor/trantor/net/Resolver.h b/modules/trantor/trantor/net/Resolver.h deleted file mode 100644 index 478887b..0000000 --- a/modules/trantor/trantor/net/Resolver.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2016, Tao An. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#pragma once -#include -#include -#include -#include - -namespace trantor -{ -/** - * @brief This class represents an asynchronous DNS resolver. - * @note Although the c-ares library is not essential, it is recommended to - * install it for higher performance - */ -class TRANTOR_EXPORT Resolver -{ - public: - using Callback = std::function; - - /** - * @brief Create a new DNS resolver. - * - * @param loop The event loop in which the DNS resolver runs. - * @param timeout The timeout in seconds for DNS. - * @return std::shared_ptr - */ - static std::shared_ptr newResolver(EventLoop* loop = nullptr, - size_t timeout = 60); - - /** - * @brief Resolve an address asynchronously. - * - * @param hostname - * @param callback - */ - virtual void resolve(const std::string& hostname, - const Callback& callback) = 0; - - virtual ~Resolver() - { - } - - /** - * @brief Check whether the c-ares library is used. - * - * @return true - * @return false - */ - static bool isCAresUsed(); -}; -} // namespace trantor \ No newline at end of file diff --git a/modules/trantor/trantor/net/TcpClient.cc b/modules/trantor/trantor/net/TcpClient.cc deleted file mode 100644 index 98048a0..0000000 --- a/modules/trantor/trantor/net/TcpClient.cc +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Shuo Chen (chenshuo at chenshuo dot com) -// - -// Taken from muduo and modified by an tao - -#include - -#include -#include "Connector.h" -#include "inner/TcpConnectionImpl.h" -#include - -#include -#include - -#include "Socket.h" - -#include // snprintf - -using namespace trantor; -using namespace std::placeholders; - -namespace trantor -{ -// void removeConnector(const ConnectorPtr &) -// { -// // connector-> -// } -#ifndef _WIN32 -TcpClient::IgnoreSigPipe TcpClient::initObj; -#endif - -static void defaultConnectionCallback(const TcpConnectionPtr &conn) -{ - LOG_TRACE << conn->localAddr().toIpPort() << " -> " - << conn->peerAddr().toIpPort() << " is " - << (conn->connected() ? "UP" : "DOWN"); - // do not call conn->forceClose(), because some users want to register - // message callback only. -} - -static void defaultMessageCallback(const TcpConnectionPtr &, MsgBuffer *buf) -{ - buf->retrieveAll(); -} - -} // namespace trantor - -TcpClient::TcpClient(EventLoop *loop, - const InetAddress &serverAddr, - const std::string &nameArg) - : loop_(loop), - connector_(new Connector(loop, serverAddr, false)), - name_(nameArg), - connectionCallback_(defaultConnectionCallback), - messageCallback_(defaultMessageCallback), - retry_(false), - connect_(true) -{ - connector_->setNewConnectionCallback( - std::bind(&TcpClient::newConnection, this, _1)); - connector_->setErrorCallback([this]() { - if (connectionErrorCallback_) - { - connectionErrorCallback_(); - } - }); - LOG_TRACE << "TcpClient::TcpClient[" << name_ << "] - connector "; -} - -TcpClient::~TcpClient() -{ - LOG_TRACE << "TcpClient::~TcpClient[" << name_ << "] - connector "; - TcpConnectionImplPtr conn; - { - std::lock_guard lock(mutex_); - conn = std::dynamic_pointer_cast(connection_); - } - if (conn) - { - assert(loop_ == conn->getLoop()); - // TODO: not 100% safe, if we are in different thread - auto loop = loop_; - loop_->runInLoop([conn, loop]() { - conn->setCloseCallback([loop](const TcpConnectionPtr &connPtr) { - loop->queueInLoop([connPtr]() { - static_cast(connPtr.get()) - ->connectDestroyed(); - }); - }); - }); - conn->forceClose(); - } - else - { - /// TODO need test in this condition - connector_->stop(); - } -} - -void TcpClient::connect() -{ - // TODO: check state - LOG_TRACE << "TcpClient::connect[" << name_ << "] - connecting to " - << connector_->serverAddress().toIpPort(); - connect_ = true; - connector_->start(); -} - -void TcpClient::disconnect() -{ - connect_ = false; - - { - std::lock_guard lock(mutex_); - if (connection_) - { - connection_->shutdown(); - } - } -} - -void TcpClient::stop() -{ - connect_ = false; - connector_->stop(); -} - -void TcpClient::newConnection(int sockfd) -{ - loop_->assertInLoopThread(); - InetAddress peerAddr(Socket::getPeerAddr(sockfd)); - InetAddress localAddr(Socket::getLocalAddr(sockfd)); - // TODO poll with zero timeout to double confirm the new connection - // TODO use make_shared if necessary - std::shared_ptr conn; - if (sslCtxPtr_) - { -#ifdef USE_OPENSSL - conn = std::make_shared(loop_, - sockfd, - localAddr, - peerAddr, - sslCtxPtr_, - false, - validateCert_, - SSLHostName_); -#else - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -#endif - } - else - { - conn = std::make_shared(loop_, - sockfd, - localAddr, - peerAddr); - } - conn->setConnectionCallback(connectionCallback_); - conn->setRecvMsgCallback(messageCallback_); - conn->setWriteCompleteCallback(writeCompleteCallback_); - conn->setCloseCallback(std::bind(&TcpClient::removeConnection, this, _1)); - { - std::lock_guard lock(mutex_); - connection_ = conn; - } - conn->setSSLErrorCallback([this](SSLError err) { - if (sslErrorCallback_) - { - sslErrorCallback_(err); - } - }); - conn->connectEstablished(); -} - -void TcpClient::removeConnection(const TcpConnectionPtr &conn) -{ - loop_->assertInLoopThread(); - assert(loop_ == conn->getLoop()); - - { - std::lock_guard lock(mutex_); - assert(connection_ == conn); - connection_.reset(); - } - - loop_->queueInLoop( - std::bind(&TcpConnectionImpl::connectDestroyed, - std::dynamic_pointer_cast(conn))); - if (retry_ && connect_) - { - LOG_TRACE << "TcpClient::connect[" << name_ << "] - Reconnecting to " - << connector_->serverAddress().toIpPort(); - connector_->restart(); - } -} - -void TcpClient::enableSSL( - bool useOldTLS, - bool validateCert, - std::string hostname, - const std::vector> &sslConfCmds) -{ -#ifdef USE_OPENSSL - /* Create a new OpenSSL context */ - sslCtxPtr_ = newSSLContext(useOldTLS, validateCert, sslConfCmds); - validateCert_ = validateCert; - if (!hostname.empty()) - { - std::transform(hostname.begin(), - hostname.end(), - hostname.begin(), - tolower); - SSLHostName_ = std::move(hostname); - } - -#else - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -#endif -} diff --git a/modules/trantor/trantor/net/TcpClient.h b/modules/trantor/trantor/net/TcpClient.h deleted file mode 100644 index 045ad06..0000000 --- a/modules/trantor/trantor/net/TcpClient.h +++ /dev/null @@ -1,247 +0,0 @@ -// taken from muduo -// Copyright 2010, Shuo Chen. All rights reserved. -// http://code.google.com/p/muduo/ -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Shuo Chen (chenshuo at chenshuo dot com) -// -// This is a public header file, it must only include public header files. - -// Copyright 2016, Tao An. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -namespace trantor -{ -class Connector; -using ConnectorPtr = std::shared_ptr; -class SSLContext; -/** - * @brief This class represents a TCP client. - * - */ -class TRANTOR_EXPORT TcpClient : NonCopyable -{ - public: - /** - * @brief Construct a new TCP client instance. - * - * @param loop The event loop in which the client runs. - * @param serverAddr The address of the server. - * @param nameArg The name of the client. - */ - TcpClient(EventLoop *loop, - const InetAddress &serverAddr, - const std::string &nameArg); - ~TcpClient(); - - /** - * @brief Connect to the server. - * - */ - void connect(); - - /** - * @brief Disconnect from the server. - * - */ - void disconnect(); - - /** - * @brief Stop connecting to the server. - * - */ - void stop(); - - /** - * @brief Get the TCP connection to the server. - * - * @return TcpConnectionPtr - */ - TcpConnectionPtr connection() const - { - std::lock_guard lock(mutex_); - return connection_; - } - - /** - * @brief Get the event loop. - * - * @return EventLoop* - */ - EventLoop *getLoop() const - { - return loop_; - } - - /** - * @brief Check whether the client re-connect to the server. - * - * @return true - * @return false - */ - bool retry() const - { - return retry_; - } - - /** - * @brief Enable retrying. - * - */ - void enableRetry() - { - retry_ = true; - } - - /** - * @brief Get the name of the client. - * - * @return const std::string& - */ - const std::string &name() const - { - return name_; - } - - /** - * @brief Set the connection callback. - * - * @param cb The callback is called when the connection to the server is - * established or closed. - */ - void setConnectionCallback(const ConnectionCallback &cb) - { - connectionCallback_ = cb; - } - void setConnectionCallback(ConnectionCallback &&cb) - { - connectionCallback_ = std::move(cb); - } - - /** - * @brief Set the connection error callback. - * - * @param cb The callback is called when an error occurs during connecting - * to the server. - */ - void setConnectionErrorCallback(const ConnectionErrorCallback &cb) - { - connectionErrorCallback_ = cb; - } - - /** - * @brief Set the message callback. - * - * @param cb The callback is called when some data is received from the - * server. - */ - void setMessageCallback(const RecvMessageCallback &cb) - { - messageCallback_ = cb; - } - void setMessageCallback(RecvMessageCallback &&cb) - { - messageCallback_ = std::move(cb); - } - /// Set write complete callback. - /// Not thread safe. - - /** - * @brief Set the write complete callback. - * - * @param cb The callback is called when data to send is written to the - * socket. - */ - void setWriteCompleteCallback(const WriteCompleteCallback &cb) - { - writeCompleteCallback_ = cb; - } - void setWriteCompleteCallback(WriteCompleteCallback &&cb) - { - writeCompleteCallback_ = std::move(cb); - } - - /** - * @brief Set the callback for errors of SSL - * @param cb The callback is called when an SSL error occurs. - */ - void setSSLErrorCallback(const SSLErrorCallback &cb) - { - sslErrorCallback_ = cb; - } - void setSSLErrorCallback(SSLErrorCallback &&cb) - { - sslErrorCallback_ = std::move(cb); - } - - /** - * @brief Enable SSL encryption. - * @param useOldTLS If true, the TLS 1.0 and 1.1 are supported by the - * client. - * @param validateCert If true, we try to validate if the peer's SSL cert - * is valid. - * @param hostname The server hostname for SNI. If it is empty, the SNI is - * not used. - * @param 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(bool useOldTLS = false, - bool validateCert = true, - std::string hostname = "", - const std::vector> - &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 sslCtxPtr_; - bool validateCert_{false}; - std::string SSLHostName_; -#ifndef _WIN32 - class IgnoreSigPipe - { - public: - IgnoreSigPipe() - { - ::signal(SIGPIPE, SIG_IGN); - } - }; - - static IgnoreSigPipe initObj; -#endif -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/TcpConnection.h b/modules/trantor/trantor/net/TcpConnection.h deleted file mode 100644 index 90f2446..0000000 --- a/modules/trantor/trantor/net/TcpConnection.h +++ /dev/null @@ -1,261 +0,0 @@ -/** - * - * @file TcpConnection.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -class SSLContext; -TRANTOR_EXPORT std::shared_ptr newSSLServerContext( - const std::string &certPath, - const std::string &keyPath, - bool useOldTLS = false, - const std::vector> &sslConfCmds = {}); -/** - * @brief This class represents a TCP connection. - * - */ -class TRANTOR_EXPORT TcpConnection -{ - public: - TcpConnection() = default; - virtual ~TcpConnection(){}; - - /** - * @brief Send some data to the peer. - * - * @param msg - * @param len - */ - 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 &msgPtr) = 0; - virtual void send(const std::shared_ptr &msgPtr) = 0; - - /** - * @brief Send a file to the peer. - * - * @param fileName - * @param offset - * @param length - */ - virtual void sendFile(const char *fileName, - size_t offset = 0, - size_t length = 0) = 0; - - /** - * @brief Get the local address of the connection. - * - * @return const InetAddress& - */ - virtual const InetAddress &localAddr() const = 0; - - /** - * @brief Get the remote address of the connection. - * - * @return const InetAddress& - */ - virtual const InetAddress &peerAddr() const = 0; - - /** - * @brief Return true if the connection is established. - * - * @return true - * @return false - */ - virtual bool connected() const = 0; - - /** - * @brief Return false if the connection is established. - * - * @return true - * @return false - */ - virtual bool disconnected() const = 0; - - /** - * @brief Get the buffer in which the received data stored. - * - * @return MsgBuffer* - */ - virtual MsgBuffer *getRecvBuffer() = 0; - - /** - * @brief Set the high water mark callback - * - * @param cb The callback is called when the data in sending buffer is - * larger than the water mark. - * @param markLen The water mark in bytes. - */ - virtual void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, - size_t markLen) = 0; - - /** - * @brief Set the TCP_NODELAY option to the socket. - * - * @param on - */ - virtual void setTcpNoDelay(bool on) = 0; - - /** - * @brief Shutdown the connection. - * @note This method only closes the writing direction. - */ - virtual void shutdown() = 0; - - /** - * @brief Close the connection forcefully. - * - */ - virtual void forceClose() = 0; - - /** - * @brief Get the event loop in which the connection I/O is handled. - * - * @return EventLoop* - */ - virtual EventLoop *getLoop() = 0; - - /** - * @brief Set the custom data on the connection. - * - * @param context - */ - void setContext(const std::shared_ptr &context) - { - contextPtr_ = context; - } - void setContext(std::shared_ptr &&context) - { - contextPtr_ = std::move(context); - } - - /** - * @brief Get the custom data from the connection. - * - * @tparam T - * @return std::shared_ptr - */ - template - std::shared_ptr getContext() const - { - return std::static_pointer_cast(contextPtr_); - } - - /** - * @brief Return true if the custom data is set by user. - * - * @return true - * @return false - */ - bool hasContext() const - { - return (bool)contextPtr_; - } - - /** - * @brief Clear the custom data. - * - */ - void clearContext() - { - contextPtr_.reset(); - } - - /** - * @brief Call this method to avoid being kicked off by TcpServer, refer to - * the kickoffIdleConnections method in the TcpServer class. - * - */ - virtual void keepAlive() = 0; - - /** - * @brief Return true if the keepAlive() method is called. - * - * @return true - * @return false - */ - virtual bool isKeepAlive() = 0; - - /** - * @brief Return the number of bytes sent - * - * @return size_t - */ - virtual size_t bytesSent() const = 0; - - /** - * @brief Return the number of bytes received. - * - * @return size_t - */ - virtual size_t bytesReceived() const = 0; - - /** - * @brief Check whether the connection is SSL encrypted. - * - * @return true - * @return false - */ - virtual bool isSSLConnection() const = 0; - - /** - * @brief Start the SSL encryption on the connection (as a client). - * - * @param callback The callback is called when the SSL connection is - * established. - * @param hostname The server hostname for SNI. If it is empty, the SNI is - * not used. - * @param sslConfCmds The commands used to call the SSL_CONF_cmd function in - * OpenSSL. - */ - virtual void startClientEncryption( - std::function callback, - bool useOldTLS = false, - bool validateCert = true, - std::string hostname = "", - const std::vector> &sslConfCmds = - {}) = 0; - - /** - * @brief Start the SSL encryption on the connection (as a server). - * - * @param ctx The SSL context. - * @param callback The callback is called when the SSL connection is - * established. - */ - virtual void startServerEncryption(const std::shared_ptr &ctx, - std::function callback) = 0; - - protected: - bool validateCert_ = false; - - private: - std::shared_ptr contextPtr_; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/TcpServer.cc b/modules/trantor/trantor/net/TcpServer.cc deleted file mode 100644 index d67488b..0000000 --- a/modules/trantor/trantor/net/TcpServer.cc +++ /dev/null @@ -1,201 +0,0 @@ -/** - * - * @file TcpServer.cc - * @author An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/trantor - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * Trantor - * - */ - -#include "Acceptor.h" -#include "inner/TcpConnectionImpl.h" -#include -#include -#include -#include -using namespace trantor; -using namespace std::placeholders; - -TcpServer::TcpServer(EventLoop *loop, - const InetAddress &address, - const std::string &name, - bool reUseAddr, - bool reUsePort) - : loop_(loop), - acceptorPtr_(new Acceptor(loop, address, reUseAddr, reUsePort)), - serverName_(name), - recvMessageCallback_([](const TcpConnectionPtr &, MsgBuffer *buffer) { - LOG_ERROR << "unhandled recv message [" << buffer->readableBytes() - << " bytes]"; - buffer->retrieveAll(); - }) -{ - acceptorPtr_->setNewConnectionCallback( - std::bind(&TcpServer::newConnection, this, _1, _2)); -} - -TcpServer::~TcpServer() -{ - // loop_->assertInLoopThread(); - LOG_TRACE << "TcpServer::~TcpServer [" << serverName_ << "] destructing"; -} - -void TcpServer::newConnection(int sockfd, const InetAddress &peer) -{ - LOG_TRACE << "new connection:fd=" << sockfd - << " address=" << peer.toIpPort(); - // test code for blocking or nonblocking - // std::vector str(1024*1024*100); - // for(int i=0;iassertInLoopThread(); - EventLoop *ioLoop = NULL; - if (loopPoolPtr_ && loopPoolPtr_->size() > 0) - { - ioLoop = loopPoolPtr_->getNextLoop(); - } - if (ioLoop == NULL) - ioLoop = loop_; - std::shared_ptr newPtr; - if (sslCtxPtr_) - { -#ifdef USE_OPENSSL - newPtr = std::make_shared( - ioLoop, - sockfd, - InetAddress(Socket::getLocalAddr(sockfd)), - peer, - sslCtxPtr_); -#else - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -#endif - } - else - { - newPtr = std::make_shared( - ioLoop, sockfd, InetAddress(Socket::getLocalAddr(sockfd)), peer); - } - - if (idleTimeout_ > 0) - { - assert(timingWheelMap_[ioLoop]); - newPtr->enableKickingOff(idleTimeout_, timingWheelMap_[ioLoop]); - } - newPtr->setRecvMsgCallback(recvMessageCallback_); - - newPtr->setConnectionCallback( - [this](const TcpConnectionPtr &connectionPtr) { - if (connectionCallback_) - connectionCallback_(connectionPtr); - }); - newPtr->setWriteCompleteCallback( - [this](const TcpConnectionPtr &connectionPtr) { - if (writeCompleteCallback_) - writeCompleteCallback_(connectionPtr); - }); - newPtr->setCloseCallback(std::bind(&TcpServer::connectionClosed, this, _1)); - connSet_.insert(newPtr); - newPtr->connectEstablished(); -} - -void TcpServer::start() -{ - loop_->runInLoop([this]() { - assert(!started_); - started_ = true; - if (idleTimeout_ > 0) - { - timingWheelMap_[loop_] = - std::make_shared(loop_, - idleTimeout_, - 1.0F, - idleTimeout_ < 500 - ? idleTimeout_ + 1 - : 100); - if (loopPoolPtr_) - { - auto loopNum = loopPoolPtr_->size(); - while (loopNum > 0) - { - // LOG_TRACE << "new Wheel loopNum=" << loopNum; - auto poolLoop = loopPoolPtr_->getNextLoop(); - timingWheelMap_[poolLoop] = - std::make_shared(poolLoop, - idleTimeout_, - 1.0F, - idleTimeout_ < 500 - ? idleTimeout_ + 1 - : 100); - --loopNum; - } - } - } - LOG_TRACE << "map size=" << timingWheelMap_.size(); - acceptorPtr_->listen(); - }); -} -void TcpServer::stop() -{ - loop_->runInLoop([this]() { acceptorPtr_.reset(); }); - for (auto connection : connSet_) - { - connection->forceClose(); - } - loopPoolPtr_.reset(); - for (auto &iter : timingWheelMap_) - { - std::promise pro; - auto f = pro.get_future(); - iter.second->getLoop()->runInLoop([&iter, &pro]() mutable { - iter.second.reset(); - pro.set_value(1); - }); - f.get(); - } -} -void TcpServer::connectionClosed(const TcpConnectionPtr &connectionPtr) -{ - LOG_TRACE << "connectionClosed"; - // loop_->assertInLoopThread(); - loop_->runInLoop([this, connectionPtr]() { - size_t n = connSet_.erase(connectionPtr); - (void)n; - assert(n == 1); - }); - - static_cast(connectionPtr.get())->connectDestroyed(); -} - -const std::string TcpServer::ipPort() const -{ - return acceptorPtr_->addr().toIpPort(); -} - -const trantor::InetAddress &TcpServer::address() const -{ - return acceptorPtr_->addr(); -} - -void TcpServer::enableSSL( - const std::string &certPath, - const std::string &keyPath, - bool useOldTLS, - const std::vector> &sslConfCmds) -{ -#ifdef USE_OPENSSL - /* Create a new OpenSSL context */ - sslCtxPtr_ = newSSLServerContext(certPath, keyPath, useOldTLS, sslConfCmds); -#else - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -#endif -} diff --git a/modules/trantor/trantor/net/TcpServer.h b/modules/trantor/trantor/net/TcpServer.h deleted file mode 100644 index 194fbb2..0000000 --- a/modules/trantor/trantor/net/TcpServer.h +++ /dev/null @@ -1,250 +0,0 @@ -/** - * - * @file TcpServer.h - * @author An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/trantor - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * Trantor - * - */ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -namespace trantor -{ -class Acceptor; -class SSLContext; -/** - * @brief This class represents a TCP server. - * - */ -class TRANTOR_EXPORT TcpServer : NonCopyable -{ - public: - /** - * @brief Construct a new TCP server instance. - * - * @param loop The event loop in which the acceptor of the server is - * handled. - * @param address The address of the server. - * @param name The name of the server. - * @param reUseAddr The SO_REUSEADDR option. - * @param reUsePort The SO_REUSEPORT option. - */ - TcpServer(EventLoop *loop, - const InetAddress &address, - const std::string &name, - bool reUseAddr = true, - bool reUsePort = true); - ~TcpServer(); - - /** - * @brief Start the server. - * - */ - void start(); - - /** - * @brief Stop the server. - * - */ - void stop(); - - /** - * @brief Set the number of event loops in which the I/O of connections to - * the server is handled. - * - * @param num - */ - void setIoLoopNum(size_t num) - { - assert(!started_); - loopPoolPtr_ = std::make_shared(num); - loopPoolPtr_->start(); - } - - /** - * @brief Set the event loops pool in which the I/O of connections to - * the server is handled. - * - * @param pool - */ - void setIoLoopThreadPool(const std::shared_ptr &pool) - { - assert(pool->size() > 0); - assert(!started_); - loopPoolPtr_ = pool; - loopPoolPtr_->start(); - } - - /** - * @brief Set the message callback. - * - * @param cb The callback is called when some data is received on a - * connection to the server. - */ - void setRecvMessageCallback(const RecvMessageCallback &cb) - { - recvMessageCallback_ = cb; - } - void setRecvMessageCallback(RecvMessageCallback &&cb) - { - recvMessageCallback_ = std::move(cb); - } - - /** - * @brief Set the connection callback. - * - * @param cb The callback is called when a connection is established or - * closed. - */ - void setConnectionCallback(const ConnectionCallback &cb) - { - connectionCallback_ = cb; - } - void setConnectionCallback(ConnectionCallback &&cb) - { - connectionCallback_ = std::move(cb); - } - - /** - * @brief Set the write complete callback. - * - * @param cb The callback is called when data to send is written to the - * socket of a connection. - */ - void setWriteCompleteCallback(const WriteCompleteCallback &cb) - { - writeCompleteCallback_ = cb; - } - void setWriteCompleteCallback(WriteCompleteCallback &&cb) - { - writeCompleteCallback_ = std::move(cb); - } - - /** - * @brief Get the name of the server. - * - * @return const std::string& - */ - const std::string &name() const - { - return serverName_; - } - - /** - * @brief Get the IP and port string of the server. - * - * @return const std::string - */ - const std::string ipPort() const; - - /** - * @brief Get the address of the server. - * - * @return const trantor::InetAddress& - */ - const trantor::InetAddress &address() const; - - /** - * @brief Get the event loop of the server. - * - * @return EventLoop* - */ - EventLoop *getLoop() const - { - return loop_; - } - - /** - * @brief Get the I/O event loops of the server. - * - * @return std::vector - */ - std::vector getIoLoops() const - { - return loopPoolPtr_->getLoops(); - } - - /** - * @brief An idle connection is a connection that has no read or write, kick - * off it after timeout seconds. - * - * @param timeout - */ - void kickoffIdleConnections(size_t timeout) - { - loop_->runInLoop([this, timeout]() { - assert(!started_); - idleTimeout_ = timeout; - }); - } - - /** - * @brief Enable SSL encryption. - * - * @param certPath The path of the certificate file. - * @param keyPath The path of the private key file. - * @param useOldTLS If true, the TLS 1.0 and 1.1 are supported by the - * server. - * @param 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> - &sslConfCmds = {}); - - private: - EventLoop *loop_; - std::unique_ptr acceptorPtr_; - void newConnection(int fd, const InetAddress &peer); - std::string serverName_; - std::set connSet_; - - RecvMessageCallback recvMessageCallback_; - ConnectionCallback connectionCallback_; - WriteCompleteCallback writeCompleteCallback_; - - size_t idleTimeout_{0}; - std::map> timingWheelMap_; - void connectionClosed(const TcpConnectionPtr &connectionPtr); - std::shared_ptr 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 sslCtxPtr_; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/callbacks.h b/modules/trantor/trantor/net/callbacks.h deleted file mode 100644 index f737870..0000000 --- a/modules/trantor/trantor/net/callbacks.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * - * callbacks.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -namespace trantor -{ -enum class SSLError -{ - kSSLHandshakeError, - kSSLInvalidCertificate -}; -using TimerCallback = std::function; - -// the data has been read to (buf, len) -class TcpConnection; -class MsgBuffer; -using TcpConnectionPtr = std::shared_ptr; -// tcp server and connection callback -using RecvMessageCallback = - std::function; -using ConnectionErrorCallback = std::function; -using ConnectionCallback = std::function; -using CloseCallback = std::function; -using WriteCompleteCallback = std::function; -using HighWaterMarkCallback = - std::function; -using SSLErrorCallback = std::function; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/Acceptor.cc b/modules/trantor/trantor/net/inner/Acceptor.cc deleted file mode 100644 index 6186b94..0000000 --- a/modules/trantor/trantor/net/inner/Acceptor.cc +++ /dev/null @@ -1,97 +0,0 @@ -/** - * - * Acceptor.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "Acceptor.h" -using namespace trantor; - -#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 - } -} diff --git a/modules/trantor/trantor/net/inner/Acceptor.h b/modules/trantor/trantor/net/inner/Acceptor.h deleted file mode 100644 index 62ec421..0000000 --- a/modules/trantor/trantor/net/inner/Acceptor.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * - * Acceptor.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include "Socket.h" -#include -#include "Channel.h" -#include - -namespace trantor -{ -using NewConnectionCallback = std::function; -class Acceptor : NonCopyable -{ - 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(); -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/AresResolver.cc b/modules/trantor/trantor/net/inner/AresResolver.cc deleted file mode 100644 index 3b77b44..0000000 --- a/modules/trantor/trantor/net/inner/AresResolver.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2016, Tao An. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#include "AresResolver.h" -#include -#include -#ifdef _WIN32 -#include -#else -#include -#include // inet_ntop -#include -#endif -#include -#include -#include - -using namespace trantor; -using namespace std::placeholders; - -namespace -{ -double getSeconds(struct timeval* tv) -{ - if (tv) - return double(tv->tv_sec) + double(tv->tv_usec) / 1000000.0; - else - return -1.0; -} - -const char* getSocketType(int type) -{ - if (type == SOCK_DGRAM) - return "UDP"; - else if (type == SOCK_STREAM) - return "TCP"; - else - return "Unknown"; -} - -} // namespace - -bool Resolver::isCAresUsed() -{ - return true; -} - -AresResolver::LibraryInitializer::LibraryInitializer() -{ - ares_library_init(ARES_LIB_INIT_ALL); -} -AresResolver::LibraryInitializer::~LibraryInitializer() -{ - ares_library_cleanup(); -} - -AresResolver::LibraryInitializer AresResolver::libraryInitializer_; - -std::shared_ptr Resolver::newResolver(trantor::EventLoop* loop, - size_t timeout) -{ - return std::make_shared(loop, timeout); -} - -AresResolver::AresResolver(EventLoop* loop, size_t timeout) - : loop_(loop), timeout_(timeout) -{ - if (!loop) - { - loop_ = getLoop(); - } -} -void AresResolver::init() -{ - if (!ctx_) - { - struct ares_options options; - int optmask = ARES_OPT_FLAGS; - options.flags = ARES_FLAG_NOCHECKRESP; - options.flags |= ARES_FLAG_STAYOPEN; - options.flags |= ARES_FLAG_IGNTC; // UDP only - optmask |= ARES_OPT_SOCK_STATE_CB; - options.sock_state_cb = &AresResolver::ares_sock_statecallback_; - options.sock_state_cb_data = this; - optmask |= ARES_OPT_TIMEOUT; - options.timeout = 2; - // optmask |= ARES_OPT_LOOKUPS; - // options.lookups = lookups; - - int status = ares_init_options(&ctx_, &options, optmask); - if (status != ARES_SUCCESS) - { - assert(0); - } - ares_set_socket_callback(ctx_, - &AresResolver::ares_sock_createcallback_, - this); - } -} -AresResolver::~AresResolver() -{ - if (ctx_) - ares_destroy(ctx_); -} - -void AresResolver::resolveInLoop(const std::string& hostname, - const Callback& cb) -{ - loop_->assertInLoopThread(); -#ifdef _WIN32 - if (hostname == "localhost") - { - const static trantor::InetAddress localhost_{"127.0.0.1", 0}; - cb(localhost_); - return; - } -#endif - init(); - QueryData* queryData = new QueryData(this, cb, hostname); - ares_gethostbyname(ctx_, - hostname.c_str(), - AF_INET, - &AresResolver::ares_hostcallback_, - queryData); - struct timeval tv; - struct timeval* tvp = ares_timeout(ctx_, NULL, &tv); - double timeout = getSeconds(tvp); - // LOG_DEBUG << "timeout " << timeout << " active " << timerActive_; - if (!timerActive_ && timeout >= 0.0) - { - loop_->runAfter(timeout, - std::bind(&AresResolver::onTimer, shared_from_this())); - timerActive_ = true; - } - return; -} - -void AresResolver::onRead(int sockfd) -{ - ares_process_fd(ctx_, sockfd, ARES_SOCKET_BAD); -} - -void AresResolver::onTimer() -{ - assert(timerActive_ == true); - ares_process_fd(ctx_, ARES_SOCKET_BAD, ARES_SOCKET_BAD); - struct timeval tv; - struct timeval* tvp = ares_timeout(ctx_, NULL, &tv); - double timeout = getSeconds(tvp); - - if (timeout < 0) - { - timerActive_ = false; - } - else - { - loop_->runAfter(timeout, - std::bind(&AresResolver::onTimer, shared_from_this())); - } -} - -void AresResolver::onQueryResult(int status, - struct hostent* result, - const std::string& hostname, - const Callback& callback) -{ - LOG_TRACE << "onQueryResult " << status; - struct sockaddr_in addr; - memset(&addr, 0, sizeof addr); - addr.sin_family = AF_INET; - addr.sin_port = 0; - if (result) - { - addr.sin_addr = *reinterpret_cast(result->h_addr); - } - InetAddress inet(addr); - { - std::lock_guard lock(globalMutex()); - auto& addrItem = globalCache()[hostname]; - addrItem.first = addr.sin_addr; - addrItem.second = trantor::Date::date(); - } - callback(inet); -} - -void AresResolver::onSockCreate(int sockfd, int type) -{ - (void)type; - loop_->assertInLoopThread(); - assert(channels_.find(sockfd) == channels_.end()); - Channel* channel = new Channel(loop_, sockfd); - channel->setReadCallback(std::bind(&AresResolver::onRead, this, sockfd)); - channel->enableReading(); - channels_[sockfd].reset(channel); -} - -void AresResolver::onSockStateChange(int sockfd, bool read, bool write) -{ - (void)write; - loop_->assertInLoopThread(); - ChannelList::iterator it = channels_.find(sockfd); - assert(it != channels_.end()); - if (read) - { - // update - // if (write) { } else { } - } - else - { - // remove - it->second->disableAll(); - it->second->remove(); - channels_.erase(it); - } -} - -void AresResolver::ares_hostcallback_(void* data, - int status, - int timeouts, - struct hostent* hostent) -{ - (void)timeouts; - QueryData* query = static_cast(data); - - query->owner_->onQueryResult(status, - hostent, - query->hostname_, - query->callback_); - delete query; -} - -#ifdef _WIN32 -int AresResolver::ares_sock_createcallback_(SOCKET sockfd, int type, void* data) -#else -int AresResolver::ares_sock_createcallback_(int sockfd, int type, void* data) -#endif -{ - LOG_TRACE << "sockfd=" << sockfd << " type=" << getSocketType(type); - static_cast(data)->onSockCreate(sockfd, type); - return 0; -} - -void AresResolver::ares_sock_statecallback_(void* data, -#ifdef _WIN32 - SOCKET sockfd, -#else - int sockfd, -#endif - int read, - int write) -{ - LOG_TRACE << "sockfd=" << sockfd << " read=" << read << " write=" << write; - static_cast(data)->onSockStateChange(sockfd, read, write); -} diff --git a/modules/trantor/trantor/net/inner/AresResolver.h b/modules/trantor/trantor/net/inner/AresResolver.h deleted file mode 100644 index 6f4adac..0000000 --- a/modules/trantor/trantor/net/inner/AresResolver.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2016, Tao An. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#pragma once -#include -#include -#include -#include -#include -#include - -extern "C" -{ - struct hostent; - struct ares_channeldata; - using ares_channel = struct ares_channeldata*; -} -namespace trantor -{ -class AresResolver : public Resolver, - public NonCopyable, - public std::enable_shared_from_this -{ - public: - AresResolver(trantor::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 lock(globalMutex()); - auto iter = globalCache().find(hostname); - if (iter != globalCache().end()) - { - auto& cachedAddr = iter->second; - if (timeout_ == 0 || - cachedAddr.second.after(timeout_) > trantor::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(); - trantor::EventLoop* loop_; - ares_channel ctx_{nullptr}; - bool timerActive_{false}; - using ChannelList = std::map>; - ChannelList channels_; - static std::unordered_map>& - globalCache() - { - static std::unordered_map> - 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_; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/Connector.cc b/modules/trantor/trantor/net/inner/Connector.cc deleted file mode 100644 index 1b70397..0000000 --- a/modules/trantor/trantor/net/inner/Connector.cc +++ /dev/null @@ -1,261 +0,0 @@ -/** - * - * @file Connector.cc - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "Connector.h" -#include "Channel.h" -#include "Socket.h" - -using namespace trantor; - -Connector::Connector(EventLoop *loop, const InetAddress &addr, bool retry) - : loop_(loop), serverAddr_(addr), retry_(retry) -{ -} -Connector::Connector(EventLoop *loop, InetAddress &&addr, bool retry) - : loop_(loop), serverAddr_(std::move(addr)), retry_(retry) -{ -} - -void Connector::start() -{ - connect_ = true; - loop_->runInLoop([this]() { startInLoop(); }); -} -void Connector::restart() -{ -} -void Connector::stop() -{ -} - -void Connector::startInLoop() -{ - loop_->assertInLoopThread(); - assert(status_ == Status::Disconnected); - if (connect_) - { - connect(); - } - else - { - LOG_DEBUG << "do not connect"; - } -} -void Connector::connect() -{ - int sockfd = Socket::createNonblockingSocketOrDie(serverAddr_.family()); - errno = 0; - int ret = Socket::connect(sockfd, serverAddr_); - int savedErrno = (ret == 0) ? 0 : errno; - switch (savedErrno) - { - case 0: - case EINPROGRESS: - case EINTR: - case EISCONN: - LOG_TRACE << "connecting"; - connecting(sockfd); - break; - - case EAGAIN: - case EADDRINUSE: - case EADDRNOTAVAIL: - case ECONNREFUSED: - case ENETUNREACH: - if (retry_) - { - retry(sockfd); - } - break; - - case EACCES: - case EPERM: - case EAFNOSUPPORT: - case EALREADY: - case EBADF: - case EFAULT: - case ENOTSOCK: - LOG_SYSERR << "connect error in Connector::startInLoop " - << savedErrno; -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - if (errorCallback_) - errorCallback_(); - break; - - default: - LOG_SYSERR << "Unexpected error in Connector::startInLoop " - << savedErrno; -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - if (errorCallback_) - errorCallback_(); - break; - } -} - -void Connector::connecting(int sockfd) -{ - status_ = Status::Connecting; - assert(!channelPtr_); - channelPtr_.reset(new Channel(loop_, sockfd)); - channelPtr_->setWriteCallback( - std::bind(&Connector::handleWrite, shared_from_this())); - channelPtr_->setErrorCallback( - std::bind(&Connector::handleError, shared_from_this())); - channelPtr_->setCloseCallback( - std::bind(&Connector::handleError, shared_from_this())); - LOG_TRACE << "connecting:" << sockfd; - channelPtr_->enableWriting(); -} - -int Connector::removeAndResetChannel() -{ - channelPtr_->disableAll(); - channelPtr_->remove(); - int sockfd = channelPtr_->fd(); - // Can't reset channel_ here, because we are inside Channel::handleEvent - loop_->queueInLoop([this]() { channelPtr_.reset(); }); - return sockfd; -} - -void Connector::handleWrite() -{ - if (status_ == Status::Connecting) - { - int sockfd = removeAndResetChannel(); - int err = Socket::getSocketError(sockfd); - if (err) - { - LOG_WARN << "Connector::handleWrite - SO_ERROR = " << err << " " - << strerror_tl(err); - if (retry_) - { - retry(sockfd); - } - else - { -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - } - if (errorCallback_) - { - errorCallback_(); - } - } - else if (Socket::isSelfConnect(sockfd)) - { - LOG_WARN << "Connector::handleWrite - Self connect"; - if (retry_) - { - retry(sockfd); - } - else - { -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - } - if (errorCallback_) - { - errorCallback_(); - } - } - else - { - status_ = Status::Connected; - if (connect_) - { - newConnectionCallback_(sockfd); - } - else - { -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - } - } - } - else - { - // what happened? - assert(status_ == Status::Disconnected); - } -} - -void Connector::handleError() -{ - if (status_ == Status::Connecting) - { - status_ = Status::Disconnected; - int sockfd = removeAndResetChannel(); - int err = Socket::getSocketError(sockfd); - LOG_TRACE << "SO_ERROR = " << err << " " << strerror_tl(err); - if (retry_) - { - retry(sockfd); - } - else - { -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - } - if (errorCallback_) - { - errorCallback_(); - } - } -} - -void Connector::retry(int sockfd) -{ - assert(retry_); -#ifndef _WIN32 - ::close(sockfd); -#else - closesocket(sockfd); -#endif - status_ = Status::Disconnected; - if (connect_) - { - LOG_INFO << "Connector::retry - Retry connecting to " - << serverAddr_.toIpPort() << " in " << retryInterval_ - << " milliseconds. "; - loop_->runAfter(retryInterval_ / 1000.0, - std::bind(&Connector::startInLoop, shared_from_this())); - retryInterval_ = retryInterval_ * 2; - if (retryInterval_ > maxRetryInterval_) - retryInterval_ = maxRetryInterval_; - } - else - { - LOG_DEBUG << "do not connect"; - } -} diff --git a/modules/trantor/trantor/net/inner/Connector.h b/modules/trantor/trantor/net/inner/Connector.h deleted file mode 100644 index 2c943ba..0000000 --- a/modules/trantor/trantor/net/inner/Connector.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * - * Connector.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include - -namespace trantor -{ -class Connector : public NonCopyable, - public std::enable_shared_from_this -{ - public: - using NewConnectionCallback = std::function; - using ConnectionErrorCallback = std::function; - 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 channelPtr_; - EventLoop *loop_; - InetAddress serverAddr_; - - std::atomic_bool connect_{false}; - std::atomic 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); -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/NormalResolver.cc b/modules/trantor/trantor/net/inner/NormalResolver.cc deleted file mode 100644 index 87c2d7c..0000000 --- a/modules/trantor/trantor/net/inner/NormalResolver.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include "NormalResolver.h" -#include -#ifdef _WIN32 -#include -#else -#include -#include -#include -#include -#include // memset -#endif - -using namespace trantor; - -std::shared_ptr Resolver::newResolver(trantor::EventLoop *, - size_t timeout) -{ - return std::make_shared(timeout); -} -bool Resolver::isCAresUsed() -{ - return false; -} -void NormalResolver::resolve(const std::string &hostname, - const Callback &callback) -{ - { - std::lock_guard guard(globalMutex()); - auto iter = globalCache().find(hostname); - if (iter != globalCache().end()) - { - auto &cachedAddr = iter->second; - if (timeout_ == 0 || cachedAddr.second.after(static_cast( - timeout_)) > trantor::Date::date()) - { - callback(cachedAddr.first); - return; - } - } - } - - concurrentTaskQueue().runTaskInQueue( - [thisPtr = shared_from_this(), callback, hostname]() { - { - std::lock_guard guard(thisPtr->globalMutex()); - auto iter = thisPtr->globalCache().find(hostname); - if (iter != thisPtr->globalCache().end()) - { - auto &cachedAddr = iter->second; - if (thisPtr->timeout_ == 0 || - cachedAddr.second.after(static_cast( - thisPtr->timeout_)) > trantor::Date::date()) - { - callback(cachedAddr.first); - return; - } - } - } - struct addrinfo hints, *res; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - auto error = getaddrinfo(hostname.data(), nullptr, &hints, &res); - if (error == -1 || res == nullptr) - { - LOG_SYSERR << "InetAddress::resolve"; - callback(InetAddress{}); - return; - } - InetAddress inet; - if (res->ai_family == AF_INET) - { - struct sockaddr_in addr; - memset(&addr, 0, sizeof addr); - addr = *reinterpret_cast(res->ai_addr); - inet = InetAddress(addr); - } - else if (res->ai_family == AF_INET6) - { - struct sockaddr_in6 addr; - memset(&addr, 0, sizeof addr); - addr = *reinterpret_cast(res->ai_addr); - inet = InetAddress(addr); - } - callback(inet); - { - std::lock_guard guard(thisPtr->globalMutex()); - auto &addrItem = thisPtr->globalCache()[hostname]; - addrItem.first = inet; - addrItem.second = trantor::Date::date(); - } - return; - }); -} diff --git a/modules/trantor/trantor/net/inner/NormalResolver.h b/modules/trantor/trantor/net/inner/NormalResolver.h deleted file mode 100644 index bc19e0f..0000000 --- a/modules/trantor/trantor/net/inner/NormalResolver.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2016, Tao An. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the License file. - -// Author: Tao An - -#pragma once -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -constexpr size_t kResolveBufferLength{16 * 1024}; -class NormalResolver : public Resolver, - public NonCopyable, - public std::enable_shared_from_this -{ - 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>& - globalCache() - { - static std::unordered_map< - std::string, - std::pair> - dnsCache_; - return dnsCache_; - } - static std::mutex& globalMutex() - { - static std::mutex mutex_; - return mutex_; - } - static trantor::ConcurrentTaskQueue& concurrentTaskQueue() - { - static trantor::ConcurrentTaskQueue queue( - std::thread::hardware_concurrency() < 8 - ? 8 - : std::thread::hardware_concurrency(), - "Dns Queue"); - return queue; - } - const size_t timeout_; - std::vector resolveBuffer_; -}; -} // namespace trantor \ No newline at end of file diff --git a/modules/trantor/trantor/net/inner/Poller.cc b/modules/trantor/trantor/net/inner/Poller.cc deleted file mode 100644 index 379236a..0000000 --- a/modules/trantor/trantor/net/inner/Poller.cc +++ /dev/null @@ -1,32 +0,0 @@ -/** - * - * Poller.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "Poller.h" -#ifdef __linux__ -#include "poller/EpollPoller.h" -#elif defined _WIN32 -#include "Wepoll.h" -#include "poller/EpollPoller.h" -#else -#include "poller/KQueue.h" -#endif -using namespace trantor; -Poller *Poller::newPoller(EventLoop *loop) -{ -#if defined __linux__ || defined _WIN32 - return new EpollPoller(loop); -#else - return new KQueue(loop); -#endif -} diff --git a/modules/trantor/trantor/net/inner/Poller.h b/modules/trantor/trantor/net/inner/Poller.h deleted file mode 100644 index 9261824..0000000 --- a/modules/trantor/trantor/net/inner/Poller.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * - * Poller.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once -#include "NonCopyable.h" -#include "EventLoop.h" - -#include -#include - -namespace trantor -{ -class Channel; -#ifdef _WIN32 -using EventCallback = std::function; -#endif -class Poller : NonCopyable -{ - 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_; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/Socket.cc b/modules/trantor/trantor/net/inner/Socket.cc deleted file mode 100644 index c9eb58d..0000000 --- a/modules/trantor/trantor/net/inner/Socket.cc +++ /dev/null @@ -1,248 +0,0 @@ -/** - * - * Socket.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include "Socket.h" -#include -#include -#ifdef _WIN32 -#include -#else -#include -#include -#endif - -using namespace trantor; - -bool Socket::isSelfConnect(int sockfd) -{ - struct sockaddr_in6 localaddr = getLocalAddr(sockfd); - struct sockaddr_in6 peeraddr = getPeerAddr(sockfd); - if (localaddr.sin6_family == AF_INET) - { - const struct sockaddr_in *laddr4 = - reinterpret_cast(&localaddr); - const struct sockaddr_in *raddr4 = - reinterpret_cast(&peeraddr); - return laddr4->sin_port == raddr4->sin_port && - laddr4->sin_addr.s_addr == raddr4->sin_addr.s_addr; - } - else if (localaddr.sin6_family == AF_INET6) - { - return localaddr.sin6_port == peeraddr.sin6_port && - memcmp(&localaddr.sin6_addr, - &peeraddr.sin6_addr, - sizeof localaddr.sin6_addr) == 0; - } - else - { - return false; - } -} - -void Socket::bindAddress(const InetAddress &localaddr) -{ - assert(sockFd_ > 0); - int ret; - if (localaddr.isIpV6()) - ret = ::bind(sockFd_, localaddr.getSockAddr(), sizeof(sockaddr_in6)); - else - ret = ::bind(sockFd_, localaddr.getSockAddr(), sizeof(sockaddr_in)); - - if (ret == 0) - return; - else - { - LOG_SYSERR << ", Bind address failed at " << localaddr.toIpPort(); - exit(1); - } -} -void Socket::listen() -{ - assert(sockFd_ > 0); - int ret = ::listen(sockFd_, SOMAXCONN); - if (ret < 0) - { - LOG_SYSERR << "listen failed"; - exit(1); - } -} -int Socket::accept(InetAddress *peeraddr) -{ - struct sockaddr_in6 addr6; - memset(&addr6, 0, sizeof(addr6)); - socklen_t size = sizeof(addr6); -#ifdef __linux__ - int connfd = ::accept4(sockFd_, - (struct sockaddr *)&addr6, - &size, - SOCK_NONBLOCK | SOCK_CLOEXEC); -#else - int connfd = - static_cast(::accept(sockFd_, (struct sockaddr *)&addr6, &size)); - setNonBlockAndCloseOnExec(connfd); -#endif - if (connfd >= 0) - { - peeraddr->setSockAddrInet6(addr6); - } - return connfd; -} -void Socket::closeWrite() -{ -#ifndef _WIN32 - if (::shutdown(sockFd_, SHUT_WR) < 0) -#else - if (::shutdown(sockFd_, SD_SEND) < 0) -#endif - { - LOG_SYSERR << "sockets::shutdownWrite"; - } -} -int Socket::read(char *buffer, uint64_t len) -{ -#ifndef _WIN32 - return ::read(sockFd_, buffer, len); -#else - return recv(sockFd_, buffer, static_cast(len), 0); -#endif -} - -struct sockaddr_in6 Socket::getLocalAddr(int sockfd) -{ - struct sockaddr_in6 localaddr; - memset(&localaddr, 0, sizeof(localaddr)); - socklen_t addrlen = static_cast(sizeof localaddr); - if (::getsockname(sockfd, - static_cast((void *)(&localaddr)), - &addrlen) < 0) - { - LOG_SYSERR << "sockets::getLocalAddr"; - } - return localaddr; -} - -struct sockaddr_in6 Socket::getPeerAddr(int sockfd) -{ - struct sockaddr_in6 peeraddr; - memset(&peeraddr, 0, sizeof(peeraddr)); - socklen_t addrlen = static_cast(sizeof peeraddr); - if (::getpeername(sockfd, - static_cast((void *)(&peeraddr)), - &addrlen) < 0) - { - LOG_SYSERR << "sockets::getPeerAddr"; - } - return peeraddr; -} - -void Socket::setTcpNoDelay(bool on) -{ -#ifdef _WIN32 - char optval = on ? 1 : 0; -#else - int optval = on ? 1 : 0; -#endif - ::setsockopt(sockFd_, - IPPROTO_TCP, - TCP_NODELAY, - &optval, - static_cast(sizeof optval)); - // TODO CHECK -} - -void Socket::setReuseAddr(bool on) -{ -#ifdef _WIN32 - char optval = on ? 1 : 0; -#else - int optval = on ? 1 : 0; -#endif - ::setsockopt(sockFd_, - SOL_SOCKET, - SO_REUSEADDR, - &optval, - static_cast(sizeof optval)); - // TODO CHECK -} - -void Socket::setReusePort(bool on) -{ -#ifdef SO_REUSEPORT -#ifdef _WIN32 - char optval = on ? 1 : 0; -#else - int optval = on ? 1 : 0; -#endif - int ret = ::setsockopt(sockFd_, - SOL_SOCKET, - SO_REUSEPORT, - &optval, - static_cast(sizeof optval)); - if (ret < 0 && on) - { - LOG_SYSERR << "SO_REUSEPORT failed."; - } -#else - if (on) - { - LOG_ERROR << "SO_REUSEPORT is not supported."; - } -#endif -} - -void Socket::setKeepAlive(bool on) -{ -#ifdef _WIN32 - char optval = on ? 1 : 0; -#else - int optval = on ? 1 : 0; -#endif - ::setsockopt(sockFd_, - SOL_SOCKET, - SO_KEEPALIVE, - &optval, - static_cast(sizeof optval)); - // TODO CHECK -} - -int Socket::getSocketError() -{ -#ifdef _WIN32 - char optval; -#else - int optval; -#endif - socklen_t optlen = static_cast(sizeof optval); - - if (::getsockopt(sockFd_, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) - { - return errno; - } - else - { - return optval; - } -} - -Socket::~Socket() -{ - LOG_TRACE << "Socket deconstructed:" << sockFd_; - if (sockFd_ >= 0) -#ifndef _WIN32 - close(sockFd_); -#else - closesocket(sockFd_); -#endif -} diff --git a/modules/trantor/trantor/net/inner/Socket.h b/modules/trantor/trantor/net/inner/Socket.h deleted file mode 100644 index 8cce9dd..0000000 --- a/modules/trantor/trantor/net/inner/Socket.h +++ /dev/null @@ -1,157 +0,0 @@ -/** - * - * Socket.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif -#include - -namespace trantor -{ -class Socket : NonCopyable -{ - 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(::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(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( - sizeof(struct sockaddr_in6))); - else - return ::connect(sockfd, - addr.getSockAddr(), - static_cast( - 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 - } -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/TcpConnectionImpl.cc b/modules/trantor/trantor/net/inner/TcpConnectionImpl.cc deleted file mode 100644 index 57ff1de..0000000 --- a/modules/trantor/trantor/net/inner/TcpConnectionImpl.cc +++ /dev/null @@ -1,1747 +0,0 @@ -/** - * - * @file TcpConnectionImpl.cc - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "TcpConnectionImpl.h" -#include "Socket.h" -#include "Channel.h" -#ifdef __linux__ -#include -#endif -#include -#ifndef _WIN32 -#include -#else -#include -#include -#include -#endif -#include -#include -#ifdef USE_OPENSSL -#include -#include -#include -#endif -#ifdef _WIN32 -#define stat _stati64 -#endif -#include - -using namespace trantor; - -#ifdef USE_OPENSSL -namespace trantor -{ -namespace internal -{ -#ifdef _WIN32 -// Code yanked from stackoverflow -// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store -inline bool loadWindowsSystemCert(X509_STORE *store) -{ - auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT"); - - if (!hStore) - { - return false; - } - - PCCERT_CONTEXT pContext = NULL; - while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != - nullptr) - { - auto encoded_cert = - static_cast(pContext->pbCertEncoded); - - auto x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); - if (x509) - { - X509_STORE_add_cert(store, x509); - X509_free(x509); - } - } - - CertFreeCertificateContext(pContext); - CertCloseStore(hStore, 0); - - return true; -} -#endif - -inline std::string certNameToRegex(const std::string &certName) -{ - std::string result; - result.reserve(certName.size() + 11); - - bool isStar = false; - bool isLeadingStar = true; - for (char ch : certName) - { - if (isStar == false) - { - if (ch == '*') - isStar = true; - else if (ch == '.') - { - result += "\\."; - isLeadingStar = false; - } - else - { - result.push_back(ch); - isLeadingStar = false; - } - } - else - { - if (ch == '.' && isLeadingStar) - result += "([^.]*\\.|)?"; - else - result += std::string("[^.]*") + ch; - isStar = false; - } - } - assert(isStar == false); - return result; -} - -inline bool verifyName(const std::string &certName, const std::string &hostname) -{ - std::regex re(certNameToRegex(certName)); - return std::regex_match(hostname, re); -} - -inline bool verifyCommonName(X509 *cert, const std::string &hostname) -{ - X509_NAME *subjectName = X509_get_subject_name(cert); - - if (subjectName != nullptr) - { - std::array name; - auto length = X509_NAME_get_text_by_NID(subjectName, - NID_commonName, - name.data(), - (int)name.size()); - if (length == -1) - return false; - - return verifyName(std::string(name.begin(), name.begin() + length), - hostname); - } - - return false; -} - -inline bool verifyAltName(X509 *cert, const std::string &hostname) -{ - bool good = false; - auto altNames = static_cast( - X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr)); - - if (altNames) - { - int numNames = sk_GENERAL_NAME_num(altNames); - - for (int i = 0; i < numNames && !good; i++) - { - auto val = sk_GENERAL_NAME_value(altNames, i); - if (val->type != GEN_DNS) - { - LOG_WARN << "Name using IP addresses are not supported. Open " - "an issue if you need that feature"; - continue; - } -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) - auto name = (const char *)ASN1_STRING_get0_data(val->d.ia5); -#else - auto name = (const char *)ASN1_STRING_data(val->d.ia5); -#endif - auto name_len = (size_t)ASN1_STRING_length(val->d.ia5); - good = verifyName(std::string(name, name + name_len), hostname); - } - } - - GENERAL_NAMES_free((STACK_OF(GENERAL_NAME) *)altNames); - return good; -} - -} // namespace internal - -void initOpenSSL() -{ -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ - (defined(LIBRESSL_VERSION_NUMBER) && \ - LIBRESSL_VERSION_NUMBER < 0x20700000L) - // Initialize OpenSSL once; - static std::once_flag once; - std::call_once(once, []() { - SSL_library_init(); - ERR_load_crypto_strings(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - }); -#endif -} - -class SSLContext -{ - public: - explicit SSLContext( - bool useOldTLS, - bool enableValidtion, - const std::vector> &sslConfCmds) - { -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) - ctxPtr_ = SSL_CTX_new(TLS_method()); - SSL_CONF_CTX *cctx = SSL_CONF_CTX_new(); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); - SSL_CONF_CTX_set_ssl_ctx(cctx, ctxPtr_); - for (const auto &cmd : sslConfCmds) - { - SSL_CONF_cmd(cctx, cmd.first.data(), cmd.second.data()); - } - SSL_CONF_CTX_finish(cctx); - if (!useOldTLS) - { - SSL_CTX_set_min_proto_version(ctxPtr_, TLS1_2_VERSION); - } - else - { - LOG_WARN << "TLS 1.0/1.1 are enabled. They are considered " - "obsolete, insecure standards and should only be " - "used for legacy purpose."; - } -#else - ctxPtr_ = SSL_CTX_new(SSLv23_method()); - SSL_CONF_CTX *cctx = SSL_CONF_CTX_new(); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); - SSL_CONF_CTX_set_ssl_ctx(cctx, ctxPtr_); - for (const auto &cmd : sslConfCmds) - { - SSL_CONF_cmd(cctx, cmd.first.data(), cmd.second.data()); - } - SSL_CONF_CTX_finish(cctx); - if (!useOldTLS) - { - SSL_CTX_set_options(ctxPtr_, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); - } - else - { - LOG_WARN << "TLS 1.0/1.1 are enabled. They are considered " - "obsolete, insecure standards and should only be " - "used for legacy purpose."; - } -#endif -#ifdef _WIN32 - if (enableValidtion) - internal::loadWindowsSystemCert(SSL_CTX_get_cert_store(ctxPtr_)); -#else - if (enableValidtion) - SSL_CTX_set_default_verify_paths(ctxPtr_); -#endif - } - ~SSLContext() - { - if (ctxPtr_) - { - SSL_CTX_free(ctxPtr_); - } - } - - SSL_CTX *get() - { - return ctxPtr_; - } - - private: - SSL_CTX *ctxPtr_; -}; -class SSLConn -{ - public: - explicit SSLConn(SSL_CTX *ctx) - { - SSL_ = SSL_new(ctx); - } - ~SSLConn() - { - if (SSL_) - { - SSL_free(SSL_); - } - } - SSL *get() - { - return SSL_; - } - - private: - SSL *SSL_; -}; - -std::shared_ptr newSSLContext( - bool useOldTLS, - bool validateCert, - const std::vector> &sslConfCmds) -{ // init OpenSSL - initOpenSSL(); - return std::make_shared(useOldTLS, validateCert, sslConfCmds); -} -std::shared_ptr newSSLServerContext( - const std::string &certPath, - const std::string &keyPath, - bool useOldTLS, - const std::vector> &sslConfCmds) -{ - auto ctx = newSSLContext(useOldTLS, false, sslConfCmds); - auto r = SSL_CTX_use_certificate_chain_file(ctx->get(), certPath.c_str()); - if (!r) - { -#ifndef _MSC_VER - LOG_FATAL << strerror(errno); -#else - LOG_FATAL << strerror_tl(errno); -#endif - abort(); - } - r = SSL_CTX_use_PrivateKey_file(ctx->get(), - keyPath.c_str(), - SSL_FILETYPE_PEM); - if (!r) - { -#ifndef _MSC_VER - LOG_FATAL << strerror(errno); -#else - LOG_FATAL << strerror_tl(errno); -#endif - abort(); - } - r = SSL_CTX_check_private_key(ctx->get()); - if (!r) - { -#ifndef _MSC_VER - LOG_FATAL << strerror(errno); -#else - LOG_FATAL << strerror_tl(errno); -#endif - abort(); - } - return ctx; -} -} // namespace trantor -#else -namespace trantor -{ -std::shared_ptr newSSLServerContext( - const std::string &certPath, - const std::string &keyPath, - bool useOldTLS, - const std::vector> &sslConfCmds) -{ - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -} -} // namespace trantor -#endif - -TcpConnectionImpl::TcpConnectionImpl(EventLoop *loop, - int socketfd, - const InetAddress &localAddr, - const InetAddress &peerAddr) - : loop_(loop), - ioChannelPtr_(new Channel(loop, socketfd)), - socketPtr_(new Socket(socketfd)), - localAddr_(localAddr), - peerAddr_(peerAddr) -{ - LOG_TRACE << "new connection:" << peerAddr.toIpPort() << "->" - << localAddr.toIpPort(); - ioChannelPtr_->setReadCallback( - std::bind(&TcpConnectionImpl::readCallback, this)); - ioChannelPtr_->setWriteCallback( - std::bind(&TcpConnectionImpl::writeCallback, this)); - ioChannelPtr_->setCloseCallback( - std::bind(&TcpConnectionImpl::handleClose, this)); - ioChannelPtr_->setErrorCallback( - std::bind(&TcpConnectionImpl::handleError, this)); - socketPtr_->setKeepAlive(true); - name_ = localAddr.toIpPort() + "--" + peerAddr.toIpPort(); -} -TcpConnectionImpl::~TcpConnectionImpl() -{ -} -#ifdef USE_OPENSSL -void TcpConnectionImpl::startClientEncryptionInLoop( - std::function &&callback, - bool useOldTLS, - bool validateCert, - const std::string &hostname, - const std::vector> &sslConfCmds) -{ - validateCert_ = validateCert; - loop_->assertInLoopThread(); - if (isEncrypted_) - { - LOG_WARN << "This connection is already encrypted"; - return; - } - sslEncryptionPtr_ = std::make_unique(); - sslEncryptionPtr_->upgradeCallback_ = std::move(callback); - sslEncryptionPtr_->sslCtxPtr_ = - newSSLContext(useOldTLS, validateCert_, sslConfCmds); - sslEncryptionPtr_->sslPtr_ = - std::make_unique(sslEncryptionPtr_->sslCtxPtr_->get()); - if (validateCert) - { - SSL_set_verify(sslEncryptionPtr_->sslPtr_->get(), - SSL_VERIFY_NONE, - nullptr); - validateCert_ = validateCert; - } - if (!hostname.empty()) - { - SSL_set_tlsext_host_name(sslEncryptionPtr_->sslPtr_->get(), - hostname.data()); - sslEncryptionPtr_->hostname_ = hostname; - } - isEncrypted_ = true; - sslEncryptionPtr_->isUpgrade_ = true; - auto r = SSL_set_fd(sslEncryptionPtr_->sslPtr_->get(), socketPtr_->fd()); - (void)r; - assert(r); - sslEncryptionPtr_->sendBufferPtr_ = - std::make_unique>(); - LOG_TRACE << "connectEstablished"; - ioChannelPtr_->enableWriting(); - SSL_set_connect_state(sslEncryptionPtr_->sslPtr_->get()); -} -void TcpConnectionImpl::startServerEncryptionInLoop( - const std::shared_ptr &ctx, - std::function &&callback) -{ - loop_->assertInLoopThread(); - if (isEncrypted_) - { - LOG_WARN << "This connection is already encrypted"; - return; - } - sslEncryptionPtr_ = std::make_unique(); - sslEncryptionPtr_->upgradeCallback_ = std::move(callback); - sslEncryptionPtr_->sslCtxPtr_ = ctx; - sslEncryptionPtr_->isServer_ = true; - sslEncryptionPtr_->sslPtr_ = - std::make_unique(sslEncryptionPtr_->sslCtxPtr_->get()); - isEncrypted_ = true; - sslEncryptionPtr_->isUpgrade_ = true; - if (sslEncryptionPtr_->isServer_ == false) - SSL_set_verify(sslEncryptionPtr_->sslPtr_->get(), - SSL_VERIFY_NONE, - nullptr); - auto r = SSL_set_fd(sslEncryptionPtr_->sslPtr_->get(), socketPtr_->fd()); - (void)r; - assert(r); - sslEncryptionPtr_->sendBufferPtr_ = - std::make_unique>(); - LOG_TRACE << "upgrade to ssl"; - SSL_set_accept_state(sslEncryptionPtr_->sslPtr_->get()); -} -#endif -void TcpConnectionImpl::startServerEncryption( - const std::shared_ptr &ctx, - std::function callback) -{ -#ifndef USE_OPENSSL - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -#else - if (loop_->isInLoopThread()) - { - startServerEncryptionInLoop(ctx, std::move(callback)); - } - else - { - loop_->queueInLoop([thisPtr = shared_from_this(), - ctx, - callback = std::move(callback)]() mutable { - thisPtr->startServerEncryptionInLoop(ctx, std::move(callback)); - }); - } - -#endif -} -void TcpConnectionImpl::startClientEncryption( - std::function callback, - bool useOldTLS, - bool validateCert, - std::string hostname, - const std::vector> &sslConfCmds) -{ -#ifndef USE_OPENSSL - LOG_FATAL << "OpenSSL is not found in your system!"; - abort(); -#else - if (!hostname.empty()) - { - std::transform(hostname.begin(), - hostname.end(), - hostname.begin(), - tolower); - assert(sslEncryptionPtr_ != nullptr); - sslEncryptionPtr_->hostname_ = hostname; - } - if (loop_->isInLoopThread()) - { - startClientEncryptionInLoop(std::move(callback), - useOldTLS, - validateCert, - hostname, - sslConfCmds); - } - else - { - loop_->queueInLoop([thisPtr = shared_from_this(), - callback = std::move(callback), - useOldTLS, - hostname = std::move(hostname), - validateCert, - &sslConfCmds]() mutable { - thisPtr->startClientEncryptionInLoop(std::move(callback), - useOldTLS, - validateCert, - hostname, - sslConfCmds); - }); - } -#endif -} -void TcpConnectionImpl::readCallback() -{ -// LOG_TRACE<<"read Callback"; -#ifdef USE_OPENSSL - if (!isEncrypted_) - { -#endif - loop_->assertInLoopThread(); - int ret = 0; - - ssize_t n = readBuffer_.readFd(socketPtr_->fd(), &ret); - // LOG_TRACE<<"read "< 0) - { - bytesReceived_ += n; - if (recvMsgCallback_) - { - recvMsgCallback_(shared_from_this(), &readBuffer_); - } - } -#ifdef USE_OPENSSL - } - else - { - LOG_TRACE << "read Callback"; - loop_->assertInLoopThread(); - if (sslEncryptionPtr_->statusOfSSL_ == SSLStatus::Handshaking) - { - doHandshaking(); - return; - } - else if (sslEncryptionPtr_->statusOfSSL_ == SSLStatus::Connected) - { - int rd; - bool newDataFlag = false; - size_t readLength; - do - { - readBuffer_.ensureWritableBytes(1024); - readLength = readBuffer_.writableBytes(); - rd = SSL_read(sslEncryptionPtr_->sslPtr_->get(), - readBuffer_.beginWrite(), - static_cast(readLength)); - LOG_TRACE << "ssl read:" << rd << " bytes"; - if (rd <= 0) - { - int sslerr = - SSL_get_error(sslEncryptionPtr_->sslPtr_->get(), rd); - if (sslerr == SSL_ERROR_WANT_READ) - { - break; - } - else - { - LOG_TRACE << "ssl read err:" << sslerr; - sslEncryptionPtr_->statusOfSSL_ = - SSLStatus::DisConnected; - handleClose(); - return; - } - } - readBuffer_.hasWritten(rd); - newDataFlag = true; - } while ((size_t)rd == readLength); - if (newDataFlag) - { - // Run callback function - recvMsgCallback_(shared_from_this(), &readBuffer_); - } - } - } -#endif -} -void TcpConnectionImpl::extendLife() -{ - if (idleTimeout_ > 0) - { - auto now = Date::date(); - if (now < lastTimingWheelUpdateTime_.after(1.0)) - return; - lastTimingWheelUpdateTime_ = now; - auto entry = kickoffEntry_.lock(); - if (entry) - { - auto timingWheelPtr = timingWheelWeakPtr_.lock(); - if (timingWheelPtr) - timingWheelPtr->insertEntry(idleTimeout_, entry); - } - } -} -void TcpConnectionImpl::writeCallback() -{ -#ifdef USE_OPENSSL - if (!isEncrypted_ || - (sslEncryptionPtr_ && - sslEncryptionPtr_->statusOfSSL_ == SSLStatus::Connected)) - { -#endif - loop_->assertInLoopThread(); - extendLife(); - if (ioChannelPtr_->isWriting()) - { - assert(!writeBufferList_.empty()); - auto writeBuffer_ = writeBufferList_.front(); -#ifndef _WIN32 - if (writeBuffer_->sendFd_ < 0) -#else - if (writeBuffer_->sendFp_ == nullptr) -#endif - { - if (writeBuffer_->msgBuffer_->readableBytes() <= 0) - { - writeBufferList_.pop_front(); - if (writeBufferList_.empty()) - { - ioChannelPtr_->disableWriting(); - // - if (writeCompleteCallback_) - writeCompleteCallback_(shared_from_this()); - if (status_ == ConnStatus::Disconnecting) - { - socketPtr_->closeWrite(); - } - } - else - { - auto fileNode = writeBufferList_.front(); -#ifndef _WIN32 - assert(fileNode->sendFd_ >= 0); -#else - assert(fileNode->sendFp_); -#endif - sendFileInLoop(fileNode); - } - } - else - { - auto n = - writeInLoop(writeBuffer_->msgBuffer_->peek(), - writeBuffer_->msgBuffer_->readableBytes()); - if (n >= 0) - { - writeBuffer_->msgBuffer_->retrieve(n); - } - else - { -#ifdef _WIN32 - if (errno != 0 && errno != EWOULDBLOCK) -#else - if (errno != EWOULDBLOCK) -#endif - { - // TODO: any others? - if (errno == EPIPE || errno == ECONNRESET) - { - LOG_DEBUG << "EPIPE or ECONNRESET, erron=" - << errno; - return; - } - LOG_SYSERR << "Unexpected error(" << errno << ")"; - return; - } - } - } - } - else - { - // file - if (writeBuffer_->fileBytesToSend_ <= 0) - { - writeBufferList_.pop_front(); - if (writeBufferList_.empty()) - { - ioChannelPtr_->disableWriting(); - if (writeCompleteCallback_) - writeCompleteCallback_(shared_from_this()); - if (status_ == ConnStatus::Disconnecting) - { - socketPtr_->closeWrite(); - } - } - else - { -#ifndef _WIN32 - if (writeBufferList_.front()->sendFd_ < 0) -#else - if (writeBufferList_.front()->sendFp_ == nullptr) -#endif - { - // There is data to be sent in the buffer. - auto n = writeInLoop( - writeBufferList_.front()->msgBuffer_->peek(), - writeBufferList_.front() - ->msgBuffer_->readableBytes()); - if (n >= 0) - { - writeBufferList_.front()->msgBuffer_->retrieve( - n); - } - else - { -#ifdef _WIN32 - if (errno != 0 && errno != EWOULDBLOCK) -#else - if (errno != EWOULDBLOCK) -#endif - { - // TODO: any others? - if (errno == EPIPE || errno == ECONNRESET) - { - LOG_DEBUG - << "EPIPE or ECONNRESET, erron=" - << errno; - return; - } - LOG_SYSERR << "Unexpected error(" << errno - << ")"; - return; - } - } - } - else - { - // more file - sendFileInLoop(writeBufferList_.front()); - } - } - } - else - { - sendFileInLoop(writeBuffer_); - } - } - } - else - { - LOG_SYSERR << "no writing but call write callback"; - } -#ifdef USE_OPENSSL - } - else - { - LOG_TRACE << "write Callback"; - loop_->assertInLoopThread(); - if (sslEncryptionPtr_->statusOfSSL_ == SSLStatus::Handshaking) - { - doHandshaking(); - return; - } - } -#endif -} -void TcpConnectionImpl::connectEstablished() -{ -// loop_->assertInLoopThread(); -#ifdef USE_OPENSSL - if (!isEncrypted_) - { -#endif - auto thisPtr = shared_from_this(); - loop_->runInLoop([thisPtr]() { - LOG_TRACE << "connectEstablished"; - assert(thisPtr->status_ == ConnStatus::Connecting); - thisPtr->ioChannelPtr_->tie(thisPtr); - thisPtr->ioChannelPtr_->enableReading(); - thisPtr->status_ = ConnStatus::Connected; - if (thisPtr->connectionCallback_) - thisPtr->connectionCallback_(thisPtr); - }); -#ifdef USE_OPENSSL - } - else - { - loop_->runInLoop([thisPtr = shared_from_this()]() { - LOG_TRACE << "connectEstablished"; - assert(thisPtr->status_ == ConnStatus::Connecting); - thisPtr->ioChannelPtr_->tie(thisPtr); - thisPtr->ioChannelPtr_->enableReading(); - thisPtr->status_ = ConnStatus::Connected; - if (thisPtr->sslEncryptionPtr_->isServer_) - { - SSL_set_accept_state( - thisPtr->sslEncryptionPtr_->sslPtr_->get()); - } - else - { - thisPtr->ioChannelPtr_->enableWriting(); - SSL_set_connect_state( - thisPtr->sslEncryptionPtr_->sslPtr_->get()); - } - }); - } -#endif -} -void TcpConnectionImpl::handleClose() -{ - LOG_TRACE << "connection closed, fd=" << socketPtr_->fd(); - loop_->assertInLoopThread(); - status_ = ConnStatus::Disconnected; - ioChannelPtr_->disableAll(); - // ioChannelPtr_->remove(); - auto guardThis = shared_from_this(); - if (connectionCallback_) - connectionCallback_(guardThis); - if (closeCallback_) - { - LOG_TRACE << "to call close callback"; - closeCallback_(guardThis); - } -} -void TcpConnectionImpl::handleError() -{ - int err = socketPtr_->getSocketError(); - if (err == 0) - return; - if (err == EPIPE || err == ECONNRESET || err == 104) - { - LOG_DEBUG << "[" << name_ << "] - SO_ERROR = " << err << " " - << strerror_tl(err); - } - else - { - LOG_ERROR << "[" << name_ << "] - SO_ERROR = " << err << " " - << strerror_tl(err); - } -} -void TcpConnectionImpl::setTcpNoDelay(bool on) -{ - socketPtr_->setTcpNoDelay(on); -} -void TcpConnectionImpl::connectDestroyed() -{ - loop_->assertInLoopThread(); - if (status_ == ConnStatus::Connected) - { - status_ = ConnStatus::Disconnected; - ioChannelPtr_->disableAll(); - - connectionCallback_(shared_from_this()); - } - ioChannelPtr_->remove(); -} -void TcpConnectionImpl::shutdown() -{ - auto thisPtr = shared_from_this(); - loop_->runInLoop([thisPtr]() { - if (thisPtr->status_ == ConnStatus::Connected) - { - thisPtr->status_ = ConnStatus::Disconnecting; - if (!thisPtr->ioChannelPtr_->isWriting()) - { - thisPtr->socketPtr_->closeWrite(); - } - } - }); -} - -void TcpConnectionImpl::forceClose() -{ - auto thisPtr = shared_from_this(); - loop_->runInLoop([thisPtr]() { - if (thisPtr->status_ == ConnStatus::Connected || - thisPtr->status_ == ConnStatus::Disconnecting) - { - thisPtr->status_ = ConnStatus::Disconnecting; - thisPtr->handleClose(); - } - }); -} -#ifndef _WIN32 -void TcpConnectionImpl::sendInLoop(const void *buffer, size_t length) -#else -void TcpConnectionImpl::sendInLoop(const char *buffer, size_t length) -#endif -{ - loop_->assertInLoopThread(); - if (status_ != ConnStatus::Connected) - { - LOG_WARN << "Connection is not connected,give up sending"; - return; - } - extendLife(); - size_t remainLen = length; - ssize_t sendLen = 0; - if (!ioChannelPtr_->isWriting() && writeBufferList_.empty()) - { - // send directly - sendLen = writeInLoop(buffer, length); - if (sendLen < 0) - { - // error -#ifdef _WIN32 - if (errno != 0 && errno != EWOULDBLOCK) -#else - if (errno != EWOULDBLOCK) -#endif - { - if (errno == EPIPE || errno == ECONNRESET) // TODO: any others? - { - LOG_DEBUG << "EPIPE or ECONNRESET, erron=" << errno; - return; - } - LOG_SYSERR << "Unexpected error(" << errno << ")"; - return; - } - sendLen = 0; - } - remainLen -= sendLen; - } - if (remainLen > 0 && status_ == ConnStatus::Connected) - { - if (writeBufferList_.empty()) - { - BufferNodePtr node(new BufferNode); - node->msgBuffer_ = std::make_shared(); - writeBufferList_.push_back(std::move(node)); - } -#ifndef _WIN32 - else if (writeBufferList_.back()->sendFd_ >= 0) -#else - else if (writeBufferList_.back()->sendFp_) -#endif - { - BufferNodePtr node(new BufferNode); - node->msgBuffer_ = std::make_shared(); - writeBufferList_.push_back(std::move(node)); - } - writeBufferList_.back()->msgBuffer_->append( - static_cast(buffer) + sendLen, remainLen); - if (!ioChannelPtr_->isWriting()) - ioChannelPtr_->enableWriting(); - if (highWaterMarkCallback_ && - writeBufferList_.back()->msgBuffer_->readableBytes() > - highWaterMarkLen_) - { - highWaterMarkCallback_( - shared_from_this(), - writeBufferList_.back()->msgBuffer_->readableBytes()); - } - } -} -// The order of data sending should be same as the order of calls of send() -void TcpConnectionImpl::send(const std::shared_ptr &msgPtr) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(msgPtr->data(), msgPtr->length()); - } - else - { - ++sendNum_; - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, msgPtr]() { - thisPtr->sendInLoop(msgPtr->data(), msgPtr->length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, msgPtr]() { - thisPtr->sendInLoop(msgPtr->data(), msgPtr->length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} -// The order of data sending should be same as the order of calls of send() -void TcpConnectionImpl::send(const std::shared_ptr &msgPtr) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(msgPtr->peek(), msgPtr->readableBytes()); - } - else - { - ++sendNum_; - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, msgPtr]() { - thisPtr->sendInLoop(msgPtr->peek(), msgPtr->readableBytes()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, msgPtr]() { - thisPtr->sendInLoop(msgPtr->peek(), msgPtr->readableBytes()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} -void TcpConnectionImpl::send(const char *msg, size_t len) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(msg, len); - } - else - { - ++sendNum_; - auto buffer = std::make_shared(msg, len); - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, buffer]() { - thisPtr->sendInLoop(buffer->data(), buffer->length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto buffer = std::make_shared(msg, len); - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, buffer]() { - thisPtr->sendInLoop(buffer->data(), buffer->length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} -void TcpConnectionImpl::send(const void *msg, size_t len) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { -#ifndef _WIN32 - sendInLoop(msg, len); -#else - sendInLoop(static_cast(msg), len); -#endif - } - else - { - ++sendNum_; - auto buffer = - std::make_shared(static_cast(msg), - len); - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, buffer]() { - thisPtr->sendInLoop(buffer->data(), buffer->length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto buffer = - std::make_shared(static_cast(msg), len); - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, buffer]() { - thisPtr->sendInLoop(buffer->data(), buffer->length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} -void TcpConnectionImpl::send(const std::string &msg) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(msg.data(), msg.length()); - } - else - { - ++sendNum_; - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, msg]() { - thisPtr->sendInLoop(msg.data(), msg.length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, msg]() { - thisPtr->sendInLoop(msg.data(), msg.length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} -void TcpConnectionImpl::send(std::string &&msg) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(msg.data(), msg.length()); - } - else - { - auto thisPtr = shared_from_this(); - ++sendNum_; - loop_->queueInLoop([thisPtr, msg = std::move(msg)]() { - thisPtr->sendInLoop(msg.data(), msg.length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, msg = std::move(msg)]() { - thisPtr->sendInLoop(msg.data(), msg.length()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} - -void TcpConnectionImpl::send(const MsgBuffer &buffer) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(buffer.peek(), buffer.readableBytes()); - } - else - { - ++sendNum_; - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, buffer]() { - thisPtr->sendInLoop(buffer.peek(), buffer.readableBytes()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, buffer]() { - thisPtr->sendInLoop(buffer.peek(), buffer.readableBytes()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} - -void TcpConnectionImpl::send(MsgBuffer &&buffer) -{ - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - sendInLoop(buffer.peek(), buffer.readableBytes()); - } - else - { - ++sendNum_; - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, buffer = std::move(buffer)]() { - thisPtr->sendInLoop(buffer.peek(), buffer.readableBytes()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, buffer = std::move(buffer)]() { - thisPtr->sendInLoop(buffer.peek(), buffer.readableBytes()); - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - }); - } -} -void TcpConnectionImpl::sendFile(const char *fileName, - size_t offset, - size_t length) -{ - assert(fileName); -#ifndef _WIN32 - int fd = open(fileName, O_RDONLY); - - if (fd < 0) - { - LOG_SYSERR << fileName << " open error"; - return; - } - - if (length == 0) - { - struct stat filestat; - if (stat(fileName, &filestat) < 0) - { - LOG_SYSERR << fileName << " stat error"; - close(fd); - return; - } - length = filestat.st_size; - } - - sendFile(fd, offset, length); -#else -#ifndef _MSC_VER - auto fp = fopen(fileName, "rb"); -#else - FILE *fp; - if (fopen_s(&fp, fileName, "rb") != 0) - { - fp = nullptr; - } -#endif - if (fp == nullptr) - { - LOG_SYSERR << fileName << " open error"; - return; - } - - if (length == 0) - { - struct stat filestat; - if (stat(fileName, &filestat) < 0) - { - LOG_SYSERR << fileName << " stat error"; - fclose(fp); - return; - } - length = filestat.st_size; - } - - sendFile(fp, offset, length); -#endif -} - -#ifndef _WIN32 -void TcpConnectionImpl::sendFile(int sfd, size_t offset, size_t length) -#else -void TcpConnectionImpl::sendFile(FILE *fp, size_t offset, size_t length) -#endif -{ - assert(length > 0); -#ifndef _WIN32 - assert(sfd >= 0); - BufferNodePtr node(new BufferNode); - node->sendFd_ = sfd; -#else - assert(fp); - BufferNodePtr node(new BufferNode); - node->sendFp_ = fp; -#endif - node->offset_ = static_cast(offset); - node->fileBytesToSend_ = length; - if (loop_->isInLoopThread()) - { - std::lock_guard guard(sendNumMutex_); - if (sendNum_ == 0) - { - writeBufferList_.push_back(node); - if (writeBufferList_.size() == 1) - { - sendFileInLoop(writeBufferList_.front()); - return; - } - } - else - { - ++sendNum_; - auto thisPtr = shared_from_this(); - loop_->queueInLoop([thisPtr, node]() { - thisPtr->writeBufferList_.push_back(node); - { - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - } - - if (thisPtr->writeBufferList_.size() == 1) - { - thisPtr->sendFileInLoop(thisPtr->writeBufferList_.front()); - } - }); - } - } - else - { - auto thisPtr = shared_from_this(); - std::lock_guard guard(sendNumMutex_); - ++sendNum_; - loop_->queueInLoop([thisPtr, node]() { - LOG_TRACE << "Push sendfile to list"; - thisPtr->writeBufferList_.push_back(node); - - { - std::lock_guard guard1(thisPtr->sendNumMutex_); - --thisPtr->sendNum_; - } - - if (thisPtr->writeBufferList_.size() == 1) - { - thisPtr->sendFileInLoop(thisPtr->writeBufferList_.front()); - } - }); - } -} - -void TcpConnectionImpl::sendFileInLoop(const BufferNodePtr &filePtr) -{ - loop_->assertInLoopThread(); -#ifndef _WIN32 - assert(filePtr->sendFd_ >= 0); -#else - assert(filePtr->sendFp_); -#endif -#ifdef __linux__ - if (!isEncrypted_) - { - auto bytesSent = sendfile(socketPtr_->fd(), - filePtr->sendFd_, - &filePtr->offset_, - filePtr->fileBytesToSend_); - if (bytesSent < 0) - { - if (errno != EAGAIN) - { - LOG_SYSERR << "TcpConnectionImpl::sendFileInLoop"; - if (ioChannelPtr_->isWriting()) - ioChannelPtr_->disableWriting(); - } - return; - } - if (bytesSent < filePtr->fileBytesToSend_) - { - if (bytesSent == 0) - { - LOG_SYSERR << "TcpConnectionImpl::sendFileInLoop"; - return; - } - } - LOG_TRACE << "sendfile() " << bytesSent << " bytes sent"; - filePtr->fileBytesToSend_ -= bytesSent; - if (!ioChannelPtr_->isWriting()) - { - ioChannelPtr_->enableWriting(); - } - return; - } -#endif -#ifndef _WIN32 - lseek(filePtr->sendFd_, filePtr->offset_, SEEK_SET); - if (!fileBufferPtr_) - { - fileBufferPtr_ = std::make_unique>(16 * 1024); - } - while (filePtr->fileBytesToSend_ > 0) - { - auto n = read(filePtr->sendFd_, - &(*fileBufferPtr_)[0], - fileBufferPtr_->size()); -#else - _fseeki64(filePtr->sendFp_, filePtr->offset_, SEEK_SET); - if (!fileBufferPtr_) - { - fileBufferPtr_ = std::make_unique>(16 * 1024); - } - while (filePtr->fileBytesToSend_ > 0) - { - auto n = fread(&(*fileBufferPtr_)[0], - 1, - fileBufferPtr_->size(), - filePtr->sendFp_); -#endif - if (n > 0) - { - auto nSend = writeInLoop(&(*fileBufferPtr_)[0], n); - if (nSend >= 0) - { - filePtr->fileBytesToSend_ -= nSend; - filePtr->offset_ += static_cast(nSend); - if (static_cast(nSend) < static_cast(n)) - { - if (!ioChannelPtr_->isWriting()) - { - ioChannelPtr_->enableWriting(); - } - return; - } - else if (nSend == n) - continue; - } - if (nSend < 0) - { -#ifdef _WIN32 - if (errno != 0 && errno != EWOULDBLOCK) -#else - if (errno != EWOULDBLOCK) -#endif - { - // TODO: any others? - if (errno == EPIPE || errno == ECONNRESET) - { - LOG_DEBUG << "EPIPE or ECONNRESET, erron=" << errno; - return; - } - LOG_SYSERR << "Unexpected error(" << errno << ")"; - return; - } - break; - } - } - if (n < 0) - { - LOG_SYSERR << "read error"; - if (ioChannelPtr_->isWriting()) - ioChannelPtr_->disableWriting(); - return; - } - if (n == 0) - { - LOG_SYSERR << "read"; - return; - } - } - if (!ioChannelPtr_->isWriting()) - { - ioChannelPtr_->enableWriting(); - } -} -#ifndef _WIN32 -ssize_t TcpConnectionImpl::writeInLoop(const void *buffer, size_t length) -#else -ssize_t TcpConnectionImpl::writeInLoop(const char *buffer, size_t length) -#endif -{ -#ifdef USE_OPENSSL - if (!isEncrypted_) - { -#endif - bytesSent_ += length; -#ifndef _WIN32 - return write(socketPtr_->fd(), buffer, length); -#else - errno = 0; - return ::send(socketPtr_->fd(), buffer, static_cast(length), 0); -#endif -#ifdef USE_OPENSSL - } - else - { - LOG_TRACE << "send in loop"; - loop_->assertInLoopThread(); - if (status_ != ConnStatus::Connected && - status_ != ConnStatus::Disconnecting) - { - LOG_WARN << "Connection is not connected,give up sending"; - return -1; - } - if (sslEncryptionPtr_->statusOfSSL_ != SSLStatus::Connected) - { - LOG_WARN << "SSL is not connected,give up sending"; - return -1; - } - // send directly - size_t sendTotalLen = 0; - while (sendTotalLen < length) - { - auto len = length - sendTotalLen; - if (len > sslEncryptionPtr_->sendBufferPtr_->size()) - { - len = sslEncryptionPtr_->sendBufferPtr_->size(); - } - memcpy(sslEncryptionPtr_->sendBufferPtr_->data(), - static_cast(buffer) + sendTotalLen, - len); - ERR_clear_error(); - auto sendLen = SSL_write(sslEncryptionPtr_->sslPtr_->get(), - sslEncryptionPtr_->sendBufferPtr_->data(), - static_cast(len)); - if (sendLen <= 0) - { - int sslerr = - SSL_get_error(sslEncryptionPtr_->sslPtr_->get(), sendLen); - if (sslerr != SSL_ERROR_WANT_WRITE && - sslerr != SSL_ERROR_WANT_READ) - { - // LOG_ERROR << "ssl write error:" << sslerr; - forceClose(); - return -1; - } - return sendTotalLen; - } - sendTotalLen += sendLen; - } - return sendTotalLen; - } -#endif -} - -#ifdef USE_OPENSSL - -TcpConnectionImpl::TcpConnectionImpl(EventLoop *loop, - int socketfd, - const InetAddress &localAddr, - const InetAddress &peerAddr, - const std::shared_ptr &ctxPtr, - bool isServer, - bool validateCert, - const std::string &hostname) - : isEncrypted_(true), - loop_(loop), - ioChannelPtr_(new Channel(loop, socketfd)), - socketPtr_(new Socket(socketfd)), - localAddr_(localAddr), - peerAddr_(peerAddr) -{ - LOG_TRACE << "new connection:" << peerAddr.toIpPort() << "->" - << localAddr.toIpPort(); - ioChannelPtr_->setReadCallback( - std::bind(&TcpConnectionImpl::readCallback, this)); - ioChannelPtr_->setWriteCallback( - std::bind(&TcpConnectionImpl::writeCallback, this)); - ioChannelPtr_->setCloseCallback( - std::bind(&TcpConnectionImpl::handleClose, this)); - ioChannelPtr_->setErrorCallback( - std::bind(&TcpConnectionImpl::handleError, this)); - socketPtr_->setKeepAlive(true); - name_ = localAddr.toIpPort() + "--" + peerAddr.toIpPort(); - sslEncryptionPtr_ = std::make_unique(); - sslEncryptionPtr_->sslPtr_ = std::make_unique(ctxPtr->get()); - sslEncryptionPtr_->isServer_ = isServer; - validateCert_ = validateCert; - if (isServer == false) - SSL_set_verify(sslEncryptionPtr_->sslPtr_->get(), - SSL_VERIFY_NONE, - nullptr); - if (!isServer && !hostname.empty()) - { - SSL_set_tlsext_host_name(sslEncryptionPtr_->sslPtr_->get(), - hostname.data()); - sslEncryptionPtr_->hostname_ = hostname; - } - assert(sslEncryptionPtr_->sslPtr_); - auto r = SSL_set_fd(sslEncryptionPtr_->sslPtr_->get(), socketfd); - (void)r; - assert(r); - isEncrypted_ = true; - sslEncryptionPtr_->sendBufferPtr_ = - std::make_unique>(); -} - -bool TcpConnectionImpl::validatePeerCertificate() -{ - LOG_TRACE << "Validating peer cerificate"; - assert(sslEncryptionPtr_ != nullptr); - assert(sslEncryptionPtr_->sslPtr_ != nullptr); - SSL *ssl = sslEncryptionPtr_->sslPtr_->get(); - - auto result = SSL_get_verify_result(ssl); - if (result != X509_V_OK) - { - LOG_DEBUG << "cert error code: " << result; - LOG_ERROR << "Server certificate is not valid"; - return false; - } - - X509 *cert = SSL_get_peer_certificate(ssl); - if (cert == nullptr) - { - LOG_ERROR << "Unable to obtain peer certificate"; - return false; - } - - bool domainIsValid = - internal::verifyCommonName(cert, sslEncryptionPtr_->hostname_) || - internal::verifyAltName(cert, sslEncryptionPtr_->hostname_); - X509_free(cert); - - if (domainIsValid) - { - return true; - } - else - { - LOG_ERROR << "Domain validation failed"; - return false; - } -} - -void TcpConnectionImpl::doHandshaking() -{ - assert(sslEncryptionPtr_->statusOfSSL_ == SSLStatus::Handshaking); - - int r = SSL_do_handshake(sslEncryptionPtr_->sslPtr_->get()); - LOG_TRACE << "hand shaking: " << r; - if (r == 1) - { - // Clients don't commonly have certificates. Let's not validate - // that - if (validateCert_ && sslEncryptionPtr_->isServer_ == false) - { - if (validatePeerCertificate() == false) - { - LOG_ERROR << "SSL certificate validation failed."; - ioChannelPtr_->disableReading(); - sslEncryptionPtr_->statusOfSSL_ = SSLStatus::DisConnected; - if (sslErrorCallback_) - { - sslErrorCallback_(SSLError::kSSLInvalidCertificate); - } - forceClose(); - return; - } - } - sslEncryptionPtr_->statusOfSSL_ = SSLStatus::Connected; - if (sslEncryptionPtr_->isUpgrade_) - { - sslEncryptionPtr_->upgradeCallback_(); - } - else - { - connectionCallback_(shared_from_this()); - } - return; - } - int err = SSL_get_error(sslEncryptionPtr_->sslPtr_->get(), r); - LOG_TRACE << "hand shaking: " << err; - if (err == SSL_ERROR_WANT_WRITE) - { // SSL want writable; - if (!ioChannelPtr_->isWriting()) - ioChannelPtr_->enableWriting(); - // ioChannelPtr_->disableReading(); - } - else if (err == SSL_ERROR_WANT_READ) - { // SSL want readable; - if (!ioChannelPtr_->isReading()) - ioChannelPtr_->enableReading(); - if (ioChannelPtr_->isWriting()) - ioChannelPtr_->disableWriting(); - } - else - { - // ERR_print_errors(err); - LOG_TRACE << "SSL handshake err: " << err; - ioChannelPtr_->disableReading(); - sslEncryptionPtr_->statusOfSSL_ = SSLStatus::DisConnected; - if (sslErrorCallback_) - { - sslErrorCallback_(SSLError::kSSLHandshakeError); - } - forceClose(); - } -} - -#endif diff --git a/modules/trantor/trantor/net/inner/TcpConnectionImpl.h b/modules/trantor/trantor/net/inner/TcpConnectionImpl.h deleted file mode 100644 index cad3dfa..0000000 --- a/modules/trantor/trantor/net/inner/TcpConnectionImpl.h +++ /dev/null @@ -1,344 +0,0 @@ -/** - * - * @file TcpConnectionImpl.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif -#include -#include - -namespace trantor -{ -#ifdef USE_OPENSSL -enum class SSLStatus -{ - Handshaking, - Connecting, - Connected, - DisConnecting, - DisConnected -}; -class SSLContext; -class SSLConn; - -std::shared_ptr newSSLContext( - bool useOldTLS, - bool validateCert, - const std::vector> &sslConfCmds); -std::shared_ptr newSSLServerContext( - const std::string &certPath, - const std::string &keyPath, - bool useOldTLS, - const std::vector> &sslConfCmds); -// void initServerSSLContext(const std::shared_ptr &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 NonCopyable, - public std::enable_shared_from_this -{ - friend class TcpServer; - friend class TcpClient; - friend void trantor::removeConnection(EventLoop *loop, - const TcpConnectionPtr &conn); - - public: - class KickoffEntry - { - public: - explicit KickoffEntry(const std::weak_ptr &conn) - : conn_(conn) - { - } - void reset() - { - conn_.reset(); - } - ~KickoffEntry() - { - auto conn = conn_.lock(); - if (conn) - { - conn->forceClose(); - } - } - - private: - std::weak_ptr 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 &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 &msgPtr) override; - virtual void send(const std::shared_ptr &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 callback, - bool useOldTLS = false, - bool validateCert = true, - std::string hostname = "", - const std::vector> &sslConfCmds = - {}) override; - virtual void startServerEncryption(const std::shared_ptr &ctx, - std::function callback) override; - virtual bool isSSLConnection() const override - { - return isEncrypted_; - } - - private: - /// Internal use only. - - std::weak_ptr kickoffEntry_; - std::weak_ptr timingWheelWeakPtr_; - size_t idleTimeout_{0}; - Date lastTimingWheelUpdateTime_; - - void enableKickingOff(size_t timeout, - const std::shared_ptr &timingWheel) - { - assert(timingWheel); - assert(timingWheel->getLoop() == loop_); - assert(timeout > 0); - auto entry = std::make_shared(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_; - ~BufferNode() - { -#ifndef _WIN32 - if (sendFd_ >= 0) - close(sendFd_); -#else - if (sendFp_) - fclose(sendFp_); -#endif - } - }; - using BufferNodePtr = std::shared_ptr; - enum class ConnStatus - { - Disconnected, - Connecting, - Connected, - Disconnecting - }; - bool isEncrypted_{false}; - EventLoop *loop_; - std::unique_ptr ioChannelPtr_; - std::unique_ptr socketPtr_; - MsgBuffer readBuffer_; - std::list 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> fileBufferPtr_; - -#ifdef USE_OPENSSL - private: - void doHandshaking(); - bool validatePeerCertificate(); - struct SSLEncryption - { - SSLStatus statusOfSSL_ = SSLStatus::Handshaking; - // OpenSSL - std::shared_ptr sslCtxPtr_; - std::unique_ptr sslPtr_; - std::unique_ptr> sendBufferPtr_; - bool isServer_{false}; - bool isUpgrade_{false}; - std::function upgradeCallback_; - std::string hostname_; - }; - std::unique_ptr sslEncryptionPtr_; - void startClientEncryptionInLoop( - std::function &&callback, - bool useOldTLS, - bool validateCert, - const std::string &hostname, - const std::vector> &sslConfCmds); - void startServerEncryptionInLoop(const std::shared_ptr &ctx, - std::function &&callback); -#endif -}; - -using TcpConnectionImplPtr = std::shared_ptr; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/Timer.cc b/modules/trantor/trantor/net/inner/Timer.cc deleted file mode 100644 index 4d10eeb..0000000 --- a/modules/trantor/trantor/net/inner/Timer.cc +++ /dev/null @@ -1,64 +0,0 @@ -/** - * - * Timer.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "Timer.h" -#include -#include - -namespace trantor -{ -std::atomic 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_; -} -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/Timer.h b/modules/trantor/trantor/net/inner/Timer.h deleted file mode 100644 index 17c6d33..0000000 --- a/modules/trantor/trantor/net/inner/Timer.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * - * Timer.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -using TimerId = uint64_t; -using TimePoint = std::chrono::steady_clock::time_point; -using TimeInterval = std::chrono::microseconds; -class Timer : public NonCopyable -{ - 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!"<(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 timersCreated_; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/TimerQueue.cc b/modules/trantor/trantor/net/inner/TimerQueue.cc deleted file mode 100644 index 91293a2..0000000 --- a/modules/trantor/trantor/net/inner/TimerQueue.cc +++ /dev/null @@ -1,294 +0,0 @@ -/** - * - * @file TimerQueue.cc - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include - -#include "TimerQueue.h" -#include "Channel.h" -#ifdef __linux__ -#include -#endif -#include -#include -#ifndef _WIN32 -#include -#endif - -using namespace trantor; -#ifdef __linux__ -static int createTimerfd() -{ - int timerfd = ::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - if (timerfd < 0) - { - std::cerr << "create timerfd failed!" << std::endl; - } - return timerfd; -} - -static struct timespec howMuchTimeFromNow(const TimePoint &when) -{ - auto microSeconds = std::chrono::duration_cast( - when - std::chrono::steady_clock::now()) - .count(); - if (microSeconds < 100) - { - microSeconds = 100; - } - struct timespec ts; - ts.tv_sec = static_cast(microSeconds / 1000000); - ts.tv_nsec = static_cast((microSeconds % 1000000) * 1000); - return ts; -} -static void resetTimerfd(int timerfd, const TimePoint &expiration) -{ - // wake up loop by timerfd_settime() - struct itimerspec newValue; - struct itimerspec oldValue; - memset(&newValue, 0, sizeof(newValue)); - memset(&oldValue, 0, sizeof(oldValue)); - newValue.it_value = howMuchTimeFromNow(expiration); - int ret = ::timerfd_settime(timerfd, 0, &newValue, &oldValue); - if (ret) - { - // LOG_SYSERR << "timerfd_settime()"; - } -} -static void readTimerfd(int timerfd, const TimePoint &) -{ - uint64_t howmany; - ssize_t n = ::read(timerfd, &howmany, sizeof howmany); - if (n != sizeof howmany) - { - LOG_ERROR << "TimerQueue::handleRead() reads " << n - << " bytes instead of 8"; - } -} - -void TimerQueue::handleRead() -{ - loop_->assertInLoopThread(); - const auto now = std::chrono::steady_clock::now(); - readTimerfd(timerfd_, now); - - std::vector expired = getExpired(now); - - callingExpiredTimers_ = true; - // cancelingTimers_.clear(); - // safe to callback outside critical section - for (auto const &timerPtr : expired) - { - if (timerIdSet_.find(timerPtr->id()) != timerIdSet_.end()) - { - timerPtr->run(); - } - } - callingExpiredTimers_ = false; - - reset(expired, now); -} -#else -static int64_t howMuchTimeFromNow(const TimePoint &when) -{ - auto microSeconds = std::chrono::duration_cast( - when - std::chrono::steady_clock::now()) - .count(); - if (microSeconds < 1000) - { - microSeconds = 1000; - } - return microSeconds / 1000; -} -void TimerQueue::processTimers() -{ - loop_->assertInLoopThread(); - const auto now = std::chrono::steady_clock::now(); - - std::vector expired = getExpired(now); - - callingExpiredTimers_ = true; - // cancelingTimers_.clear(); - // safe to callback outside critical section - for (auto const &timerPtr : expired) - { - if (timerIdSet_.find(timerPtr->id()) != timerIdSet_.end()) - { - timerPtr->run(); - } - } - callingExpiredTimers_ = false; - - reset(expired, now); -} -#endif -/////////////////////////////////////// -TimerQueue::TimerQueue(EventLoop *loop) - : loop_(loop), -#ifdef __linux__ - timerfd_(createTimerfd()), - timerfdChannelPtr_(new Channel(loop, timerfd_)), -#endif - timers_(), - callingExpiredTimers_(false) -{ -#ifdef __linux__ - timerfdChannelPtr_->setReadCallback( - std::bind(&TimerQueue::handleRead, this)); - // we are always reading the timerfd, we disarm it with timerfd_settime. - timerfdChannelPtr_->enableReading(); -#endif -} -#ifdef __linux__ -void TimerQueue::reset() -{ - loop_->runInLoop([this]() { - timerfdChannelPtr_->disableAll(); - timerfdChannelPtr_->remove(); - close(timerfd_); - timerfd_ = createTimerfd(); - timerfdChannelPtr_ = std::make_shared(loop_, timerfd_); - timerfdChannelPtr_->setReadCallback( - std::bind(&TimerQueue::handleRead, this)); - // we are always reading the timerfd, we disarm it with timerfd_settime. - timerfdChannelPtr_->enableReading(); - if (!timers_.empty()) - { - const auto nextExpire = timers_.top()->when(); - resetTimerfd(timerfd_, nextExpire); - } - }); -} -#endif -TimerQueue::~TimerQueue() -{ -#ifdef __linux__ - auto chlPtr = timerfdChannelPtr_; - auto fd = timerfd_; - loop_->runInLoop([chlPtr, fd]() { - chlPtr->disableAll(); - chlPtr->remove(); - ::close(fd); - }); -#endif -} - -TimerId TimerQueue::addTimer(const TimerCallback &cb, - const TimePoint &when, - const TimeInterval &interval) -{ - std::shared_ptr timerPtr = - std::make_shared(cb, when, interval); - - loop_->runInLoop([this, timerPtr]() { addTimerInLoop(timerPtr); }); - return timerPtr->id(); -} -TimerId TimerQueue::addTimer(TimerCallback &&cb, - const TimePoint &when, - const TimeInterval &interval) -{ - std::shared_ptr timerPtr = - std::make_shared(std::move(cb), when, interval); - - loop_->runInLoop([this, timerPtr]() { addTimerInLoop(timerPtr); }); - return timerPtr->id(); -} -void TimerQueue::addTimerInLoop(const TimerPtr &timer) -{ - loop_->assertInLoopThread(); - timerIdSet_.insert(timer->id()); - if (insert(timer)) - { -// the earliest timer changed -#ifdef __linux__ - resetTimerfd(timerfd_, timer->when()); -#endif - } -} - -void TimerQueue::invalidateTimer(TimerId id) -{ - loop_->runInLoop([this, id]() { timerIdSet_.erase(id); }); -} - -bool TimerQueue::insert(const TimerPtr &timerPtr) -{ - loop_->assertInLoopThread(); - bool earliestChanged = false; - if (timers_.size() == 0 || *timerPtr < *timers_.top()) - { - earliestChanged = true; - } - timers_.push(timerPtr); - // std::cout<<"after push new - // timer:"<when().microSecondsSinceEpoch()/1000000<assertInLoopThread(); - if (timers_.empty()) - { - return 10000; - } - else - { - return howMuchTimeFromNow(timers_.top()->when()); - } -} -#endif - -std::vector TimerQueue::getExpired(const TimePoint &now) -{ - std::vector expired; - while (!timers_.empty()) - { - if (timers_.top()->when() < now) - { - expired.push_back(timers_.top()); - timers_.pop(); - } - else - break; - } - return expired; -} -void TimerQueue::reset(const std::vector &expired, - const TimePoint &now) -{ - loop_->assertInLoopThread(); - for (auto const &timerPtr : expired) - { - auto iter = timerIdSet_.find(timerPtr->id()); - if (iter != timerIdSet_.end()) - { - if (timerPtr->isRepeat()) - { - timerPtr->restart(now); - insert(timerPtr); - } - else - { - timerIdSet_.erase(iter); - } - } - } -#ifdef __linux__ - if (!timers_.empty()) - { - const auto nextExpire = timers_.top()->when(); - resetTimerfd(timerfd_, nextExpire); - } -#endif -} diff --git a/modules/trantor/trantor/net/inner/TimerQueue.h b/modules/trantor/trantor/net/inner/TimerQueue.h deleted file mode 100644 index 6903fb4..0000000 --- a/modules/trantor/trantor/net/inner/TimerQueue.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * - * TimerQueue.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include "Timer.h" -#include -#include -#include -#include -namespace trantor -{ -// class Timer; -class EventLoop; -class Channel; -using TimerPtr = std::shared_ptr; -struct TimerPtrComparer -{ - bool operator()(const TimerPtr &x, const TimerPtr &y) const - { - return *x > *y; - } -}; - -class TimerQueue : NonCopyable -{ - 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 timerfdChannelPtr_; - void handleRead(); -#endif - std::priority_queue, TimerPtrComparer> - timers_; - - bool callingExpiredTimers_; - bool insert(const TimerPtr &timePtr); - std::vector getExpired(); - void reset(const std::vector &expired, const TimePoint &now); - std::vector getExpired(const TimePoint &now); - - private: - std::unordered_set timerIdSet_; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/poller/EpollPoller.cc b/modules/trantor/trantor/net/inner/poller/EpollPoller.cc deleted file mode 100644 index ac26875..0000000 --- a/modules/trantor/trantor/net/inner/poller/EpollPoller.cc +++ /dev/null @@ -1,241 +0,0 @@ -/** - * - * EpollPoller.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include "Channel.h" -#include "EpollPoller.h" -#ifdef __linux__ -#include -#include -#include -#include -#include -#include -#elif defined _WIN32 -#include "Wepoll.h" -#include -#include -#include -#include -#define EPOLL_CLOEXEC _O_NOINHERIT -#endif -namespace trantor -{ -#if defined __linux__ || defined _WIN32 - -#if defined __linux__ -static_assert(EPOLLIN == POLLIN, "EPOLLIN != POLLIN"); -static_assert(EPOLLPRI == POLLPRI, "EPOLLPRI != POLLPRI"); -static_assert(EPOLLOUT == POLLOUT, "EPOLLOUT != POLLOUT"); -static_assert(EPOLLRDHUP == POLLRDHUP, "EPOLLRDHUP != POLLRDHUP"); -static_assert(EPOLLERR == POLLERR, "EPOLLERR != POLLERR"); -static_assert(EPOLLHUP == POLLHUP, "EPOLLHUP != POLLHUP"); -#endif - -namespace -{ -const int kNew = -1; -const int kAdded = 1; -const int kDeleted = 2; -} // namespace - -EpollPoller::EpollPoller(EventLoop *loop) - : Poller(loop), -#ifdef _WIN32 - // wepoll does not suppor flags - epollfd_(::epoll_create1(0)), -#else - epollfd_(::epoll_create1(EPOLL_CLOEXEC)), -#endif - events_(kInitEventListSize) -{ -} -EpollPoller::~EpollPoller() -{ -#ifdef _WIN32 - epoll_close(epollfd_); -#else - close(epollfd_); -#endif -} -#ifdef _WIN32 -void EpollPoller::postEvent(uint64_t event) -{ - epoll_post_signal(epollfd_, event); -} -#endif -void EpollPoller::poll(int timeoutMs, ChannelList *activeChannels) -{ - int numEvents = ::epoll_wait(epollfd_, - &*events_.begin(), - static_cast(events_.size()), - timeoutMs); - int savedErrno = errno; - // Timestamp now(Timestamp::now()); - if (numEvents > 0) - { - // LOG_TRACE << numEvents << " events happended"; - fillActiveChannels(numEvents, activeChannels); - if (static_cast(numEvents) == events_.size()) - { - events_.resize(events_.size() * 2); - } - } - else if (numEvents == 0) - { - // std::cout << "nothing happended" << std::endl; - } - else - { - // error happens, log uncommon ones - if (savedErrno != EINTR) - { - errno = savedErrno; - LOG_SYSERR << "EPollEpollPoller::poll()"; - } - } - return; -} -void EpollPoller::fillActiveChannels(int numEvents, - ChannelList *activeChannels) const -{ - assert(static_cast(numEvents) <= events_.size()); - for (int i = 0; i < numEvents; ++i) - { -#ifdef _WIN32 - if (events_[i].events == EPOLLEVENT) - { - eventCallback_(events_[i].data.u64); - continue; - } -#endif - Channel *channel = static_cast(events_[i].data.ptr); -#ifndef NDEBUG - int fd = channel->fd(); - ChannelMap::const_iterator it = channels_.find(fd); - assert(it != channels_.end()); - assert(it->second == channel); -#endif - channel->setRevents(events_[i].events); - activeChannels->push_back(channel); - } - // LOG_TRACE<<"active Channels num:"<size(); -} -void EpollPoller::updateChannel(Channel *channel) -{ - assertInLoopThread(); - const int index = channel->index(); - // LOG_TRACE << "fd = " << channel->fd() - // << " events = " << channel->events() << " index = " << index; - if (index == kNew || index == kDeleted) - { -// a new one, add with EPOLL_CTL_ADD -#ifndef NDEBUG - int fd = channel->fd(); - if (index == kNew) - { - assert(channels_.find(fd) == channels_.end()); - channels_[fd] = channel; - } - else - { // index == kDeleted - assert(channels_.find(fd) != channels_.end()); - assert(channels_[fd] == channel); - } -#endif - channel->setIndex(kAdded); - update(EPOLL_CTL_ADD, channel); - } - else - { -// update existing one with EPOLL_CTL_MOD/DEL -#ifndef NDEBUG - int fd = channel->fd(); - (void)fd; - assert(channels_.find(fd) != channels_.end()); - assert(channels_[fd] == channel); -#endif - assert(index == kAdded); - if (channel->isNoneEvent()) - { - update(EPOLL_CTL_DEL, channel); - channel->setIndex(kDeleted); - } - else - { - update(EPOLL_CTL_MOD, channel); - } - } -} -void EpollPoller::removeChannel(Channel *channel) -{ - EpollPoller::assertInLoopThread(); -#ifndef NDEBUG - int fd = channel->fd(); - assert(channels_.find(fd) != channels_.end()); - assert(channels_[fd] == channel); - size_t n = channels_.erase(fd); - (void)n; - assert(n == 1); -#endif - assert(channel->isNoneEvent()); - int index = channel->index(); - assert(index == kAdded || index == kDeleted); - if (index == kAdded) - { - update(EPOLL_CTL_DEL, channel); - } - channel->setIndex(kNew); -} -void EpollPoller::update(int operation, Channel *channel) -{ - struct epoll_event event; - memset(&event, 0, sizeof(event)); - event.events = channel->events(); - event.data.ptr = channel; - int fd = channel->fd(); - if (::epoll_ctl(epollfd_, operation, fd, &event) < 0) - { - if (operation == EPOLL_CTL_DEL) - { - // LOG_SYSERR << "epoll_ctl op =" << operationToString(operation) << - // " fd =" << fd; - } - else - { - // LOG_SYSFATAL << "epoll_ctl op =" << operationToString(operation) - // << " fd =" << fd; - } - } -} -#else -EpollPoller::EpollPoller(EventLoop *loop) : Poller(loop) -{ - assert(false); -} -EpollPoller::~EpollPoller() -{ -} -void EpollPoller::poll(int, ChannelList *) -{ -} -void EpollPoller::updateChannel(Channel *) -{ -} -void EpollPoller::removeChannel(Channel *) -{ -} - -#endif -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/poller/EpollPoller.h b/modules/trantor/trantor/net/inner/poller/EpollPoller.h deleted file mode 100644 index be04a4a..0000000 --- a/modules/trantor/trantor/net/inner/poller/EpollPoller.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * - * EpollPoller.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include "../Poller.h" -#include -#include - -#if defined __linux__ || defined _WIN32 -#include -#include -using EventList = std::vector; -#endif -namespace trantor -{ -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; - ChannelMap channels_; -#endif - void fillActiveChannels(int numEvents, ChannelList *activeChannels) const; -#endif -}; -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/poller/KQueue.cc b/modules/trantor/trantor/net/inner/poller/KQueue.cc deleted file mode 100644 index ee917d2..0000000 --- a/modules/trantor/trantor/net/inner/poller/KQueue.cc +++ /dev/null @@ -1,249 +0,0 @@ -#include "KQueue.h" -#include "Channel.h" -#ifdef USE_KQUEUE -#include -#include -#include -#include -#include -#include -#endif -namespace trantor -{ -#ifdef USE_KQUEUE -namespace -{ -const int kNew = -1; -const int kAdded = 1; -const int kDeleted = 2; -} // namespace - -KQueue::KQueue(EventLoop *loop) - : Poller(loop), kqfd_(kqueue()), events_(kInitEventListSize) -{ - assert(kqfd_ >= 0); -} - -KQueue::~KQueue() -{ - close(kqfd_); -} - -void KQueue::resetAfterFork() -{ - close(kqfd_); - kqfd_ = kqueue(); - for (auto &ch : channels_) - { - ch.second.first = 0; - if (ch.second.second->isReading() || ch.second.second->isWriting()) - { - update(ch.second.second); - } - } -} - -void KQueue::poll(int timeoutMs, ChannelList *activeChannels) -{ - struct timespec timeout; - timeout.tv_sec = timeoutMs / 1000; - timeout.tv_nsec = (timeoutMs % 1000) * 1000000; - - int numEvents = kevent(kqfd_, - NULL, - 0, - events_.data(), - static_cast(events_.size()), - &timeout); - int savedErrno = errno; - // Timestamp now(Timestamp::now()); - if (numEvents > 0) - { - // LOG_TRACE << numEvents << " events happended"; - fillActiveChannels(numEvents, activeChannels); - if (static_cast(numEvents) == events_.size()) - { - events_.resize(events_.size() * 2); - } - } - else if (numEvents == 0) - { - // std::cout << "nothing happended" << std::endl; - } - else - { - // error happens, log uncommon ones - if (savedErrno != EINTR) - { - errno = savedErrno; - LOG_SYSERR << "KQueue::poll()"; - } - } - return; -} - -void KQueue::fillActiveChannels(int numEvents, - ChannelList *activeChannels) const -{ - assert(static_cast(numEvents) <= events_.size()); - for (int i = 0; i < numEvents; ++i) - { - Channel *channel = static_cast(events_[i].udata); - assert(channels_.find(channel->fd()) != channels_.end()); - int events = events_[i].filter; - if (events == EVFILT_READ) - { - channel->setRevents(POLLIN); - } - else if (events == EVFILT_WRITE) - { - channel->setRevents(POLLOUT); - } - else - { - LOG_ERROR << "events=" << events; - continue; - } - activeChannels->push_back(channel); - } -} - -void KQueue::updateChannel(Channel *channel) -{ - assertInLoopThread(); - const int index = channel->index(); - // LOG_TRACE << "fd = " << channel->fd() - // << " events = " << channel->events() << " index = " << index; - if (index == kNew || index == kDeleted) - { - if (index == kNew) - { - assert(channels_.find(channel->fd()) == channels_.end()); - } - else - { // index == kDeleted - assert(channels_.find(channel->fd()) != channels_.end()); - assert(channels_[channel->fd()].second == channel); - } - update(channel); - channel->setIndex(kAdded); - } - else - { - // update existing one - int fd = channel->fd(); - (void)fd; - assert(channels_.find(fd) != channels_.end()); - assert(index == kAdded); - if (channel->isNoneEvent()) - { - update(channel); - channel->setIndex(kDeleted); - } - else - { - update(channel); - } - } -} -void KQueue::removeChannel(Channel *channel) -{ - assertInLoopThread(); - int fd = channel->fd(); - assert(channels_.find(fd) != channels_.end()); - assert(channel->isNoneEvent()); - int index = channel->index(); - assert(index == kAdded || index == kDeleted); - - if (index == kAdded) - { - update(channel); - } - - size_t n = channels_.erase(fd); - (void)n; - assert(n == 1); - channel->setIndex(kNew); -} - -void KQueue::update(Channel *channel) -{ - struct kevent ev[2]; - int n = 0; - auto events = channel->events(); - int oldEvents = 0; - if (channels_.find(channel->fd()) != channels_.end()) - { - oldEvents = channels_[channel->fd()].first; - } - - auto fd = channel->fd(); - channels_[fd] = {events, channel}; - - if ((events & Channel::kReadEvent) && (!(oldEvents & Channel::kReadEvent))) - { - EV_SET(&ev[n++], - fd, - EVFILT_READ, - EV_ADD | EV_ENABLE, - 0, - 0, - (void *)(intptr_t)channel); - } - else if ((!(events & Channel::kReadEvent)) && - (oldEvents & Channel::kReadEvent)) - { - EV_SET(&ev[n++], - fd, - EVFILT_READ, - EV_DELETE, - 0, - 0, - (void *)(intptr_t)channel); - } - if ((events & Channel::kWriteEvent) && - (!(oldEvents & Channel::kWriteEvent))) - { - EV_SET(&ev[n++], - fd, - EVFILT_WRITE, - EV_ADD | EV_ENABLE, - 0, - 0, - (void *)(intptr_t)channel); - } - else if ((!(events & Channel::kWriteEvent)) && - (oldEvents & Channel::kWriteEvent)) - { - EV_SET(&ev[n++], - fd, - EVFILT_WRITE, - EV_DELETE, - 0, - 0, - (void *)(intptr_t)channel); - } - kevent(kqfd_, ev, n, NULL, 0, NULL); -} -#else -KQueue::KQueue(EventLoop *loop) : Poller(loop) -{ - assert(false); -} -KQueue::~KQueue() -{ -} -void KQueue::poll(int, ChannelList *) -{ -} -void KQueue::updateChannel(Channel *) -{ -} -void KQueue::removeChannel(Channel *) -{ -} -void KQueue::resetAfterFork() -{ -} -#endif -} // namespace trantor diff --git a/modules/trantor/trantor/net/inner/poller/KQueue.h b/modules/trantor/trantor/net/inner/poller/KQueue.h deleted file mode 100644 index 290082d..0000000 --- a/modules/trantor/trantor/net/inner/poller/KQueue.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * - * KQueue.h - * An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/trantor - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * Trantor - * - */ - -#pragma once -#include "../Poller.h" -#include -#include - -#if (defined(__unix__) && !defined(__linux__)) || \ - (defined(__APPLE__) && defined(__MACH__)) -#define USE_KQUEUE -#include -#include -#include -using EventList = std::vector; -#endif -namespace trantor -{ -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>; - ChannelMap channels_; - - void fillActiveChannels(int numEvents, ChannelList *activeChannels) const; - void update(Channel *channel); -#endif -}; - -} // namespace trantor \ No newline at end of file diff --git a/modules/trantor/trantor/tests/AsyncFileLoggerTest.cc b/modules/trantor/trantor/tests/AsyncFileLoggerTest.cc deleted file mode 100644 index 66c7219..0000000 --- a/modules/trantor/trantor/tests/AsyncFileLoggerTest.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include -int main() -{ - trantor::AsyncFileLogger asyncFileLogger; - asyncFileLogger.setFileName("async_test"); - asyncFileLogger.startLogging(); - trantor::Logger::setOutputFunction( - [&](const char *msg, const uint64_t len) { - asyncFileLogger.output(msg, len); - }, - [&]() { asyncFileLogger.flush(); }); - asyncFileLogger.setFileSizeLimit(100000000); - // LOG_DEBUG<<"debug log!"<<1; - // LOG_TRACE<<"trace log!"<<2; - // LOG_INFO<<"info log!"<<3; - // LOG_WARN<<"warning log!"<<4; - // if(1) - // LOG_ERROR<<"error log!"<<5; - // std::thread thread_([](){ - // LOG_FATAL<<"fatal log!"<<6; - // }); - // - // FILE *fp=fopen("/notexistfile","rb"); - // if(fp==NULL) - // { - // LOG_SYSERR<<"syserr log!"<<7; - // } - - int i = 0; - while (i < 1000000) - { - ++i; - if (i % 100 == 0) - { - LOG_ERROR << "this is the " << i << "th log"; - continue; - } - LOG_INFO << "this is the " << i << "th log"; - ++i; - LOG_DEBUG << "this is the " << i << "th log"; - } -} diff --git a/modules/trantor/trantor/tests/AsyncFileLoggerTest1.cc b/modules/trantor/trantor/tests/AsyncFileLoggerTest1.cc deleted file mode 100644 index 63c6916..0000000 --- a/modules/trantor/trantor/tests/AsyncFileLoggerTest1.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include -#include - -using namespace std::chrono_literals; -int main() -{ - trantor::AsyncFileLogger asyncFileLogger; - asyncFileLogger.setFileName("async_test"); - asyncFileLogger.startLogging(); - trantor::Logger::setOutputFunction( - [&](const char *msg, const uint64_t len) { - asyncFileLogger.output(msg, len); - }, - [&]() { asyncFileLogger.flush(); }); - asyncFileLogger.setFileSizeLimit(100000000); - int i = 0; - while (i < 1000000) - { - ++i; - if (i % 100 == 0) - { - LOG_ERROR << "this is the " << i << "th log"; - continue; - } - LOG_INFO << "this is the " << i << "th log"; - ++i; - LOG_DEBUG << "this is the " << i << "th log"; - std::this_thread::sleep_for(1s); - } -} diff --git a/modules/trantor/trantor/tests/CMakeLists.txt b/modules/trantor/trantor/tests/CMakeLists.txt deleted file mode 100644 index 180f556..0000000 --- a/modules/trantor/trantor/tests/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -add_executable(ssl_server_test SSLServerTest.cc) -add_executable(ssl_client_test SSLClientTest.cc) -add_executable(serial_task_queue_test1 SerialTaskQueueTest1.cc) -add_executable(serial_task_queue_test2 SerialTaskQueueTest2.cc) -add_executable(timer_test TimerTest.cc) -add_executable(timer_test1 TimerTest1.cc) -add_executable(run_in_loop_test1 RunInLoopTest1.cc) -add_executable(run_in_loop_test2 RunInLoopTest2.cc) -add_executable(logger_test LoggerTest.cc) -add_executable(async_file_logger_test AsyncFileLoggerTest.cc) -add_executable(tcp_server_test TcpServerTest.cc) -add_executable(concurrent_task_queue_test ConcurrentTaskQueueTest.cc) -add_executable(tcp_client_test TcpClientTest.cc) -add_executable(async_file_logger_test1 AsyncFileLoggerTest1.cc) -add_executable(sendfile_test SendfileTest.cc) -add_executable(timing_wheel_test TimingWheelTest.cc) -add_executable(kickoff_test KickoffTest.cc) -add_executable(dns_test DnsTest.cc) -add_executable(delayed_ssl_server_test DelayedSSLServerTest.cc) -add_executable(delayed_ssl_client_test DelayedSSLClientTest.cc) -add_executable(run_on_quit_test RunOnQuitTest.cc) -set(targets_list - ssl_server_test - ssl_client_test - serial_task_queue_test1 - serial_task_queue_test2 - timer_test - timer_test1 - run_in_loop_test1 - run_in_loop_test2 - logger_test - async_file_logger_test - tcp_server_test - concurrent_task_queue_test - tcp_client_test - async_file_logger_test1 - sendfile_test - timing_wheel_test - kickoff_test - dns_test - delayed_ssl_server_test - delayed_ssl_client_test - run_on_quit_test) - -set_property(TARGET ${targets_list} PROPERTY CXX_STANDARD 14) -set_property(TARGET ${targets_list} PROPERTY CXX_STANDARD_REQUIRED ON) -set_property(TARGET ${targets_list} PROPERTY CXX_EXTENSIONS OFF) - -foreach(T ${targets_list}) - target_link_libraries(${T} PRIVATE trantor) -endforeach() diff --git a/modules/trantor/trantor/tests/ConcurrentTaskQueueTest.cc b/modules/trantor/trantor/tests/ConcurrentTaskQueueTest.cc deleted file mode 100644 index cd62795..0000000 --- a/modules/trantor/trantor/tests/ConcurrentTaskQueueTest.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std::chrono_literals; - -int main() -{ - trantor::ConcurrentTaskQueue queue(5, "concurrT"); - std::atomic_int sum; - sum = 0; - for (int i = 0; i < 4; ++i) - { - queue.runTaskInQueue([&sum]() { - LOG_DEBUG << "add sum"; - for (int i = 0; i < 10000; ++i) - { - ++sum; - } - }); - } - - queue.runTaskInQueue([&sum]() { - for (int i = 0; i < 20; ++i) - { - LOG_DEBUG << "sum=" << sum; - std::this_thread::sleep_for(100us); - } - }); - - getc(stdin); - LOG_DEBUG << "sum=" << sum; -} diff --git a/modules/trantor/trantor/tests/DelayedSSLClientTest.cc b/modules/trantor/trantor/tests/DelayedSSLClientTest.cc deleted file mode 100644 index 72c5530..0000000 --- a/modules/trantor/trantor/tests/DelayedSSLClientTest.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - trantor::Logger::setLogLevel(trantor::Logger::kTrace); - LOG_DEBUG << "TcpClient class test!"; - EventLoop loop; -#if USE_IPV6 - InetAddress serverAddr("::1", 8888, true); -#else - InetAddress serverAddr("127.0.0.1", 8888); -#endif - std::shared_ptr client[10]; - std::atomic_int connCount; - connCount = 10; - for (int i = 0; i < 10; ++i) - { - client[i] = std::make_shared(&loop, - serverAddr, - "tcpclienttest"); - client[i]->setConnectionCallback( - [i, &loop, &connCount](const TcpConnectionPtr &conn) { - if (conn->connected()) - { - } - else - { - LOG_DEBUG << i << " disconnected"; - --connCount; - if (connCount == 0) - loop.quit(); - } - }); - client[i]->setMessageCallback( - [](const TcpConnectionPtr &conn, MsgBuffer *buf) { - auto msg = std::string(buf->peek(), buf->readableBytes()); - - LOG_INFO << msg; - if (msg == "hello") - { - buf->retrieveAll(); - conn->startClientEncryption( - [conn]() { - LOG_INFO << "SSL established"; - conn->send("Hello"); - }, - false, - false); - } - if (conn->isSSLConnection()) - { - buf->retrieveAll(); - } - }); - client[i]->connect(); - } - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/DelayedSSLServerTest.cc b/modules/trantor/trantor/tests/DelayedSSLServerTest.cc deleted file mode 100644 index 466b7ad..0000000 --- a/modules/trantor/trantor/tests/DelayedSSLServerTest.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - LOG_DEBUG << "test start"; - Logger::setLogLevel(Logger::kTrace); - EventLoopThread loopThread; - loopThread.run(); -#if USE_IPV6 - InetAddress addr(8888, true, true); -#else - InetAddress addr(8888); -#endif - TcpServer server(loopThread.getLoop(), addr, "test"); - auto ctx = newSSLServerContext("server.pem", "server.pem", {}); - LOG_INFO << "start"; - server.setRecvMessageCallback( - [](const TcpConnectionPtr &connectionPtr, MsgBuffer *buffer) { - LOG_DEBUG << std::string{buffer->peek(), buffer->readableBytes()}; - connectionPtr->send(*buffer); - buffer->retrieveAll(); - connectionPtr->shutdown(); - }); - server.setConnectionCallback([ctx](const TcpConnectionPtr &connPtr) { - if (connPtr->connected()) - { - LOG_DEBUG << "New connection"; - connPtr->send("hello"); - connPtr->startServerEncryption(ctx, [] { - LOG_INFO << "SSL established"; - }); - } - else if (connPtr->disconnected()) - { - LOG_DEBUG << "connection disconnected"; - } - }); - server.setIoLoopNum(3); - server.start(); - loopThread.wait(); -} diff --git a/modules/trantor/trantor/tests/DnsTest.cc b/modules/trantor/trantor/tests/DnsTest.cc deleted file mode 100644 index 1a71f53..0000000 --- a/modules/trantor/trantor/tests/DnsTest.cc +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -void dns(const std::shared_ptr &resolver) -{ - auto now = trantor::Date::now(); - resolver->resolve("www.baidu.com", [now](const trantor::InetAddress &addr) { - auto interval = trantor::Date::now().microSecondsSinceEpoch() - - now.microSecondsSinceEpoch(); - std::cout << "baidu:" << addr.toIp() << " " << interval / 1000 << "ms" - << std::endl; - }); - resolver->resolve("www.google.com", - [now](const trantor::InetAddress &addr) { - auto interval = - trantor::Date::now().microSecondsSinceEpoch() - - now.microSecondsSinceEpoch(); - std::cout << "google:" << addr.toIp() << " " - << interval / 1000 << "ms" << std::endl; - }); - resolver->resolve("www.sina.com", [now](const trantor::InetAddress &addr) { - auto interval = trantor::Date::now().microSecondsSinceEpoch() - - now.microSecondsSinceEpoch(); - std::cout << "sina:" << addr.toIp() << " " << interval / 1000 << "ms" - << std::endl; - }); - resolver->resolve("www.xjfisfjaskfeiakdjfg.com", - [now](const trantor::InetAddress &addr) { - auto interval = - trantor::Date::now().microSecondsSinceEpoch() - - now.microSecondsSinceEpoch(); - std::cout << "bad address:" << addr.toIp() << " " - << interval / 1000 << "ms" << std::endl; - }); - resolver->resolve("localhost", [now](const trantor::InetAddress &addr) { - auto interval = trantor::Date::now().microSecondsSinceEpoch() - - now.microSecondsSinceEpoch(); - std::cout << "localhost:" << addr.toIp() << " " << interval / 1000 - << "ms" << std::endl; - }); -} -int main() -{ - trantor::EventLoop loop; - auto resolver = trantor::Resolver::newResolver(&loop); - dns(resolver); - loop.runAfter(1.0, [resolver]() { dns(resolver); }); - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/KickoffTest.cc b/modules/trantor/trantor/tests/KickoffTest.cc deleted file mode 100644 index 1103822..0000000 --- a/modules/trantor/trantor/tests/KickoffTest.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - LOG_DEBUG << "test start"; - Logger::setLogLevel(Logger::kTrace); - EventLoop loop; -#if USE_IPV6 - InetAddress addr(8888, true, true); -#else - InetAddress addr(8888); -#endif - TcpServer server(&loop, addr, "test"); - server.kickoffIdleConnections(10); - server.setRecvMessageCallback( - [](const TcpConnectionPtr &connectionPtr, MsgBuffer *buffer) { - // LOG_DEBUG<<"recv callback!"; - std::cout << std::string(buffer->peek(), buffer->readableBytes()); - connectionPtr->send(buffer->peek(), buffer->readableBytes()); - buffer->retrieveAll(); - }); - int n = 0; - server.setConnectionCallback([&n](const TcpConnectionPtr &connPtr) { - if (connPtr->connected()) - { - ++n; - if (n % 2 == 0) - { - connPtr->keepAlive(); - } - LOG_DEBUG << "New connection"; - } - else if (connPtr->disconnected()) - { - LOG_DEBUG << "connection disconnected"; - } - }); - server.setIoLoopNum(3); - server.start(); - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/LoggerTest.cc b/modules/trantor/trantor/tests/LoggerTest.cc deleted file mode 100644 index 408fcb7..0000000 --- a/modules/trantor/trantor/tests/LoggerTest.cc +++ /dev/null @@ -1,1139 +0,0 @@ -#include -#include -#include -int main() -{ - int i; - LOG_DEBUG << (float)3.14; - LOG_DEBUG << (const char)'8'; - LOG_DEBUG << &i; - LOG_DEBUG << (long double)3.1415; - LOG_DEBUG << trantor::Fmt("%.3g", 3.1415926); - LOG_DEBUG << "debug log!" << 1; - LOG_TRACE << "trace log!" << 2; - LOG_INFO << "info log!" << 3; - LOG_WARN << "warning log!" << 4; - if (1) - LOG_ERROR << "error log!" << 5; - std::thread thread_([]() { LOG_FATAL << "fatal log!" << 6; }); - - FILE *fp = fopen("/notexistfile", "rb"); - if (fp == NULL) - { - LOG_SYSERR << "syserr log!" << 7; - } - LOG_DEBUG << "long message test:"; - LOG_DEBUG - << "Applications\n" - "Developer\n" - "Library\n" - "Network\n" - "System\n" - "Users\n" - "Volumes\n" - "bin\n" - "cores\n" - "dev\n" - "etc\n" - "home\n" - "installer.failurerequests\n" - "net\n" - "opt\n" - "private\n" - "sbin\n" - "tmp\n" - "usr\n" - "var\n" - "vm\n" - "\n" - "/Applications:\n" - "Adobe\n" - "Adobe Creative Cloud\n" - "Adobe Photoshop CC\n" - "AirPlayer Pro.app\n" - "AliWangwang.app\n" - "Android Studio.app\n" - "App Store.app\n" - "Autodesk\n" - "Automator.app\n" - "Axure RP Pro 7.0.app\n" - "BaiduNetdisk_mac.app\n" - "CLion.app\n" - "Calculator.app\n" - "Calendar.app\n" - "Chess.app\n" - "CleanApp.app\n" - "Cocos\n" - "Contacts.app\n" - "DVD Player.app\n" - "Dashboard.app\n" - "Dictionary.app\n" - "Docs for Xcode.app\n" - "FaceTime.app\n" - "FinalShell\n" - "Firefox.app\n" - "Font Book.app\n" - "GitHub.app\n" - "Google Chrome.app\n" - "Image Capture.app\n" - "Lantern.app\n" - "Launchpad.app\n" - "License.rtf\n" - "MacPorts\n" - "Mail.app\n" - "Maps.app\n" - "Messages.app\n" - "Microsoft Excel.app\n" - "Microsoft Office 2011\n" - "Microsoft OneNote.app\n" - "Microsoft Outlook.app\n" - "Microsoft PowerPoint.app\n" - "Microsoft Word.app\n" - "Mindjet MindManager.app\n" - "Mission Control.app\n" - "Mockplus.app\n" - "MyEclipse 2015\n" - "Notes.app\n" - "Numbers.app\n" - "OmniGraffle.app\n" - "Pages.app\n" - "Photo Booth.app\n" - "Photos.app\n" - "Preview.app\n" - "QJVPN.app\n" - "QQ.app\n" - "QQMusic.app\n" - "QuickTime Player.app\n" - "RAR Extractor Lite.app\n" - "Reminders.app\n" - "Remote Desktop Connection.app\n" - "Renee Undeleter.app\n" - "Sabaki.app\n" - "Safari.app\n" - "ShadowsocksX.app\n" - "Siri.app\n" - "SogouCharacterViewer.app\n" - "SogouInputPad.app\n" - "Stickies.app\n" - "SupremePlayer Lite.app\n" - "System Preferences.app\n" - "TeX\n" - "Telegram.app\n" - "Telnet Lite.app\n" - "Termius.app\n" - "Tesumego - How to Make a Professional Go Player.app\n" - "TextEdit.app\n" - "Thunder.app\n" - "Time Machine.app\n" - "Tunnelblick.app\n" - "Utilities\n" - "VPN Shield.appdownload\n" - "WeChat.app\n" - "WinOnX2.app\n" - "Wireshark.app\n" - "Xcode.app\n" - "Yose.app\n" - "YoudaoNote.localized\n" - "finalshelldata\n" - "iBooks.app\n" - "iHex.app\n" - "iPhoto.app\n" - "iTools.app\n" - "iTunes.app\n" - "pgAdmin 4.app\n" - "vSSH Lite.app\n" - "wechatwebdevtools.app\n" - "\n" - "/Applications/Adobe:\n" - "Flash Player\n" - "\n" - "/Applications/Adobe/Flash Player:\n" - "AddIns\n" - "\n" - "/Applications/Adobe/Flash Player/AddIns:\n" - "airappinstaller\n" - "\n" - "/Applications/Adobe/Flash Player/AddIns/airappinstaller:\n" - "airappinstaller\n" - "digest.s\n" - "\n" - "/Applications/Adobe Creative Cloud:\n" - "Adobe Creative Cloud\n" - "Icon\n" - "Uninstall Adobe Creative Cloud\n" - "\n" - "/Applications/Adobe Photoshop CC:\n" - "Adobe Photoshop CC.app\n" - "Configuration\n" - "Icon\n" - "Legal\n" - "LegalNotices.pdf\n" - "Locales\n" - "Plug-ins\n" - "Presets\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app:\n" - "Contents\n" - "Linguistics\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents:\n" - "Application Data\n" - "Frameworks\n" - "Info.plist\n" - "MacOS\n" - "PkgInfo\n" - "Required\n" - "Resources\n" - "_CodeSignature\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data:\n" - "Custom File Info Panels\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info Panels:\n" - "4.0\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info Panels/4.0:\n" - "bin\n" - "custom\n" - "panels\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/bin:\n" - "FileInfoFoundation.swf\n" - "FileInfoUI.swf\n" - "framework.swf\n" - "loc\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/bin/loc:\n" - "FileInfo_ar_AE.dat\n" - "FileInfo_bg_BG.dat\n" - "FileInfo_cs_CZ.dat\n" - "FileInfo_da_DK.dat\n" - "FileInfo_de_DE.dat\n" - "FileInfo_el_GR.dat\n" - "FileInfo_en_US.dat\n" - "FileInfo_es_ES.dat\n" - "FileInfo_et_EE.dat\n" - "FileInfo_fi_FI.dat\n" - "FileInfo_fr_FR.dat\n" - "FileInfo_he_IL.dat\n" - "FileInfo_hr_HR.dat\n" - "FileInfo_hu_HU.dat\n" - "FileInfo_it_IT.dat\n" - "FileInfo_ja_JP.dat\n" - "FileInfo_ko_KR.dat\n" - "FileInfo_lt_LT.dat\n" - "FileInfo_lv_LV.dat\n" - "FileInfo_nb_NO.dat\n" - "FileInfo_nl_NL.dat\n" - "FileInfo_pl_PL.dat\n" - "FileInfo_pt_BR.dat\n" - "FileInfo_ro_RO.dat\n" - "FileInfo_ru_RU.dat\n" - "FileInfo_sk_SK.dat\n" - "FileInfo_sl_SI.dat\n" - "FileInfo_sv_SE.dat\n" - "FileInfo_tr_TR.dat\n" - "FileInfo_uk_UA.dat\n" - "FileInfo_zh_CN.dat\n" - "FileInfo_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/custom:\n" - "DICOM.xml\n" - "Mobile.xml\n" - "loc\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/custom/loc:\n" - "DICOM_ar_AE.dat\n" - "DICOM_bg_BG.dat\n" - "DICOM_cs_CZ.dat\n" - "DICOM_da_DK.dat\n" - "DICOM_de_DE.dat\n" - "DICOM_el_GR.dat\n" - "DICOM_en_US.dat\n" - "DICOM_es_ES.dat\n" - "DICOM_et_EE.dat\n" - "DICOM_fi_FI.dat\n" - "DICOM_fr_FR.dat\n" - "DICOM_he_IL.dat\n" - "DICOM_hr_HR.dat\n" - "DICOM_hu_HU.dat\n" - "DICOM_it_IT.dat\n" - "DICOM_ja_JP.dat\n" - "DICOM_ko_KR.dat\n" - "DICOM_lt_LT.dat\n" - "DICOM_lv_LV.dat\n" - "DICOM_nb_NO.dat\n" - "DICOM_nl_NL.dat\n" - "DICOM_pl_PL.dat\n" - "DICOM_pt_BR.dat\n" - "DICOM_ro_RO.dat\n" - "DICOM_ru_RU.dat\n" - "DICOM_sk_SK.dat\n" - "DICOM_sl_SI.dat\n" - "DICOM_sv_SE.dat\n" - "DICOM_tr_TR.dat\n" - "DICOM_uk_UA.dat\n" - "DICOM_zh_CN.dat\n" - "DICOM_zh_TW.dat\n" - "Mobile_ar_AE.dat\n" - "Mobile_bg_BG.dat\n" - "Mobile_cs_CZ.dat\n" - "Mobile_da_DK.dat\n" - "Mobile_de_DE.dat\n" - "Mobile_el_GR.dat\n" - "Mobile_en_US.dat\n" - "Mobile_es_ES.dat\n" - "Mobile_et_EE.dat\n" - "Mobile_fi_FI.dat\n" - "Mobile_fr_FR.dat\n" - "Mobile_he_IL.dat\n" - "Mobile_hr_HR.dat\n" - "Mobile_hu_HU.dat\n" - "Mobile_it_IT.dat\n" - "Mobile_ja_JP.dat\n" - "Mobile_ko_KR.dat\n" - "Mobile_lt_LT.dat\n" - "Mobile_lv_LV.dat\n" - "Mobile_nb_NO.dat\n" - "Mobile_nl_NL.dat\n" - "Mobile_pl_PL.dat\n" - "Mobile_pt_BR.dat\n" - "Mobile_ro_RO.dat\n" - "Mobile_ru_RU.dat\n" - "Mobile_sk_SK.dat\n" - "Mobile_sl_SI.dat\n" - "Mobile_sv_SE.dat\n" - "Mobile_tr_TR.dat\n" - "Mobile_uk_UA.dat\n" - "Mobile_zh_CN.dat\n" - "Mobile_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels:\n" - "IPTC\n" - "IPTCExt\n" - "advanced\n" - "audioData\n" - "camera\n" - "categories\n" - "description\n" - "dicom\n" - "gpsData\n" - "history\n" - "mobile\n" - "origin\n" - "rawpacket\n" - "videoData\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/IPTC:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/IPTC/bin:\n" - "iptc.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/IPTC/loc:\n" - "IPTC_ar_AE.dat\n" - "IPTC_bg_BG.dat\n" - "IPTC_cs_CZ.dat\n" - "IPTC_da_DK.dat\n" - "IPTC_de_DE.dat\n" - "IPTC_el_GR.dat\n" - "IPTC_en_US.dat\n" - "IPTC_es_ES.dat\n" - "IPTC_et_EE.dat\n" - "IPTC_fi_FI.dat\n" - "IPTC_fr_FR.dat\n" - "IPTC_he_IL.dat\n" - "IPTC_hr_HR.dat\n" - "IPTC_hu_HU.dat\n" - "IPTC_it_IT.dat\n" - "IPTC_ja_JP.dat\n" - "IPTC_ko_KR.dat\n" - "IPTC_lt_LT.dat\n" - "IPTC_lv_LV.dat\n" - "IPTC_nb_NO.dat\n" - "IPTC_nl_NL.dat\n" - "IPTC_pl_PL.dat\n" - "IPTC_pt_BR.dat\n" - "IPTC_ro_RO.dat\n" - "IPTC_ru_RU.dat\n" - "IPTC_sk_SK.dat\n" - "IPTC_sl_SI.dat\n" - "IPTC_sv_SE.dat\n" - "IPTC_tr_TR.dat\n" - "IPTC_uk_UA.dat\n" - "IPTC_zh_CN.dat\n" - "IPTC_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/IPTCExt:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/IPTCExt/bin:\n" - "iptcExt.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/IPTCExt/loc:\n" - "IPTCExt_bg_BG.dat\n" - "IPTCExt_cs_CZ.dat\n" - "IPTCExt_da_DK.dat\n" - "IPTCExt_de_DE.dat\n" - "IPTCExt_en_US.dat\n" - "IPTCExt_es_ES.dat\n" - "IPTCExt_et_EE.dat\n" - "IPTCExt_fi_FI.dat\n" - "IPTCExt_fr_FR.dat\n" - "IPTCExt_hr_HR.dat\n" - "IPTCExt_hu_HU.dat\n" - "IPTCExt_it_IT.dat\n" - "IPTCExt_ja_JP.dat\n" - "IPTCExt_ko_KR.dat\n" - "IPTCExt_lt_LT.dat\n" - "IPTCExt_lv_LV.dat\n" - "IPTCExt_nb_NO.dat\n" - "IPTCExt_nl_NL.dat\n" - "IPTCExt_pl_PL.dat\n" - "IPTCExt_pt_BR.dat\n" - "IPTCExt_ro_RO.dat\n" - "IPTCExt_ru_RU.dat\n" - "IPTCExt_sk_SK.dat\n" - "IPTCExt_sl_SI.dat\n" - "IPTCExt_sv_SE.dat\n" - "IPTCExt_tr_TR.dat\n" - "IPTCExt_uk_UA.dat\n" - "IPTCExt_zh_CN.dat\n" - "IPTCExt_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/advanced:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/advanced/bin:\n" - "advanced.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/advanced/loc:\n" - "Advanced_ar_AE.dat\n" - "Advanced_bg_BG.dat\n" - "Advanced_cs_CZ.dat\n" - "Advanced_da_DK.dat\n" - "Advanced_de_DE.dat\n" - "Advanced_el_GR.dat\n" - "Advanced_en_US.dat\n" - "Advanced_es_ES.dat\n" - "Advanced_et_EE.dat\n" - "Advanced_fi_FI.dat\n" - "Advanced_fr_FR.dat\n" - "Advanced_he_IL.dat\n" - "Advanced_hr_HR.dat\n" - "Advanced_hu_HU.dat\n" - "Advanced_it_IT.dat\n" - "Advanced_ja_JP.dat\n" - "Advanced_ko_KR.dat\n" - "Advanced_lt_LT.dat\n" - "Advanced_lv_LV.dat\n" - "Advanced_nb_NO.dat\n" - "Advanced_nl_NL.dat\n" - "Advanced_pl_PL.dat\n" - "Advanced_pt_BR.dat\n" - "Advanced_ro_RO.dat\n" - "Advanced_ru_RU.dat\n" - "Advanced_sk_SK.dat\n" - "Advanced_sl_SI.dat\n" - "Advanced_sv_SE.dat\n" - "Advanced_tr_TR.dat\n" - "Advanced_uk_UA.dat\n" - "Advanced_zh_CN.dat\n" - "Advanced_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/audioData:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/audioData/bin:\n" - "audioData.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/audioData/loc:\n" - "AudioData_ar_AE.dat\n" - "AudioData_bg_BG.dat\n" - "AudioData_cs_CZ.dat\n" - "AudioData_da_DK.dat\n" - "AudioData_de_DE.dat\n" - "AudioData_el_GR.dat\n" - "AudioData_en_US.dat\n" - "AudioData_es_ES.dat\n" - "AudioData_et_EE.dat\n" - "AudioData_fi_FI.dat\n" - "AudioData_fr_FR.dat\n" - "AudioData_he_IL.dat\n" - "AudioData_hr_HR.dat\n" - "AudioData_hu_HU.dat\n" - "AudioData_it_IT.dat\n" - "AudioData_ja_JP.dat\n" - "AudioData_ko_KR.dat\n" - "AudioData_lt_LT.dat\n" - "AudioData_lv_LV.dat\n" - "AudioData_nb_NO.dat\n" - "AudioData_nl_NL.dat\n" - "AudioData_pl_PL.dat\n" - "AudioData_pt_BR.dat\n" - "AudioData_ro_RO.dat\n" - "AudioData_ru_RU.dat\n" - "AudioData_sk_SK.dat\n" - "AudioData_sl_SI.dat\n" - "AudioData_sv_SE.dat\n" - "AudioData_tr_TR.dat\n" - "AudioData_uk_UA.dat\n" - "AudioData_zh_CN.dat\n" - "AudioData_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/camera:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/camera/bin:\n" - "camera.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/camera/loc:\n" - "Camera_ar_AE.dat\n" - "Camera_bg_BG.dat\n" - "Camera_cs_CZ.dat\n" - "Camera_da_DK.dat\n" - "Camera_de_DE.dat\n" - "Camera_el_GR.dat\n" - "Camera_en_US.dat\n" - "Camera_es_ES.dat\n" - "Camera_et_EE.dat\n" - "Camera_fi_FI.dat\n" - "Camera_fr_FR.dat\n" - "Camera_he_IL.dat\n" - "Camera_hr_HR.dat\n" - "Camera_hu_HU.dat\n" - "Camera_it_IT.dat\n" - "Camera_ja_JP.dat\n" - "Camera_ko_KR.dat\n" - "Camera_lt_LT.dat\n" - "Camera_lv_LV.dat\n" - "Camera_nb_NO.dat\n" - "Camera_nl_NL.dat\n" - "Camera_pl_PL.dat\n" - "Camera_pt_BR.dat\n" - "Camera_ro_RO.dat\n" - "Camera_ru_RU.dat\n" - "Camera_sk_SK.dat\n" - "Camera_sl_SI.dat\n" - "Camera_sv_SE.dat\n" - "Camera_tr_TR.dat\n" - "Camera_uk_UA.dat\n" - "Camera_zh_CN.dat\n" - "Camera_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/categories:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/categories/bin:\n" - "categories.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/categories/loc:\n" - "Categories_ar_AE.dat\n" - "Categories_bg_BG.dat\n" - "Categories_cs_CZ.dat\n" - "Categories_da_DK.dat\n" - "Categories_de_DE.dat\n" - "Categories_el_GR.dat\n" - "Categories_en_US.dat\n" - "Categories_es_ES.dat\n" - "Categories_et_EE.dat\n" - "Categories_fi_FI.dat\n" - "Categories_fr_FR.dat\n" - "Categories_he_IL.dat\n" - "Categories_hr_HR.dat\n" - "Categories_hu_HU.dat\n" - "Categories_it_IT.dat\n" - "Categories_ja_JP.dat\n" - "Categories_ko_KR.dat\n" - "Categories_lt_LT.dat\n" - "Categories_lv_LV.dat\n" - "Categories_nb_NO.dat\n" - "Categories_nl_NL.dat\n" - "Categories_pl_PL.dat\n" - "Categories_pt_BR.dat\n" - "Categories_ro_RO.dat\n" - "Categories_ru_RU.dat\n" - "Categories_sk_SK.dat\n" - "Categories_sl_SI.dat\n" - "Categories_sv_SE.dat\n" - "Categories_tr_TR.dat\n" - "Categories_uk_UA.dat\n" - "Categories_zh_CN.dat\n" - "Categories_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/description:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/description/bin:\n" - "description.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/description/loc:\n" - "description_ar_AE.dat\n" - "description_bg_BG.dat\n" - "description_cs_CZ.dat\n" - "description_da_DK.dat\n" - "description_de_DE.dat\n" - "description_el_GR.dat\n" - "description_en_US.dat\n" - "description_es_ES.dat\n" - "description_et_EE.dat\n" - "description_fi_FI.dat\n" - "description_fr_FR.dat\n" - "description_he_IL.dat\n" - "description_hr_HR.dat\n" - "description_hu_HU.dat\n" - "description_it_IT.dat\n" - "description_ja_JP.dat\n" - "description_ko_KR.dat\n" - "description_lt_LT.dat\n" - "description_lv_LV.dat\n" - "description_nb_NO.dat\n" - "description_nl_NL.dat\n" - "description_pl_PL.dat\n" - "description_pt_BR.dat\n" - "description_ro_RO.dat\n" - "description_ru_RU.dat\n" - "description_sk_SK.dat\n" - "description_sl_SI.dat\n" - "description_sv_SE.dat\n" - "description_tr_TR.dat\n" - "description_uk_UA.dat\n" - "description_zh_CN.dat\n" - "description_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/dicom:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/dicom/bin:\n" - "dicom.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/dicom/loc:\n" - "DICOM_ar_AE.dat\n" - "DICOM_bg_BG.dat\n" - "DICOM_cs_CZ.dat\n" - "DICOM_da_DK.dat\n" - "DICOM_de_DE.dat\n" - "DICOM_el_GR.dat\n" - "DICOM_en_US.dat\n" - "DICOM_es_ES.dat\n" - "DICOM_et_EE.dat\n" - "DICOM_fi_FI.dat\n" - "DICOM_fr_FR.dat\n" - "DICOM_he_IL.dat\n" - "DICOM_hr_HR.dat\n" - "DICOM_hu_HU.dat\n" - "DICOM_it_IT.dat\n" - "DICOM_ja_JP.dat\n" - "DICOM_ko_KR.dat\n" - "DICOM_lt_LT.dat\n" - "DICOM_lv_LV.dat\n" - "DICOM_nb_NO.dat\n" - "DICOM_nl_NL.dat\n" - "DICOM_pl_PL.dat\n" - "DICOM_pt_BR.dat\n" - "DICOM_ro_RO.dat\n" - "DICOM_ru_RU.dat\n" - "DICOM_sk_SK.dat\n" - "DICOM_sl_SI.dat\n" - "DICOM_sv_SE.dat\n" - "DICOM_tr_TR.dat\n" - "DICOM_uk_UA.dat\n" - "DICOM_zh_CN.dat\n" - "DICOM_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/gpsData:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/gpsData/bin:\n" - "gpsData.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/gpsData/loc:\n" - "GPSData_ar_AE.dat\n" - "GPSData_bg_BG.dat\n" - "GPSData_cs_CZ.dat\n" - "GPSData_da_DK.dat\n" - "GPSData_de_DE.dat\n" - "GPSData_el_GR.dat\n" - "GPSData_en_US.dat\n" - "GPSData_es_ES.dat\n" - "GPSData_et_EE.dat\n" - "GPSData_fi_FI.dat\n" - "GPSData_fr_FR.dat\n" - "GPSData_he_IL.dat\n" - "GPSData_hr_HR.dat\n" - "GPSData_hu_HU.dat\n" - "GPSData_it_IT.dat\n" - "GPSData_ja_JP.dat\n" - "GPSData_ko_KR.dat\n" - "GPSData_lt_LT.dat\n" - "GPSData_lv_LV.dat\n" - "GPSData_nb_NO.dat\n" - "GPSData_nl_NL.dat\n" - "GPSData_pl_PL.dat\n" - "GPSData_pt_BR.dat\n" - "GPSData_ro_RO.dat\n" - "GPSData_ru_RU.dat\n" - "GPSData_sk_SK.dat\n" - "GPSData_sl_SI.dat\n" - "GPSData_sv_SE.dat\n" - "GPSData_tr_TR.dat\n" - "GPSData_uk_UA.dat\n" - "GPSData_zh_CN.dat\n" - "GPSData_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/history:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/history/bin:\n" - "history.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/history/loc:\n" - "History_ar_AE.dat\n" - "History_bg_BG.dat\n" - "History_cs_CZ.dat\n" - "History_da_DK.dat\n" - "History_de_DE.dat\n" - "History_el_GR.dat\n" - "History_en_US.dat\n" - "History_es_ES.dat\n" - "History_et_EE.dat\n" - "History_fi_FI.dat\n" - "History_fr_FR.dat\n" - "History_he_IL.dat\n" - "History_hr_HR.dat\n" - "History_hu_HU.dat\n" - "History_it_IT.dat\n" - "History_ja_JP.dat\n" - "History_ko_KR.dat\n" - "History_lt_LT.dat\n" - "History_lv_LV.dat\n" - "History_nb_NO.dat\n" - "History_nl_NL.dat\n" - "History_pl_PL.dat\n" - "History_pt_BR.dat\n" - "History_ro_RO.dat\n" - "History_ru_RU.dat\n" - "History_sk_SK.dat\n" - "History_sl_SI.dat\n" - "History_sv_SE.dat\n" - "History_tr_TR.dat\n" - "History_uk_UA.dat\n" - "History_zh_CN.dat\n" - "History_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/mobile:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/mobile/bin:\n" - "mobile.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/mobile/loc:\n" - "Mobile_ar_AE.dat\n" - "Mobile_bg_BG.dat\n" - "Mobile_cs_CZ.dat\n" - "Mobile_da_DK.dat\n" - "Mobile_de_DE.dat\n" - "Mobile_el_GR.dat\n" - "Mobile_en_US.dat\n" - "Mobile_es_ES.dat\n" - "Mobile_et_EE.dat\n" - "Mobile_fi_FI.dat\n" - "Mobile_fr_FR.dat\n" - "Mobile_he_IL.dat\n" - "Mobile_hr_HR.dat\n" - "Mobile_hu_HU.dat\n" - "Mobile_it_IT.dat\n" - "Mobile_ja_JP.dat\n" - "Mobile_ko_KR.dat\n" - "Mobile_lt_LT.dat\n" - "Mobile_lv_LV.dat\n" - "Mobile_nb_NO.dat\n" - "Mobile_nl_NL.dat\n" - "Mobile_pl_PL.dat\n" - "Mobile_pt_BR.dat\n" - "Mobile_ro_RO.dat\n" - "Mobile_ru_RU.dat\n" - "Mobile_sk_SK.dat\n" - "Mobile_sl_SI.dat\n" - "Mobile_sv_SE.dat\n" - "Mobile_tr_TR.dat\n" - "Mobile_uk_UA.dat\n" - "Mobile_zh_CN.dat\n" - "Mobile_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/origin:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/origin/bin:\n" - "origin.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/origin/loc:\n" - "origin_ar_AE.dat\n" - "origin_bg_BG.dat\n" - "origin_cs_CZ.dat\n" - "origin_da_DK.dat\n" - "origin_de_DE.dat\n" - "origin_el_GR.dat\n" - "origin_en_US.dat\n" - "origin_es_ES.dat\n" - "origin_et_EE.dat\n" - "origin_fi_FI.dat\n" - "origin_fr_FR.dat\n" - "origin_he_IL.dat\n" - "origin_hr_HR.dat\n" - "origin_hu_HU.dat\n" - "origin_it_IT.dat\n" - "origin_ja_JP.dat\n" - "origin_ko_KR.dat\n" - "origin_lt_LT.dat\n" - "origin_lv_LV.dat\n" - "origin_nb_NO.dat\n" - "origin_nl_NL.dat\n" - "origin_pl_PL.dat\n" - "origin_pt_BR.dat\n" - "origin_ro_RO.dat\n" - "origin_ru_RU.dat\n" - "origin_sk_SK.dat\n" - "origin_sl_SI.dat\n" - "origin_sv_SE.dat\n" - "origin_tr_TR.dat\n" - "origin_uk_UA.dat\n" - "origin_zh_CN.dat\n" - "origin_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/rawpacket:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/rawpacket/bin:\n" - "rawpacket.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/rawpacket/loc:\n" - "Rawpacket_ar_AE.dat\n" - "Rawpacket_bg_BG.dat\n" - "Rawpacket_cs_CZ.dat\n" - "Rawpacket_da_DK.dat\n" - "Rawpacket_de_DE.dat\n" - "Rawpacket_el_GR.dat\n" - "Rawpacket_en_US.dat\n" - "Rawpacket_es_ES.dat\n" - "Rawpacket_et_EE.dat\n" - "Rawpacket_fi_FI.dat\n" - "Rawpacket_fr_FR.dat\n" - "Rawpacket_he_IL.dat\n" - "Rawpacket_hr_HR.dat\n" - "Rawpacket_hu_HU.dat\n" - "Rawpacket_it_IT.dat\n" - "Rawpacket_ja_JP.dat\n" - "Rawpacket_ko_KR.dat\n" - "Rawpacket_lt_LT.dat\n" - "Rawpacket_lv_LV.dat\n" - "Rawpacket_nb_NO.dat\n" - "Rawpacket_nl_NL.dat\n" - "Rawpacket_pl_PL.dat\n" - "Rawpacket_pt_BR.dat\n" - "Rawpacket_ro_RO.dat\n" - "Rawpacket_ru_RU.dat\n" - "Rawpacket_sk_SK.dat\n" - "Rawpacket_sl_SI.dat\n" - "Rawpacket_sv_SE.dat\n" - "Rawpacket_tr_TR.dat\n" - "Rawpacket_uk_UA.dat\n" - "Rawpacket_zh_CN.dat\n" - "Rawpacket_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/videoData:\n" - "bin\n" - "loc\n" - "manifest.xml\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/videoData/bin:\n" - "videoData.swf\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Application Data/Custom File Info " - "Panels/4.0/panels/videoData/loc:\n" - "VideoData_ar_AE.dat\n" - "VideoData_bg_BG.dat\n" - "VideoData_cs_CZ.dat\n" - "VideoData_da_DK.dat\n" - "VideoData_de_DE.dat\n" - "VideoData_el_GR.dat\n" - "VideoData_en_US.dat\n" - "VideoData_es_ES.dat\n" - "VideoData_et_EE.dat\n" - "VideoData_fi_FI.dat\n" - "VideoData_fr_FR.dat\n" - "VideoData_he_IL.dat\n" - "VideoData_hr_HR.dat\n" - "VideoData_hu_HU.dat\n" - "VideoData_it_IT.dat\n" - "VideoData_ja_JP.dat\n" - "VideoData_ko_KR.dat\n" - "VideoData_lt_LT.dat\n" - "VideoData_lv_LV.dat\n" - "VideoData_nb_NO.dat\n" - "VideoData_nl_NL.dat\n" - "VideoData_pl_PL.dat\n" - "VideoData_pt_BR.dat\n" - "VideoData_ro_RO.dat\n" - "VideoData_ru_RU.dat\n" - "VideoData_sk_SK.dat\n" - "VideoData_sl_SI.dat\n" - "VideoData_sv_SE.dat\n" - "VideoData_tr_TR.dat\n" - "VideoData_uk_UA.dat\n" - "VideoData_zh_CN.dat\n" - "VideoData_zh_TW.dat\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks:\n" - "AdbeScriptUIFlex.framework\n" - "AdobeACE.framework\n" - "AdobeAGM.framework\n" - "AdobeAXE8SharedExpat.framework\n" - "AdobeAXEDOMCore.framework\n" - "AdobeBIB.framework\n" - "AdobeBIBUtils.framework\n" - "AdobeCoolType.framework\n" - "AdobeCrashReporter.framework\n" - "AdobeExtendScript.framework\n" - "AdobeLinguistic.framework\n" - "AdobeMPS.framework\n" - "AdobeOwl.framework\n" - "AdobePDFSettings.framework\n" - "AdobePIP.framework\n" - "AdobeScCore.framework\n" - "AdobeUpdater.framework\n" - "AdobeXMP.framework\n" - "AdobeXMPFiles.framework\n" - "AdobeXMPScript.framework\n" - "AlignmentLib.framework\n" - "CIT\n" - "CIT.framework\n" - "CITThreading.framework\n" - "Cg.framework\n" - "FileInfo.framework\n" - "ICUConverter.framework\n" - "ICUData.framework\n" - "IMSLib.dylib\n" - "LogSession.framework\n" - "PlugPlugOwl.framework\n" - "WRServices.framework\n" - "adbeape.framework\n" - "adobe_caps.framework\n" - "adobejp2k.framework\n" - "adobepdfl.framework\n" - "ahclient.framework\n" - "aif_core.framework\n" - "aif_ocl.framework\n" - "aif_ogl.framework\n" - "amtlib.framework\n" - "boost_date_time.framework\n" - "boost_signals.framework\n" - "boost_system.framework\n" - "boost_threads.framework\n" - "dvaaudiodevice.framework\n" - "dvacore.framework\n" - "dvamarshal.framework\n" - "dvamediatypes.framework\n" - "dvaplayer.framework\n" - "dvatransport.framework\n" - "dvaunittesting.framework\n" - "dynamiclink.framework\n" - "filter_graph.framework\n" - "libtbb.dylib\n" - "libtbbmalloc.dylib\n" - "mediacoreif.framework\n" - "patchmatch.framework\n" - "updaternotifications.framework\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdbeScriptUIFlex.framework:\n" - "AdbeScriptUIFlex\n" - "Resources\n" - "Versions\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdbeScriptUIFlex.framework/Versions:\n" - "A\n" - "Current\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdbeScriptUIFlex.framework/Versions/A:\n" - "AdbeScriptUIFlex\n" - "CodeResources\n" - "_CodeSignature\n" - "resources\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdbeScriptUIFlex.framework/Versions/A/" - "_CodeSignature:\n" - "CodeResources\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdbeScriptUIFlex.framework/Versions/A/" - "resources:\n" - "Info.plist\n" - "english.lproj\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdbeScriptUIFlex.framework/Versions/A/" - "resources/english.lproj:\n" - "InfoPlist.strings\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdobeACE.framework:\n" - "AdobeACE\n" - "Versions\n" - "resources\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdobeACE.framework/Versions:\n" - "A\n" - "current\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdobeACE.framework/Versions/A:\n" - "AdobeACE\n" - "CodeResources\n" - "_CodeSignature\n" - "resources\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdobeACE.framework/Versions/A/" - "_CodeSignature:\n" - "CodeResources\n" - "\n" - "/Applications/Adobe Photoshop CC/Adobe Photoshop " - "CC.app/Contents/Frameworks/AdobeACE.framework/Versions/A/" - "resources:\n" - "Info.plist\n" - "english.lproj\n" - "" - << 123 << 123.123 << "haha" << '\n' - << std::string("12356"); - LOG_RAW << "Testing finished\n"; - LOG_RAW_TO(5) << "Testing finished\n"; - thread_.join(); -} diff --git a/modules/trantor/trantor/tests/RunInLoopTest1.cc b/modules/trantor/trantor/tests/RunInLoopTest1.cc deleted file mode 100644 index d5c6951..0000000 --- a/modules/trantor/trantor/tests/RunInLoopTest1.cc +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by antao on 1/14/17. -// - -#include -#ifndef _WIN32 -#include -#endif - -#include -#include -#include -using namespace std::chrono_literals; -int main() -{ - trantor::EventLoop loop; - std::thread thread([&loop]() { - std::this_thread::sleep_for(3s); - loop.runInLoop([&loop]() { - std::cout << "runInLoop called in other thread" << std::endl; - loop.queueInLoop( - []() { std::cout << "queueInLoop in runInLoop" << std::endl; }); - }); - }); - loop.runInLoop([]() { std::cout << "runInLoop 1" << std::endl; }); - loop.runInLoop([]() { std::cout << "runInLoop 2" << std::endl; }); - loop.queueInLoop([]() { std::cout << "queueInLoop 1" << std::endl; }); - loop.runAfter(1.5, []() { std::cout << "run after 1.5" << std::endl; }); - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/RunInLoopTest2.cc b/modules/trantor/trantor/tests/RunInLoopTest2.cc deleted file mode 100644 index ce969a3..0000000 --- a/modules/trantor/trantor/tests/RunInLoopTest2.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif - -int main() -{ - std::atomic counter; - counter = 0; - std::promise pro; - auto ft = pro.get_future(); - trantor::EventLoopThread loopThread; - - auto loop = loopThread.getLoop(); - loop->runInLoop([&counter, &pro, loop]() { - for (int i = 0; i < 10000; ++i) - { - loop->queueInLoop([&counter, &pro]() { - ++counter; - if (counter.load() == 110000) - pro.set_value(1); - }); - } - }); - for (int i = 0; i < 10; ++i) - { - std::thread([&counter, loop, &pro]() { - for (int i = 0; i < 10000; ++i) - { - loop->runInLoop([&counter, &pro]() { - ++counter; - if (counter.load() == 110000) - pro.set_value(1); - }); - } - }).detach(); - } - loopThread.run(); - ft.get(); - std::cout << "counter=" << counter.load() << std::endl; -} diff --git a/modules/trantor/trantor/tests/RunOnQuitTest.cc b/modules/trantor/trantor/tests/RunOnQuitTest.cc deleted file mode 100644 index 37f9572..0000000 --- a/modules/trantor/trantor/tests/RunOnQuitTest.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif - -int main() -{ - std::atomic flag(false); - { - trantor::EventLoopThread thr; - thr.getLoop()->runOnQuit([&]() { flag = true; }); - thr.run(); - thr.getLoop()->quit(); - } - - if (flag == false) - { - std::cerr << "Test failed\n"; - } - else - { - std::cout << "Success\n"; - } -} diff --git a/modules/trantor/trantor/tests/SSLClientTest.cc b/modules/trantor/trantor/tests/SSLClientTest.cc deleted file mode 100644 index f38a0f3..0000000 --- a/modules/trantor/trantor/tests/SSLClientTest.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - trantor::Logger::setLogLevel(trantor::Logger::kTrace); - LOG_DEBUG << "TcpClient class test!"; - EventLoop loop; -#if USE_IPV6 - InetAddress serverAddr("::1", 8888, true); -#else - InetAddress serverAddr("127.0.0.1", 8888); -#endif - std::shared_ptr client[10]; - std::atomic_int connCount; - connCount = 1; - for (int i = 0; i < connCount; ++i) - { - client[i] = std::make_shared(&loop, - serverAddr, - "tcpclienttest"); - client[i]->enableSSL(false, false); - client[i]->setConnectionCallback( - [i, &loop, &connCount](const TcpConnectionPtr &conn) { - if (conn->connected()) - { - LOG_DEBUG << i << " connected!"; - char tmp[20]; - sprintf(tmp, "%d client!!", i); - conn->send(tmp); - } - else - { - LOG_DEBUG << i << " disconnected"; - --connCount; - if (connCount == 0) - loop.quit(); - } - }); - client[i]->setMessageCallback( - [](const TcpConnectionPtr &conn, MsgBuffer *buf) { - LOG_DEBUG << std::string(buf->peek(), buf->readableBytes()); - buf->retrieveAll(); - conn->shutdown(); - }); - client[i]->connect(); - } - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/SSLServerTest.cc b/modules/trantor/trantor/tests/SSLServerTest.cc deleted file mode 100644 index 3cf5213..0000000 --- a/modules/trantor/trantor/tests/SSLServerTest.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - LOG_DEBUG << "test start"; - Logger::setLogLevel(Logger::kTrace); - EventLoopThread loopThread; - loopThread.run(); -#if USE_IPV6 - InetAddress addr(8888, true, true); -#else - InetAddress addr(8888); -#endif - TcpServer server(loopThread.getLoop(), addr, "test"); - server.enableSSL("server.pem", "server.pem"); - server.setRecvMessageCallback( - [](const TcpConnectionPtr &connectionPtr, MsgBuffer *buffer) { - // LOG_DEBUG<<"recv callback!"; - std::cout << std::string(buffer->peek(), buffer->readableBytes()); - connectionPtr->send(buffer->peek(), buffer->readableBytes()); - buffer->retrieveAll(); - connectionPtr->forceClose(); - }); - server.setConnectionCallback([](const TcpConnectionPtr &connPtr) { - if (connPtr->connected()) - { - LOG_DEBUG << "New connection"; - connPtr->send("Hello world\r\n"); - } - else if (connPtr->disconnected()) - { - LOG_DEBUG << "connection disconnected"; - } - }); - server.setIoLoopNum(3); - server.start(); - loopThread.wait(); -} diff --git a/modules/trantor/trantor/tests/SendfileTest.cc b/modules/trantor/trantor/tests/SendfileTest.cc deleted file mode 100644 index c0abb5b..0000000 --- a/modules/trantor/trantor/tests/SendfileTest.cc +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif - -using namespace trantor; -#define USE_IPV6 0 -int main(int argc, char *argv[]) -{ - if (argc < 2) - { - std::cout << "usage:" << argv[0] << " filename" << std::endl; - return 1; - } - std::cout << "filename:" << argv[1] << std::endl; - struct stat filestat; - if (stat(argv[1], &filestat) < 0) - { - perror(""); - exit(1); - } - std::cout << "file len=" << filestat.st_size << std::endl; - - auto fp = fopen(argv[1], "rb"); - - if (fp == nullptr) - { - perror(""); - exit(1); - } - fclose(fp); - - LOG_DEBUG << "test start"; - - Logger::setLogLevel(Logger::kTrace); - EventLoopThread loopThread; - loopThread.run(); - -#if USE_IPV6 - InetAddress addr(1207, true, true); -#else - InetAddress addr(1207); -#endif - TcpServer server(loopThread.getLoop(), addr, "test"); - server.setRecvMessageCallback( - [](const TcpConnectionPtr &connectionPtr, MsgBuffer *buffer) { - // LOG_DEBUG<<"recv callback!"; - }); - int counter = 0; - server.setConnectionCallback( - [argv, &counter](const TcpConnectionPtr &connPtr) { - if (connPtr->connected()) - { - LOG_DEBUG << "New connection"; - std::thread t([connPtr, argv, &counter]() { - for (int i = 0; i < 5; ++i) - { - connPtr->sendFile(argv[1]); - char str[64]; - ++counter; - sprintf(str, "\n%d files sent!\n", counter); - connPtr->send(str, strlen(str)); - } - }); - t.detach(); - - for (int i = 0; i < 3; ++i) - { - connPtr->sendFile(argv[1]); - char str[64]; - ++counter; - sprintf(str, "\n%d files sent!\n", counter); - connPtr->send(str, strlen(str)); - } - } - else if (connPtr->disconnected()) - { - LOG_DEBUG << "connection disconnected"; - } - }); - server.setIoLoopNum(3); - server.start(); - loopThread.wait(); -} diff --git a/modules/trantor/trantor/tests/SerialTaskQueueTest1.cc b/modules/trantor/trantor/tests/SerialTaskQueueTest1.cc deleted file mode 100755 index b989d32..0000000 --- a/modules/trantor/trantor/tests/SerialTaskQueueTest1.cc +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include -#include - -using namespace std::chrono_literals; -int main() -{ - trantor::Logger::setLogLevel(trantor::Logger::kTrace); - trantor::SerialTaskQueue queue1("test queue1"); - trantor::SerialTaskQueue queue2(""); - queue1.runTaskInQueue([&]() { - for (int i = 0; i < 5; ++i) - { - std::this_thread::sleep_for(1s); - printf("task(%s) i=%d\n", queue1.getName().c_str(), i); - } - }); - queue2.runTaskInQueue([&]() { - for (int i = 0; i < 5; ++i) - { - std::this_thread::sleep_for(1s); - printf("task(%s) i=%d\n", queue2.getName().c_str(), i); - } - }); - queue1.waitAllTasksFinished(); - queue2.waitAllTasksFinished(); -} diff --git a/modules/trantor/trantor/tests/SerialTaskQueueTest2.cc b/modules/trantor/trantor/tests/SerialTaskQueueTest2.cc deleted file mode 100644 index 59068fe..0000000 --- a/modules/trantor/trantor/tests/SerialTaskQueueTest2.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include -#ifndef _WIN32 -#include -#endif - -int main() -{ - std::atomic counter; - counter = 0; - std::promise pro; - auto ft = pro.get_future(); - trantor::SerialTaskQueue queue(""); - queue.runTaskInQueue([&counter, &pro, &queue]() { - for (int i = 0; i < 10000; ++i) - { - queue.runTaskInQueue([&counter, &pro]() { - ++counter; - if (counter.load() == 110000) - pro.set_value(1); - }); - } - }); - for (int i = 0; i < 10; ++i) - { - std::thread([&counter, &queue, &pro]() { - for (int i = 0; i < 10000; ++i) - { - queue.runTaskInQueue([&counter, &pro]() { - ++counter; - if (counter.load() == 110000) - pro.set_value(1); - }); - } - }).detach(); - } - - ft.get(); - std::cout << "counter=" << counter.load() << std::endl; -} \ No newline at end of file diff --git a/modules/trantor/trantor/tests/TcpClientTest.cc b/modules/trantor/trantor/tests/TcpClientTest.cc deleted file mode 100644 index 68d6f89..0000000 --- a/modules/trantor/trantor/tests/TcpClientTest.cc +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - trantor::Logger::setLogLevel(trantor::Logger::kTrace); - LOG_DEBUG << "TcpClient class test!"; - EventLoop loop; -#if USE_IPV6 - InetAddress serverAddr("::1", 8888, true); -#else - InetAddress serverAddr("127.0.0.1", 8888); -#endif - std::shared_ptr client[10]; - std::atomic_int connCount; - connCount = 10; - for (int i = 0; i < 10; ++i) - { - client[i] = std::make_shared(&loop, - serverAddr, - "tcpclienttest"); - client[i]->setConnectionCallback( - [i, &loop, &connCount](const TcpConnectionPtr &conn) { - if (conn->connected()) - { - LOG_DEBUG << i << " connected!"; - char tmp[20]; - sprintf(tmp, "%d client!!", i); - conn->send(tmp); - } - else - { - LOG_DEBUG << i << " disconnected"; - --connCount; - if (connCount == 0) - loop.quit(); - } - }); - client[i]->setMessageCallback( - [](const TcpConnectionPtr &conn, MsgBuffer *buf) { - LOG_DEBUG << std::string(buf->peek(), buf->readableBytes()); - buf->retrieveAll(); - conn->shutdown(); - }); - client[i]->connect(); - } - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/TcpServerTest.cc b/modules/trantor/trantor/tests/TcpServerTest.cc deleted file mode 100644 index dbd8b7c..0000000 --- a/modules/trantor/trantor/tests/TcpServerTest.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include -#include -using namespace trantor; -#define USE_IPV6 0 -int main() -{ - LOG_DEBUG << "test start"; - Logger::setLogLevel(Logger::kTrace); - EventLoopThread loopThread; - loopThread.run(); -#if USE_IPV6 - InetAddress addr(8888, true, true); -#else - InetAddress addr(8888); -#endif - TcpServer server(loopThread.getLoop(), addr, "test"); - server.setRecvMessageCallback( - [](const TcpConnectionPtr &connectionPtr, MsgBuffer *buffer) { - // LOG_DEBUG<<"recv callback!"; - std::cout << std::string(buffer->peek(), buffer->readableBytes()); - connectionPtr->send(buffer->peek(), buffer->readableBytes()); - buffer->retrieveAll(); - // connectionPtr->forceClose(); - }); - server.setConnectionCallback([](const TcpConnectionPtr &connPtr) { - if (connPtr->connected()) - { - LOG_DEBUG << "New connection"; - } - else if (connPtr->disconnected()) - { - LOG_DEBUG << "connection disconnected"; - } - }); - server.setIoLoopNum(3); - server.start(); - loopThread.wait(); -} diff --git a/modules/trantor/trantor/tests/TimerTest.cc b/modules/trantor/trantor/tests/TimerTest.cc deleted file mode 100644 index 606c45e..0000000 --- a/modules/trantor/trantor/tests/TimerTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include -#include -using namespace std::literals; - -int main() -{ - trantor::Logger::setLogLevel(trantor::Logger::kTrace); - trantor::EventLoop loop; - auto id1 = loop.runAfter(1s, []() { - LOG_ERROR << "This info shouldn't be displayed!"; - }); - loop.invalidateTimer(id1); - auto id2 = loop.runEvery(0.3s, []() { - LOG_ERROR << "This timer will be invalidated after 3 second;"; - }); - std::thread thread([id2, &loop]() { - std::this_thread::sleep_for(3s); - loop.invalidateTimer(id2); - }); - thread.detach(); - loop.runEvery(3, []() { LOG_DEBUG << " runEvery 3s"; }); - loop.runAt(trantor::Date::date().after(10), - []() { LOG_DEBUG << "runAt 10s later"; }); - loop.runAfter(5, []() { std::cout << "runAt 5s later" << std::endl; }); - loop.runEvery(1, []() { std::cout << "runEvery 1s" << std::endl; }); - loop.runAfter(4, []() { std::cout << "runAfter 4s" << std::endl; }); - loop.runAfter(10min, - []() { std::cout << "*********** run after 10 min\n"; }); - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/TimerTest1.cc b/modules/trantor/trantor/tests/TimerTest1.cc deleted file mode 100644 index 09884c5..0000000 --- a/modules/trantor/trantor/tests/TimerTest1.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -int main() -{ - trantor::EventLoop loop; - LOG_FATAL << trantor::Date::date().roundDay().microSecondsSinceEpoch(); - trantor::Date begin = trantor::Date::date().roundSecond().after(2); - auto id = loop.runAt(begin, [begin, &loop]() { - LOG_DEBUG << "test begin:"; - srand((unsigned int)time(NULL)); - for (int i = 0; i < 10000; ++i) - { - int aa = rand() % 10000; - double s = (double)aa / 1000.0 + 1; - loop.runAt(begin.after(s), - [s]() { LOG_ERROR << "run After:" << s; }); - } - LOG_DEBUG << "timer created!"; - }); - std::cout << "id=" << id << std::endl; - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/TimingWheelTest.cc b/modules/trantor/trantor/tests/TimingWheelTest.cc deleted file mode 100644 index c9ae1b5..0000000 --- a/modules/trantor/trantor/tests/TimingWheelTest.cc +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -class MyClass -{ - public: - MyClass(); - MyClass(MyClass &&) = default; - MyClass(const MyClass &) = default; - MyClass &operator=(MyClass &&) = default; - MyClass &operator=(const MyClass &) = default; - ~MyClass(); - - private: -}; - -MyClass::MyClass() -{ -} - -MyClass::~MyClass() -{ - LOG_DEBUG << "MyClass destructed!"; -} - -int main() -{ - LOG_DEBUG << "start"; - trantor::EventLoop loop; - std::weak_ptr weakEntry; - trantor::TimingWheel wheel(&loop, 75, 0.1, 100); - { - auto entry = std::shared_ptr(new MyClass); - - wheel.insertEntry(75, entry); - weakEntry = entry; - } - // loop.runAfter(5.0, [&]() { - // wheel.insertEntry(10, weakEntry.lock()); - // }); - // loop.runAfter(0.5,[&](){ - // wheel.insertEntry(28,weakEntry.lock()); - // }); - // loop.runEvery(1.0,[](){ - // LOG_DEBUG<<"tick"; - // }); - loop.loop(); -} diff --git a/modules/trantor/trantor/tests/server.pem b/modules/trantor/trantor/tests/server.pem deleted file mode 100644 index 507f700..0000000 --- a/modules/trantor/trantor/tests/server.pem +++ /dev/null @@ -1,49 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC/vLeZ4B80b22y -JSF9WoAEGo5D0GLlzSxL7rRZSd81h3YMKpsgFT4WkZxs9sqoRW/OTaqMGuEzGt6a -54RMwycQwJL+GGt/stZ+7AYHoLE6cQzP8iFcwy4mLFsX+gQjoE0UHr0RykKRl3Vw -qZST74AhAMlFvEDCfoMxTy9dy5ZjbLTFrH1kvo5CT9MEbyBLpxYrYYFjBAMIZdvV -82Mz3JftDLbx7t+96PaGLpDMLk9NgrV1kbUpzck/aCbZ5DgV7enTU33tVIcfMU5e -fZii044OkOvFNXibi6tdPORP8TBnrmEZjmDnFAgEijzpIcJ4VVPTrlCuxLUKcSDY -wYLro7gbAgMBAAECggEAesztcnoewkCTq0MovdZWo0o2z6wJi1DrC/7oNz+e2/PU -YVpwXA3+5AmCfC9cAIXoY+NOVclpbofJBsE89MUQoiQUgPU29GSgCE42VnBO0jVR -lWVohLblOcGy3hpcyEyE0VwWj+xQ0lqE9xFFfbIpB/ou7qDxgR/x+oTSu2oG+cmr -xv+Dj+k46QW0X2A3XHnlZkk0fQGb+Tf3fIJ4BBwF/UFQTDyZPZrsZfbpoEk1BnIf -VPcfM1/ca6h1t/oEnpD66H2TjxYzZC58mqZSZIZ+Pk+wocSsF5UcQLedcM137LDH -OR+fdscinr1xgMhV30RmAUP5tug9Km3oq8wf4Xl1IQKBgQDmDtYbwN7V1eA6Dbeq -HCk07t/llK+j4mvyuU+pVKfNHmnUUd+NPpDwREFrfoR6ilrZMJ4Obl7z53rja+9s -JqECBThhRzHxnUQgsu3DQeY7e2KxBBGGvhQBjRGtVRID3aFTTyMKvaOkTc7kL+x1 -5DbtoVAA1kbYnjgZJyZosx+bmQKBgQDVW6lXxoLzC7npXdXOTMJifExcCIzXskc9 -5b+rJTXgkqaPQSQ7nNmRReUY9r9UBsZKLduuYJZ3TLMCaU91/wBwc1ygkQvRz+8A -2QGMovlVOqwPAOEc1lMCXzQki9PcqmVX/e0oFmTtUgyF4RKEwL/q8A9fWy587rkQ -57MDNJ3h0wKBgQDNJgPFweq0EsGd4yeZuP0B59Wee0VYxgru6lLgM85iujEzFUNd -R6KlrqgLvElUoNW8gX8gbUmdBBlwfYqGDbhb/d212W/u/geHhSdCjBxLhI6QPYmH -dy6N54cQ4yBqdBNtH8+mv08SsBPDJf0db8GPi960sF+CwSxTObclfD2+WQKBgBgi -HxyLmsJNIEFSWN3V9uLW9ngui2fWhZJty2lbcyWs0ORBVQzdKArzof9Z4bhqb8Fy -QHgP+tURuunZ6aAKMQ2HLwIGhhS8dWdeJHu474UBdvbXfZ8aaxdIl4hOvK8oIwB5 -+3peVho1/q6iD8suVkcH0mVR1gdRpWNRIgGJ0RX7AoGBAMzp0u3X3SEMWTlqFR7D -BJqmpiMvJJJSqex1i4PJoy+uJpqfl3b1jUMnFIS4GiscVCIEJkPpZaz3eSTt7aVQ -+7v0b/Cusv1qYX2c5v9j9x7nmUlfdwT5rY2g6RXI/xlhPD9elb1dxlzmhiO4VQtr -AdiFmu0poyPpEGwjpcLEZq6K ------END PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDajCCAlICCQCXmD7IkkDArzANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJD -TjEQMA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEPMA0GA1UECgwG -YW4tdGFvMQ8wDQYDVQQLDAZhbi10YW8xIjAgBgkqhkiG9w0BCQEWE2FudGFvMjAw -MkBnbWFpbC5jb20wHhcNMTgwNzIxMDEyMjEyWhcNMTkwNzIxMDEyMjEyWjB3MQsw -CQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEP -MA0GA1UECgwGYW4tdGFvMQ8wDQYDVQQLDAZhbi10YW8xIjAgBgkqhkiG9w0BCQEW -E2FudGFvMjAwMkBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC/vLeZ4B80b22yJSF9WoAEGo5D0GLlzSxL7rRZSd81h3YMKpsgFT4WkZxs -9sqoRW/OTaqMGuEzGt6a54RMwycQwJL+GGt/stZ+7AYHoLE6cQzP8iFcwy4mLFsX -+gQjoE0UHr0RykKRl3VwqZST74AhAMlFvEDCfoMxTy9dy5ZjbLTFrH1kvo5CT9ME -byBLpxYrYYFjBAMIZdvV82Mz3JftDLbx7t+96PaGLpDMLk9NgrV1kbUpzck/aCbZ -5DgV7enTU33tVIcfMU5efZii044OkOvFNXibi6tdPORP8TBnrmEZjmDnFAgEijzp -IcJ4VVPTrlCuxLUKcSDYwYLro7gbAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAClA -Z6JHessY1mo0ObCp8Sh83gIiGu9M77xz6Gy2vUpUGE9N1hJwYH3uZPLbpnIuxZU0 -uDXd9w5vCJmtqo/4X6sedqKA6Upi8DROawtCUJaGrHrb2vJONyL7A3OWpHyYgOAa -z+sl4jbrGGv4azSg9ef1mQZTDcEcdsYiKj9U4zoyDXteyt6NQK3x5BtziB0mJfeM -gjrltVcc59s8Z2jf3PI3qmWtMuJm7KGHlan2DUz12AZxY3sJrFyew3Vi1V2uvIZB -YwgcXbVa3r6PQU3RwFwkazxAe80ZgiQlVsEiBl8mre4zznt5XHF6mzAqvpHyXPCI -LfEO3waLkgB94mFha5A= ------END CERTIFICATE----- diff --git a/modules/trantor/trantor/third_party/wepoll/LICENSE b/modules/trantor/trantor/third_party/wepoll/LICENSE deleted file mode 100644 index 8753814..0000000 --- a/modules/trantor/trantor/third_party/wepoll/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -wepoll - epoll for Windows -https://github.com/piscisaureus/wepoll - -Copyright 2012-2020, Bert Belder -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. - -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. \ No newline at end of file diff --git a/modules/trantor/trantor/third_party/wepoll/README.md b/modules/trantor/trantor/third_party/wepoll/README.md deleted file mode 100644 index fc9ce85..0000000 --- a/modules/trantor/trantor/third_party/wepoll/README.md +++ /dev/null @@ -1,41 +0,0 @@ -## wepoll - -This library is based on [wepoll v1.5.8](https://github.com/piscisaureus/wepoll/commit/0598a791bf9cbbf480793d778930fc635b044980). - -An eventfd-like mechanism is added to it. After making the changes, we can wake up `trantor::EventLoop` from the epoll_wait() function. - -## Modifications - -```shell -diff wepoll.h Wepoll.h -53a54 -> EPOLLEVENT = (int)(1U << 14), -67a69 -> #define EPOLLEVENT (1U << 14) -111a114 -> WEPOLL_EXPORT void epoll_post_signal(HANDLE ephnd, uint64_t event); -``` - -```shell -diff wepoll.c Wepoll.c -50a51 -> EPOLLEVENT = (int)(1U << 14), -64a66 -> #define EPOLLEVENT (1U << 14) -1262a1265,1271 -> if (iocp_events[i].lpCompletionKey) -> { -> struct epoll_event* ev = &epoll_events[epoll_event_count++]; -> ev->data.u64 = (uint64_t)iocp_events[i].lpCompletionKey; -> ev->events = EPOLLEVENT; -> continue; -> } -2441a2451,2457 -> void epoll_post_signal(HANDLE port_handle, uint64_t event) -> { -> ULONG_PTR ev; -> ev = (ULONG_PTR)event; -> PostQueuedCompletionStatus(port_handle, 1, ev, NULL); -> } -> -``` diff --git a/modules/trantor/trantor/third_party/wepoll/Wepoll.c b/modules/trantor/trantor/third_party/wepoll/Wepoll.c deleted file mode 100644 index 5b8ee51..0000000 --- a/modules/trantor/trantor/third_party/wepoll/Wepoll.c +++ /dev/null @@ -1,2491 +0,0 @@ -/* - * wepoll - epoll for Windows - * https://github.com/piscisaureus/wepoll - * - * Copyright 2012-2020, Bert Belder - * 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. - * - * 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 WEPOLL_EXPORT -#define WEPOLL_EXPORT -#endif - -#include - -enum EPOLL_EVENTS -{ - EPOLLIN = (int)(1U << 0), - EPOLLPRI = (int)(1U << 1), - EPOLLOUT = (int)(1U << 2), - EPOLLERR = (int)(1U << 3), - EPOLLHUP = (int)(1U << 4), - EPOLLRDNORM = (int)(1U << 6), - EPOLLRDBAND = (int)(1U << 7), - EPOLLWRNORM = (int)(1U << 8), - EPOLLWRBAND = (int)(1U << 9), - EPOLLMSG = (int)(1U << 10), /* Never reported. */ - EPOLLRDHUP = (int)(1U << 13), - EPOLLEVENT = (int)(1U << 14), - EPOLLONESHOT = (int)(1U << 31) -}; - -#define EPOLLIN (1U << 0) -#define EPOLLPRI (1U << 1) -#define EPOLLOUT (1U << 2) -#define EPOLLERR (1U << 3) -#define EPOLLHUP (1U << 4) -#define EPOLLRDNORM (1U << 6) -#define EPOLLRDBAND (1U << 7) -#define EPOLLWRNORM (1U << 8) -#define EPOLLWRBAND (1U << 9) -#define EPOLLMSG (1U << 10) -#define EPOLLRDHUP (1U << 13) -#define EPOLLEVENT (1U << 14) -#define EPOLLONESHOT (1U << 31) - -#define EPOLL_CTL_ADD 1 -#define EPOLL_CTL_MOD 2 -#define EPOLL_CTL_DEL 3 - -typedef void* HANDLE; -typedef uintptr_t SOCKET; - -typedef union epoll_data -{ - void* ptr; - int fd; - uint32_t u32; - uint64_t u64; - SOCKET sock; /* Windows specific */ - HANDLE hnd; /* Windows specific */ -} epoll_data_t; - -struct epoll_event -{ - uint32_t events; /* Epoll events and flags */ - epoll_data_t data; /* User data variable */ -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - WEPOLL_EXPORT HANDLE epoll_create(int size); - WEPOLL_EXPORT HANDLE epoll_create1(int flags); - - WEPOLL_EXPORT int epoll_close(HANDLE ephnd); - - WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd, - int op, - SOCKET sock, - struct epoll_event* event); - - WEPOLL_EXPORT int epoll_wait(HANDLE ephnd, - struct epoll_event* events, - int maxevents, - int timeout); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#include - -#include - -#define WEPOLL_INTERNAL static -#define WEPOLL_INTERNAL_EXTERN static - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonportable-system-include-path" -#pragma clang diagnostic ignored "-Wreserved-id-macro" -#elif defined(_MSC_VER) -#pragma warning(push, 1) -#endif - -#undef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN - -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 - -#include -#include -#include - -#if defined(__clang__) -#pragma clang diagnostic pop -#elif defined(_MSC_VER) -#pragma warning(pop) -#endif - -WEPOLL_INTERNAL int nt_global_init(void); - -typedef LONG NTSTATUS; -typedef NTSTATUS* PNTSTATUS; - -#ifndef NT_SUCCESS -#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0) -#endif - -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) -#endif - -#ifndef STATUS_PENDING -#define STATUS_PENDING ((NTSTATUS)0x00000103L) -#endif - -#ifndef STATUS_CANCELLED -#define STATUS_CANCELLED ((NTSTATUS)0xC0000120L) -#endif - -#ifndef STATUS_NOT_FOUND -#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L) -#endif - -typedef struct _IO_STATUS_BLOCK -{ - NTSTATUS Status; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG Reserved); - -typedef struct _UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING, *PUNICODE_STRING; - -#define RTL_CONSTANT_STRING(s) \ - { \ - sizeof(s) - sizeof((s)[0]), sizeof(s), s \ - } - -typedef struct _OBJECT_ATTRIBUTES -{ - ULONG Length; - HANDLE RootDirectory; - PUNICODE_STRING ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; - -#define RTL_CONSTANT_OBJECT_ATTRIBUTES(ObjectName, Attributes) \ - { \ - sizeof(OBJECT_ATTRIBUTES), NULL, ObjectName, Attributes, NULL, NULL \ - } - -#ifndef FILE_OPEN -#define FILE_OPEN 0x00000001UL -#endif - -#define KEYEDEVENT_WAIT 0x00000001UL -#define KEYEDEVENT_WAKE 0x00000002UL -#define KEYEDEVENT_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE) - -#define NT_NTDLL_IMPORT_LIST(X) \ - X(NTSTATUS, \ - NTAPI, \ - NtCancelIoFileEx, \ - (HANDLE FileHandle, \ - PIO_STATUS_BLOCK IoRequestToCancel, \ - PIO_STATUS_BLOCK IoStatusBlock)) \ - \ - X(NTSTATUS, \ - NTAPI, \ - NtCreateFile, \ - (PHANDLE FileHandle, \ - ACCESS_MASK DesiredAccess, \ - POBJECT_ATTRIBUTES ObjectAttributes, \ - PIO_STATUS_BLOCK IoStatusBlock, \ - PLARGE_INTEGER AllocationSize, \ - ULONG FileAttributes, \ - ULONG ShareAccess, \ - ULONG CreateDisposition, \ - ULONG CreateOptions, \ - PVOID EaBuffer, \ - ULONG EaLength)) \ - \ - X(NTSTATUS, \ - NTAPI, \ - NtCreateKeyedEvent, \ - (PHANDLE KeyedEventHandle, \ - ACCESS_MASK DesiredAccess, \ - POBJECT_ATTRIBUTES ObjectAttributes, \ - ULONG Flags)) \ - \ - X(NTSTATUS, \ - NTAPI, \ - NtDeviceIoControlFile, \ - (HANDLE FileHandle, \ - HANDLE Event, \ - PIO_APC_ROUTINE ApcRoutine, \ - PVOID ApcContext, \ - PIO_STATUS_BLOCK IoStatusBlock, \ - ULONG IoControlCode, \ - PVOID InputBuffer, \ - ULONG InputBufferLength, \ - PVOID OutputBuffer, \ - ULONG OutputBufferLength)) \ - \ - X(NTSTATUS, \ - NTAPI, \ - NtReleaseKeyedEvent, \ - (HANDLE KeyedEventHandle, \ - PVOID KeyValue, \ - BOOLEAN Alertable, \ - PLARGE_INTEGER Timeout)) \ - \ - X(NTSTATUS, \ - NTAPI, \ - NtWaitForKeyedEvent, \ - (HANDLE KeyedEventHandle, \ - PVOID KeyValue, \ - BOOLEAN Alertable, \ - PLARGE_INTEGER Timeout)) \ - \ - X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status)) - -#define X(return_type, attributes, name, parameters) \ - WEPOLL_INTERNAL_EXTERN return_type(attributes* name) parameters; -NT_NTDLL_IMPORT_LIST(X) -#undef X - -#define AFD_POLL_RECEIVE 0x0001 -#define AFD_POLL_RECEIVE_EXPEDITED 0x0002 -#define AFD_POLL_SEND 0x0004 -#define AFD_POLL_DISCONNECT 0x0008 -#define AFD_POLL_ABORT 0x0010 -#define AFD_POLL_LOCAL_CLOSE 0x0020 -#define AFD_POLL_ACCEPT 0x0080 -#define AFD_POLL_CONNECT_FAIL 0x0100 - -typedef struct _AFD_POLL_HANDLE_INFO -{ - HANDLE Handle; - ULONG Events; - NTSTATUS Status; -} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO; - -typedef struct _AFD_POLL_INFO -{ - LARGE_INTEGER Timeout; - ULONG NumberOfHandles; - ULONG Exclusive; - AFD_POLL_HANDLE_INFO Handles[1]; -} AFD_POLL_INFO, *PAFD_POLL_INFO; - -WEPOLL_INTERNAL int afd_create_device_handle(HANDLE iocp_handle, - HANDLE* afd_device_handle_out); - -WEPOLL_INTERNAL int afd_poll(HANDLE afd_device_handle, - AFD_POLL_INFO* poll_info, - IO_STATUS_BLOCK* io_status_block); -WEPOLL_INTERNAL int afd_cancel_poll(HANDLE afd_device_handle, - IO_STATUS_BLOCK* io_status_block); - -#define return_map_error(value) \ - do \ - { \ - err_map_win_error(); \ - return (value); \ - } while (0) - -#define return_set_error(value, error) \ - do \ - { \ - err_set_win_error(error); \ - return (value); \ - } while (0) - -WEPOLL_INTERNAL void err_map_win_error(void); -WEPOLL_INTERNAL void err_set_win_error(DWORD error); -WEPOLL_INTERNAL int err_check_handle(HANDLE handle); - -#define IOCTL_AFD_POLL 0x00012024 - -static UNICODE_STRING afd__device_name = - RTL_CONSTANT_STRING(L"\\Device\\Afd\\Wepoll"); - -static OBJECT_ATTRIBUTES afd__device_attributes = - RTL_CONSTANT_OBJECT_ATTRIBUTES(&afd__device_name, 0); - -int afd_create_device_handle(HANDLE iocp_handle, HANDLE* afd_device_handle_out) -{ - HANDLE afd_device_handle; - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - /* By opening \Device\Afd without specifying any extended attributes, we'll - * get a handle that lets us talk to the AFD driver, but that doesn't have - * an associated endpoint (so it's not a socket). */ - status = NtCreateFile(&afd_device_handle, - SYNCHRONIZE, - &afd__device_attributes, - &iosb, - NULL, - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_OPEN, - 0, - NULL, - 0); - if (status != STATUS_SUCCESS) - return_set_error(-1, RtlNtStatusToDosError(status)); - - if (CreateIoCompletionPort(afd_device_handle, iocp_handle, 0, 0) == NULL) - goto error; - - if (!SetFileCompletionNotificationModes(afd_device_handle, - FILE_SKIP_SET_EVENT_ON_HANDLE)) - goto error; - - *afd_device_handle_out = afd_device_handle; - return 0; - -error: - CloseHandle(afd_device_handle); - return_map_error(-1); -} - -int afd_poll(HANDLE afd_device_handle, - AFD_POLL_INFO* poll_info, - IO_STATUS_BLOCK* io_status_block) -{ - NTSTATUS status; - - /* Blocking operation is not supported. */ - assert(io_status_block != NULL); - - io_status_block->Status = STATUS_PENDING; - status = NtDeviceIoControlFile(afd_device_handle, - NULL, - NULL, - io_status_block, - io_status_block, - IOCTL_AFD_POLL, - poll_info, - sizeof *poll_info, - poll_info, - sizeof *poll_info); - - if (status == STATUS_SUCCESS) - return 0; - else if (status == STATUS_PENDING) - return_set_error(-1, ERROR_IO_PENDING); - else - return_set_error(-1, RtlNtStatusToDosError(status)); -} - -int afd_cancel_poll(HANDLE afd_device_handle, IO_STATUS_BLOCK* io_status_block) -{ - NTSTATUS cancel_status; - IO_STATUS_BLOCK cancel_iosb; - - /* If the poll operation has already completed or has been cancelled - * earlier, there's nothing left for us to do. */ - if (io_status_block->Status != STATUS_PENDING) - return 0; - - cancel_status = - NtCancelIoFileEx(afd_device_handle, io_status_block, &cancel_iosb); - - /* NtCancelIoFileEx() may return STATUS_NOT_FOUND if the operation completed - * just before calling NtCancelIoFileEx(). This is not an error. */ - if (cancel_status == STATUS_SUCCESS || cancel_status == STATUS_NOT_FOUND) - return 0; - else - return_set_error(-1, RtlNtStatusToDosError(cancel_status)); -} - -WEPOLL_INTERNAL int epoll_global_init(void); - -WEPOLL_INTERNAL int init(void); - -typedef struct port_state port_state_t; -typedef struct queue queue_t; -typedef struct sock_state sock_state_t; -typedef struct ts_tree_node ts_tree_node_t; - -WEPOLL_INTERNAL port_state_t* port_new(HANDLE* iocp_handle_out); -WEPOLL_INTERNAL int port_close(port_state_t* port_state); -WEPOLL_INTERNAL int port_delete(port_state_t* port_state); - -WEPOLL_INTERNAL int port_wait(port_state_t* port_state, - struct epoll_event* events, - int maxevents, - int timeout); - -WEPOLL_INTERNAL int port_ctl(port_state_t* port_state, - int op, - SOCKET sock, - struct epoll_event* ev); - -WEPOLL_INTERNAL int port_register_socket(port_state_t* port_state, - sock_state_t* sock_state, - SOCKET socket); -WEPOLL_INTERNAL void port_unregister_socket(port_state_t* port_state, - sock_state_t* sock_state); -WEPOLL_INTERNAL sock_state_t* port_find_socket(port_state_t* port_state, - SOCKET socket); - -WEPOLL_INTERNAL void port_request_socket_update(port_state_t* port_state, - sock_state_t* sock_state); -WEPOLL_INTERNAL void port_cancel_socket_update(port_state_t* port_state, - sock_state_t* sock_state); - -WEPOLL_INTERNAL void port_add_deleted_socket(port_state_t* port_state, - sock_state_t* sock_state); -WEPOLL_INTERNAL void port_remove_deleted_socket(port_state_t* port_state, - sock_state_t* sock_state); - -WEPOLL_INTERNAL HANDLE port_get_iocp_handle(port_state_t* port_state); -WEPOLL_INTERNAL queue_t* port_get_poll_group_queue(port_state_t* port_state); - -WEPOLL_INTERNAL port_state_t* port_state_from_handle_tree_node( - ts_tree_node_t* tree_node); -WEPOLL_INTERNAL ts_tree_node_t* port_state_to_handle_tree_node( - port_state_t* port_state); - -/* The reflock is a special kind of lock that normally prevents a chunk of - * memory from being freed, but does allow the chunk of memory to eventually be - * released in a coordinated fashion. - * - * Under normal operation, threads increase and decrease the reference count, - * which are wait-free operations. - * - * Exactly once during the reflock's lifecycle, a thread holding a reference to - * the lock may "destroy" the lock; this operation blocks until all other - * threads holding a reference to the lock have dereferenced it. After - * "destroy" returns, the calling thread may assume that no other threads have - * a reference to the lock. - * - * Attemmpting to lock or destroy a lock after reflock_unref_and_destroy() has - * been called is invalid and results in undefined behavior. Therefore the user - * should use another lock to guarantee that this can't happen. - */ - -typedef struct reflock -{ - volatile long state; /* 32-bit Interlocked APIs operate on `long` values. */ -} reflock_t; - -WEPOLL_INTERNAL int reflock_global_init(void); - -WEPOLL_INTERNAL void reflock_init(reflock_t* reflock); -WEPOLL_INTERNAL void reflock_ref(reflock_t* reflock); -WEPOLL_INTERNAL void reflock_unref(reflock_t* reflock); -WEPOLL_INTERNAL void reflock_unref_and_destroy(reflock_t* reflock); - -#include - -/* N.b.: the tree functions do not set errno or LastError when they fail. Each - * of the API functions has at most one failure mode. It is up to the caller to - * set an appropriate error code when necessary. */ - -typedef struct tree tree_t; -typedef struct tree_node tree_node_t; - -typedef struct tree -{ - tree_node_t* root; -} tree_t; - -typedef struct tree_node -{ - tree_node_t* left; - tree_node_t* right; - tree_node_t* parent; - uintptr_t key; - bool red; -} tree_node_t; - -WEPOLL_INTERNAL void tree_init(tree_t* tree); -WEPOLL_INTERNAL void tree_node_init(tree_node_t* node); - -WEPOLL_INTERNAL int tree_add(tree_t* tree, tree_node_t* node, uintptr_t key); -WEPOLL_INTERNAL void tree_del(tree_t* tree, tree_node_t* node); - -WEPOLL_INTERNAL tree_node_t* tree_find(const tree_t* tree, uintptr_t key); -WEPOLL_INTERNAL tree_node_t* tree_root(const tree_t* tree); - -typedef struct ts_tree -{ - tree_t tree; - SRWLOCK lock; -} ts_tree_t; - -typedef struct ts_tree_node -{ - tree_node_t tree_node; - reflock_t reflock; -} ts_tree_node_t; - -WEPOLL_INTERNAL void ts_tree_init(ts_tree_t* rtl); -WEPOLL_INTERNAL void ts_tree_node_init(ts_tree_node_t* node); - -WEPOLL_INTERNAL int ts_tree_add(ts_tree_t* ts_tree, - ts_tree_node_t* node, - uintptr_t key); - -WEPOLL_INTERNAL ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree, - uintptr_t key); -WEPOLL_INTERNAL ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree, - uintptr_t key); - -WEPOLL_INTERNAL void ts_tree_node_unref(ts_tree_node_t* node); -WEPOLL_INTERNAL void ts_tree_node_unref_and_destroy(ts_tree_node_t* node); - -static ts_tree_t epoll__handle_tree; - -int epoll_global_init(void) -{ - ts_tree_init(&epoll__handle_tree); - return 0; -} - -static HANDLE epoll__create(void) -{ - port_state_t* port_state; - HANDLE ephnd; - ts_tree_node_t* tree_node; - - if (init() < 0) - return NULL; - - port_state = port_new(&ephnd); - if (port_state == NULL) - return NULL; - - tree_node = port_state_to_handle_tree_node(port_state); - if (ts_tree_add(&epoll__handle_tree, tree_node, (uintptr_t)ephnd) < 0) - { - /* This should never happen. */ - port_delete(port_state); - return_set_error(NULL, ERROR_ALREADY_EXISTS); - } - - return ephnd; -} - -HANDLE epoll_create(int size) -{ - if (size <= 0) - return_set_error(NULL, ERROR_INVALID_PARAMETER); - - return epoll__create(); -} - -HANDLE epoll_create1(int flags) -{ - if (flags != 0) - return_set_error(NULL, ERROR_INVALID_PARAMETER); - - return epoll__create(); -} - -int epoll_close(HANDLE ephnd) -{ - ts_tree_node_t* tree_node; - port_state_t* port_state; - - if (init() < 0) - return -1; - - tree_node = ts_tree_del_and_ref(&epoll__handle_tree, (uintptr_t)ephnd); - if (tree_node == NULL) - { - err_set_win_error(ERROR_INVALID_PARAMETER); - goto err; - } - - port_state = port_state_from_handle_tree_node(tree_node); - port_close(port_state); - - ts_tree_node_unref_and_destroy(tree_node); - - return port_delete(port_state); - -err: - err_check_handle(ephnd); - return -1; -} - -int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event* ev) -{ - ts_tree_node_t* tree_node; - port_state_t* port_state; - int r; - - if (init() < 0) - return -1; - - tree_node = ts_tree_find_and_ref(&epoll__handle_tree, (uintptr_t)ephnd); - if (tree_node == NULL) - { - err_set_win_error(ERROR_INVALID_PARAMETER); - goto err; - } - - port_state = port_state_from_handle_tree_node(tree_node); - r = port_ctl(port_state, op, sock, ev); - - ts_tree_node_unref(tree_node); - - if (r < 0) - goto err; - - return 0; - -err: - /* On Linux, in the case of epoll_ctl(), EBADF takes priority over other - * errors. Wepoll mimics this behavior. */ - err_check_handle(ephnd); - err_check_handle((HANDLE)sock); - return -1; -} - -int epoll_wait(HANDLE ephnd, - struct epoll_event* events, - int maxevents, - int timeout) -{ - ts_tree_node_t* tree_node; - port_state_t* port_state; - int num_events; - - if (maxevents <= 0) - return_set_error(-1, ERROR_INVALID_PARAMETER); - - if (init() < 0) - return -1; - - tree_node = ts_tree_find_and_ref(&epoll__handle_tree, (uintptr_t)ephnd); - if (tree_node == NULL) - { - err_set_win_error(ERROR_INVALID_PARAMETER); - goto err; - } - - port_state = port_state_from_handle_tree_node(tree_node); - num_events = port_wait(port_state, events, maxevents, timeout); - - ts_tree_node_unref(tree_node); - - if (num_events < 0) - goto err; - - return num_events; - -err: - err_check_handle(ephnd); - return -1; -} - -#include - -#define ERR__ERRNO_MAPPINGS(X) \ - X(ERROR_ACCESS_DENIED, EACCES) \ - X(ERROR_ALREADY_EXISTS, EEXIST) \ - X(ERROR_BAD_COMMAND, EACCES) \ - X(ERROR_BAD_EXE_FORMAT, ENOEXEC) \ - X(ERROR_BAD_LENGTH, EACCES) \ - X(ERROR_BAD_NETPATH, ENOENT) \ - X(ERROR_BAD_NET_NAME, ENOENT) \ - X(ERROR_BAD_NET_RESP, ENETDOWN) \ - X(ERROR_BAD_PATHNAME, ENOENT) \ - X(ERROR_BROKEN_PIPE, EPIPE) \ - X(ERROR_CANNOT_MAKE, EACCES) \ - X(ERROR_COMMITMENT_LIMIT, ENOMEM) \ - X(ERROR_CONNECTION_ABORTED, ECONNABORTED) \ - X(ERROR_CONNECTION_ACTIVE, EISCONN) \ - X(ERROR_CONNECTION_REFUSED, ECONNREFUSED) \ - X(ERROR_CRC, EACCES) \ - X(ERROR_DIR_NOT_EMPTY, ENOTEMPTY) \ - X(ERROR_DISK_FULL, ENOSPC) \ - X(ERROR_DUP_NAME, EADDRINUSE) \ - X(ERROR_FILENAME_EXCED_RANGE, ENOENT) \ - X(ERROR_FILE_NOT_FOUND, ENOENT) \ - X(ERROR_GEN_FAILURE, EACCES) \ - X(ERROR_GRACEFUL_DISCONNECT, EPIPE) \ - X(ERROR_HOST_DOWN, EHOSTUNREACH) \ - X(ERROR_HOST_UNREACHABLE, EHOSTUNREACH) \ - X(ERROR_INSUFFICIENT_BUFFER, EFAULT) \ - X(ERROR_INVALID_ADDRESS, EADDRNOTAVAIL) \ - X(ERROR_INVALID_FUNCTION, EINVAL) \ - X(ERROR_INVALID_HANDLE, EBADF) \ - X(ERROR_INVALID_NETNAME, EADDRNOTAVAIL) \ - X(ERROR_INVALID_PARAMETER, EINVAL) \ - X(ERROR_INVALID_USER_BUFFER, EMSGSIZE) \ - X(ERROR_IO_PENDING, EINPROGRESS) \ - X(ERROR_LOCK_VIOLATION, EACCES) \ - X(ERROR_MORE_DATA, EMSGSIZE) \ - X(ERROR_NETNAME_DELETED, ECONNABORTED) \ - X(ERROR_NETWORK_ACCESS_DENIED, EACCES) \ - X(ERROR_NETWORK_BUSY, ENETDOWN) \ - X(ERROR_NETWORK_UNREACHABLE, ENETUNREACH) \ - X(ERROR_NOACCESS, EFAULT) \ - X(ERROR_NONPAGED_SYSTEM_RESOURCES, ENOMEM) \ - X(ERROR_NOT_ENOUGH_MEMORY, ENOMEM) \ - X(ERROR_NOT_ENOUGH_QUOTA, ENOMEM) \ - X(ERROR_NOT_FOUND, ENOENT) \ - X(ERROR_NOT_LOCKED, EACCES) \ - X(ERROR_NOT_READY, EACCES) \ - X(ERROR_NOT_SAME_DEVICE, EXDEV) \ - X(ERROR_NOT_SUPPORTED, ENOTSUP) \ - X(ERROR_NO_MORE_FILES, ENOENT) \ - X(ERROR_NO_SYSTEM_RESOURCES, ENOMEM) \ - X(ERROR_OPERATION_ABORTED, EINTR) \ - X(ERROR_OUT_OF_PAPER, EACCES) \ - X(ERROR_PAGED_SYSTEM_RESOURCES, ENOMEM) \ - X(ERROR_PAGEFILE_QUOTA, ENOMEM) \ - X(ERROR_PATH_NOT_FOUND, ENOENT) \ - X(ERROR_PIPE_NOT_CONNECTED, EPIPE) \ - X(ERROR_PORT_UNREACHABLE, ECONNRESET) \ - X(ERROR_PROTOCOL_UNREACHABLE, ENETUNREACH) \ - X(ERROR_REM_NOT_LIST, ECONNREFUSED) \ - X(ERROR_REQUEST_ABORTED, EINTR) \ - X(ERROR_REQ_NOT_ACCEP, EWOULDBLOCK) \ - X(ERROR_SECTOR_NOT_FOUND, EACCES) \ - X(ERROR_SEM_TIMEOUT, ETIMEDOUT) \ - X(ERROR_SHARING_VIOLATION, EACCES) \ - X(ERROR_TOO_MANY_NAMES, ENOMEM) \ - X(ERROR_TOO_MANY_OPEN_FILES, EMFILE) \ - X(ERROR_UNEXP_NET_ERR, ECONNABORTED) \ - X(ERROR_WAIT_NO_CHILDREN, ECHILD) \ - X(ERROR_WORKING_SET_QUOTA, ENOMEM) \ - X(ERROR_WRITE_PROTECT, EACCES) \ - X(ERROR_WRONG_DISK, EACCES) \ - X(WSAEACCES, EACCES) \ - X(WSAEADDRINUSE, EADDRINUSE) \ - X(WSAEADDRNOTAVAIL, EADDRNOTAVAIL) \ - X(WSAEAFNOSUPPORT, EAFNOSUPPORT) \ - X(WSAECONNABORTED, ECONNABORTED) \ - X(WSAECONNREFUSED, ECONNREFUSED) \ - X(WSAECONNRESET, ECONNRESET) \ - X(WSAEDISCON, EPIPE) \ - X(WSAEFAULT, EFAULT) \ - X(WSAEHOSTDOWN, EHOSTUNREACH) \ - X(WSAEHOSTUNREACH, EHOSTUNREACH) \ - X(WSAEINPROGRESS, EBUSY) \ - X(WSAEINTR, EINTR) \ - X(WSAEINVAL, EINVAL) \ - X(WSAEISCONN, EISCONN) \ - X(WSAEMSGSIZE, EMSGSIZE) \ - X(WSAENETDOWN, ENETDOWN) \ - X(WSAENETRESET, EHOSTUNREACH) \ - X(WSAENETUNREACH, ENETUNREACH) \ - X(WSAENOBUFS, ENOMEM) \ - X(WSAENOTCONN, ENOTCONN) \ - X(WSAENOTSOCK, ENOTSOCK) \ - X(WSAEOPNOTSUPP, EOPNOTSUPP) \ - X(WSAEPROCLIM, ENOMEM) \ - X(WSAESHUTDOWN, EPIPE) \ - X(WSAETIMEDOUT, ETIMEDOUT) \ - X(WSAEWOULDBLOCK, EWOULDBLOCK) \ - X(WSANOTINITIALISED, ENETDOWN) \ - X(WSASYSNOTREADY, ENETDOWN) \ - X(WSAVERNOTSUPPORTED, ENOSYS) - -static errno_t err__map_win_error_to_errno(DWORD error) -{ - switch (error) - { -#define X(error_sym, errno_sym) \ - case error_sym: \ - return errno_sym; - ERR__ERRNO_MAPPINGS(X) -#undef X - } - return EINVAL; -} - -void err_map_win_error(void) -{ - errno = err__map_win_error_to_errno(GetLastError()); -} - -void err_set_win_error(DWORD error) -{ - SetLastError(error); - errno = err__map_win_error_to_errno(error); -} - -int err_check_handle(HANDLE handle) -{ - DWORD flags; - - /* GetHandleInformation() succeeds when passed INVALID_HANDLE_VALUE, so - * check for this condition explicitly. */ - if (handle == INVALID_HANDLE_VALUE) - return_set_error(-1, ERROR_INVALID_HANDLE); - - if (!GetHandleInformation(handle, &flags)) - return_map_error(-1); - - return 0; -} - -#include - -#define array_count(a) (sizeof(a) / (sizeof((a)[0]))) - -#define container_of(ptr, type, member) \ - ((type*)((uintptr_t)(ptr)-offsetof(type, member))) - -#define unused_var(v) ((void)(v)) - -/* Polyfill `inline` for older versions of msvc (up to Visual Studio 2013) */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -#define inline __inline -#endif - -WEPOLL_INTERNAL int ws_global_init(void); -WEPOLL_INTERNAL SOCKET ws_get_base_socket(SOCKET socket); - -static bool init__done = false; -static INIT_ONCE init__once = INIT_ONCE_STATIC_INIT; - -static BOOL CALLBACK init__once_callback(INIT_ONCE* once, - void* parameter, - void** context) -{ - unused_var(once); - unused_var(parameter); - unused_var(context); - - /* N.b. that initialization order matters here. */ - if (ws_global_init() < 0 || nt_global_init() < 0 || - reflock_global_init() < 0 || epoll_global_init() < 0) - return FALSE; - - init__done = true; - return TRUE; -} - -int init(void) -{ - if (!init__done && - !InitOnceExecuteOnce(&init__once, init__once_callback, NULL, NULL)) - /* `InitOnceExecuteOnce()` itself is infallible, and it doesn't set any - * error code when the once-callback returns FALSE. We return -1 here to - * indicate that global initialization failed; the failing init function - * is resposible for setting `errno` and calling `SetLastError()`. */ - return -1; - - return 0; -} - -/* Set up a workaround for the following problem: - * FARPROC addr = GetProcAddress(...); - * MY_FUNC func = (MY_FUNC) addr; <-- GCC 8 warning/error. - * MY_FUNC func = (MY_FUNC) (void*) addr; <-- MSVC warning/error. - * To compile cleanly with either compiler, do casts with this "bridge" type: - * MY_FUNC func = (MY_FUNC) (nt__fn_ptr_cast_t) addr; */ -#ifdef __GNUC__ -typedef void* nt__fn_ptr_cast_t; -#else -typedef FARPROC nt__fn_ptr_cast_t; -#endif - -#define X(return_type, attributes, name, parameters) \ - WEPOLL_INTERNAL return_type(attributes* name) parameters = NULL; -NT_NTDLL_IMPORT_LIST(X) -#undef X - -int nt_global_init(void) -{ - HMODULE ntdll; - FARPROC fn_ptr; - - ntdll = GetModuleHandleW(L"ntdll.dll"); - if (ntdll == NULL) - return -1; - -#define X(return_type, attributes, name, parameters) \ - fn_ptr = GetProcAddress(ntdll, #name); \ - if (fn_ptr == NULL) \ - return -1; \ - name = (return_type(attributes*) parameters)(nt__fn_ptr_cast_t)fn_ptr; - NT_NTDLL_IMPORT_LIST(X) -#undef X - - return 0; -} - -#include - -typedef struct poll_group poll_group_t; - -typedef struct queue_node queue_node_t; - -WEPOLL_INTERNAL poll_group_t* poll_group_acquire(port_state_t* port); -WEPOLL_INTERNAL void poll_group_release(poll_group_t* poll_group); - -WEPOLL_INTERNAL void poll_group_delete(poll_group_t* poll_group); - -WEPOLL_INTERNAL poll_group_t* poll_group_from_queue_node( - queue_node_t* queue_node); -WEPOLL_INTERNAL HANDLE -poll_group_get_afd_device_handle(poll_group_t* poll_group); - -typedef struct queue_node -{ - queue_node_t* prev; - queue_node_t* next; -} queue_node_t; - -typedef struct queue -{ - queue_node_t head; -} queue_t; - -WEPOLL_INTERNAL void queue_init(queue_t* queue); -WEPOLL_INTERNAL void queue_node_init(queue_node_t* node); - -WEPOLL_INTERNAL queue_node_t* queue_first(const queue_t* queue); -WEPOLL_INTERNAL queue_node_t* queue_last(const queue_t* queue); - -WEPOLL_INTERNAL void queue_prepend(queue_t* queue, queue_node_t* node); -WEPOLL_INTERNAL void queue_append(queue_t* queue, queue_node_t* node); -WEPOLL_INTERNAL void queue_move_to_start(queue_t* queue, queue_node_t* node); -WEPOLL_INTERNAL void queue_move_to_end(queue_t* queue, queue_node_t* node); -WEPOLL_INTERNAL void queue_remove(queue_node_t* node); - -WEPOLL_INTERNAL bool queue_is_empty(const queue_t* queue); -WEPOLL_INTERNAL bool queue_is_enqueued(const queue_node_t* node); - -#define POLL_GROUP__MAX_GROUP_SIZE 32 - -typedef struct poll_group -{ - port_state_t* port_state; - queue_node_t queue_node; - HANDLE afd_device_handle; - size_t group_size; -} poll_group_t; - -static poll_group_t* poll_group__new(port_state_t* port_state) -{ - HANDLE iocp_handle = port_get_iocp_handle(port_state); - queue_t* poll_group_queue = port_get_poll_group_queue(port_state); - - poll_group_t* poll_group = malloc(sizeof *poll_group); - if (poll_group == NULL) - return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY); - - memset(poll_group, 0, sizeof *poll_group); - - queue_node_init(&poll_group->queue_node); - poll_group->port_state = port_state; - - if (afd_create_device_handle(iocp_handle, &poll_group->afd_device_handle) < - 0) - { - free(poll_group); - return NULL; - } - - queue_append(poll_group_queue, &poll_group->queue_node); - - return poll_group; -} - -void poll_group_delete(poll_group_t* poll_group) -{ - assert(poll_group->group_size == 0); - CloseHandle(poll_group->afd_device_handle); - queue_remove(&poll_group->queue_node); - free(poll_group); -} - -poll_group_t* poll_group_from_queue_node(queue_node_t* queue_node) -{ - return container_of(queue_node, poll_group_t, queue_node); -} - -HANDLE poll_group_get_afd_device_handle(poll_group_t* poll_group) -{ - return poll_group->afd_device_handle; -} - -poll_group_t* poll_group_acquire(port_state_t* port_state) -{ - queue_t* poll_group_queue = port_get_poll_group_queue(port_state); - poll_group_t* poll_group = !queue_is_empty(poll_group_queue) - ? container_of(queue_last(poll_group_queue), - poll_group_t, - queue_node) - : NULL; - - if (poll_group == NULL || - poll_group->group_size >= POLL_GROUP__MAX_GROUP_SIZE) - poll_group = poll_group__new(port_state); - if (poll_group == NULL) - return NULL; - - if (++poll_group->group_size == POLL_GROUP__MAX_GROUP_SIZE) - queue_move_to_start(poll_group_queue, &poll_group->queue_node); - - return poll_group; -} - -void poll_group_release(poll_group_t* poll_group) -{ - port_state_t* port_state = poll_group->port_state; - queue_t* poll_group_queue = port_get_poll_group_queue(port_state); - - poll_group->group_size--; - assert(poll_group->group_size < POLL_GROUP__MAX_GROUP_SIZE); - - queue_move_to_end(poll_group_queue, &poll_group->queue_node); - - /* Poll groups are currently only freed when the epoll port is closed. */ -} - -WEPOLL_INTERNAL sock_state_t* sock_new(port_state_t* port_state, SOCKET socket); -WEPOLL_INTERNAL void sock_delete(port_state_t* port_state, - sock_state_t* sock_state); -WEPOLL_INTERNAL void sock_force_delete(port_state_t* port_state, - sock_state_t* sock_state); - -WEPOLL_INTERNAL int sock_set_event(port_state_t* port_state, - sock_state_t* sock_state, - const struct epoll_event* ev); - -WEPOLL_INTERNAL int sock_update(port_state_t* port_state, - sock_state_t* sock_state); -WEPOLL_INTERNAL int sock_feed_event(port_state_t* port_state, - IO_STATUS_BLOCK* io_status_block, - struct epoll_event* ev); - -WEPOLL_INTERNAL sock_state_t* sock_state_from_queue_node( - queue_node_t* queue_node); -WEPOLL_INTERNAL queue_node_t* sock_state_to_queue_node( - sock_state_t* sock_state); -WEPOLL_INTERNAL sock_state_t* sock_state_from_tree_node(tree_node_t* tree_node); -WEPOLL_INTERNAL tree_node_t* sock_state_to_tree_node(sock_state_t* sock_state); - -#define PORT__MAX_ON_STACK_COMPLETIONS 256 - -typedef struct port_state -{ - HANDLE iocp_handle; - tree_t sock_tree; - queue_t sock_update_queue; - queue_t sock_deleted_queue; - queue_t poll_group_queue; - ts_tree_node_t handle_tree_node; - CRITICAL_SECTION lock; - size_t active_poll_count; -} port_state_t; - -static inline port_state_t* port__alloc(void) -{ - port_state_t* port_state = malloc(sizeof *port_state); - if (port_state == NULL) - return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY); - - return port_state; -} - -static inline void port__free(port_state_t* port) -{ - assert(port != NULL); - free(port); -} - -static inline HANDLE port__create_iocp(void) -{ - HANDLE iocp_handle = - CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); - if (iocp_handle == NULL) - return_map_error(NULL); - - return iocp_handle; -} - -port_state_t* port_new(HANDLE* iocp_handle_out) -{ - port_state_t* port_state; - HANDLE iocp_handle; - - port_state = port__alloc(); - if (port_state == NULL) - goto err1; - - iocp_handle = port__create_iocp(); - if (iocp_handle == NULL) - goto err2; - - memset(port_state, 0, sizeof *port_state); - - port_state->iocp_handle = iocp_handle; - tree_init(&port_state->sock_tree); - queue_init(&port_state->sock_update_queue); - queue_init(&port_state->sock_deleted_queue); - queue_init(&port_state->poll_group_queue); - ts_tree_node_init(&port_state->handle_tree_node); - InitializeCriticalSection(&port_state->lock); - - *iocp_handle_out = iocp_handle; - return port_state; - -err2: - port__free(port_state); -err1: - return NULL; -} - -static inline int port__close_iocp(port_state_t* port_state) -{ - HANDLE iocp_handle = port_state->iocp_handle; - port_state->iocp_handle = NULL; - - if (!CloseHandle(iocp_handle)) - return_map_error(-1); - - return 0; -} - -int port_close(port_state_t* port_state) -{ - int result; - - EnterCriticalSection(&port_state->lock); - result = port__close_iocp(port_state); - LeaveCriticalSection(&port_state->lock); - - return result; -} - -int port_delete(port_state_t* port_state) -{ - tree_node_t* tree_node; - queue_node_t* queue_node; - - /* At this point the IOCP port should have been closed. */ - assert(port_state->iocp_handle == NULL); - - while ((tree_node = tree_root(&port_state->sock_tree)) != NULL) - { - sock_state_t* sock_state = sock_state_from_tree_node(tree_node); - sock_force_delete(port_state, sock_state); - } - - while ((queue_node = queue_first(&port_state->sock_deleted_queue)) != NULL) - { - sock_state_t* sock_state = sock_state_from_queue_node(queue_node); - sock_force_delete(port_state, sock_state); - } - - while ((queue_node = queue_first(&port_state->poll_group_queue)) != NULL) - { - poll_group_t* poll_group = poll_group_from_queue_node(queue_node); - poll_group_delete(poll_group); - } - - assert(queue_is_empty(&port_state->sock_update_queue)); - - DeleteCriticalSection(&port_state->lock); - - port__free(port_state); - - return 0; -} - -static int port__update_events(port_state_t* port_state) -{ - queue_t* sock_update_queue = &port_state->sock_update_queue; - - /* Walk the queue, submitting new poll requests for every socket that needs - * it. */ - while (!queue_is_empty(sock_update_queue)) - { - queue_node_t* queue_node = queue_first(sock_update_queue); - sock_state_t* sock_state = sock_state_from_queue_node(queue_node); - - if (sock_update(port_state, sock_state) < 0) - return -1; - - /* sock_update() removes the socket from the update queue. */ - } - - return 0; -} - -static inline void port__update_events_if_polling(port_state_t* port_state) -{ - if (port_state->active_poll_count > 0) - port__update_events(port_state); -} - -static inline int port__feed_events(port_state_t* port_state, - struct epoll_event* epoll_events, - OVERLAPPED_ENTRY* iocp_events, - DWORD iocp_event_count) -{ - int epoll_event_count = 0; - DWORD i; - - for (i = 0; i < iocp_event_count; i++) - { - if (iocp_events[i].lpCompletionKey) - { - struct epoll_event* ev = &epoll_events[epoll_event_count++]; - ev->data.u64 = (uint64_t)iocp_events[i].lpCompletionKey; - ev->events = EPOLLEVENT; - continue; - } - IO_STATUS_BLOCK* io_status_block = - (IO_STATUS_BLOCK*)iocp_events[i].lpOverlapped; - struct epoll_event* ev = &epoll_events[epoll_event_count]; - - epoll_event_count += sock_feed_event(port_state, io_status_block, ev); - } - - return epoll_event_count; -} - -static inline int port__poll(port_state_t* port_state, - struct epoll_event* epoll_events, - OVERLAPPED_ENTRY* iocp_events, - DWORD maxevents, - DWORD timeout) -{ - DWORD completion_count; - - if (port__update_events(port_state) < 0) - return -1; - - port_state->active_poll_count++; - - LeaveCriticalSection(&port_state->lock); - - BOOL r = GetQueuedCompletionStatusEx(port_state->iocp_handle, - iocp_events, - maxevents, - &completion_count, - timeout, - FALSE); - - EnterCriticalSection(&port_state->lock); - - port_state->active_poll_count--; - - if (!r) - return_map_error(-1); - - return port__feed_events(port_state, - epoll_events, - iocp_events, - completion_count); -} - -int port_wait(port_state_t* port_state, - struct epoll_event* events, - int maxevents, - int timeout) -{ - OVERLAPPED_ENTRY stack_iocp_events[PORT__MAX_ON_STACK_COMPLETIONS]; - OVERLAPPED_ENTRY* iocp_events; - uint64_t due = 0; - DWORD gqcs_timeout; - int result; - - /* Check whether `maxevents` is in range. */ - if (maxevents <= 0) - return_set_error(-1, ERROR_INVALID_PARAMETER); - - /* Decide whether the IOCP completion list can live on the stack, or - * allocate memory for it on the heap. */ - if ((size_t)maxevents <= array_count(stack_iocp_events)) - { - iocp_events = stack_iocp_events; - } - else if ((iocp_events = malloc((size_t)maxevents * sizeof *iocp_events)) == - NULL) - { - iocp_events = stack_iocp_events; - maxevents = array_count(stack_iocp_events); - } - - /* Compute the timeout for GetQueuedCompletionStatus, and the wait end - * time, if the user specified a timeout other than zero or infinite. */ - if (timeout > 0) - { - due = GetTickCount64() + (uint64_t)timeout; - gqcs_timeout = (DWORD)timeout; - } - else if (timeout == 0) - { - gqcs_timeout = 0; - } - else - { - gqcs_timeout = INFINITE; - } - - EnterCriticalSection(&port_state->lock); - - /* Dequeue completion packets until either at least one interesting event - * has been discovered, or the timeout is reached. */ - for (;;) - { - uint64_t now; - - result = port__poll( - port_state, events, iocp_events, (DWORD)maxevents, gqcs_timeout); - if (result < 0 || result > 0) - break; /* Result, error, or time-out. */ - - if (timeout < 0) - continue; /* When timeout is negative, never time out. */ - - /* Update time. */ - now = GetTickCount64(); - - /* Do not allow the due time to be in the past. */ - if (now >= due) - { - SetLastError(WAIT_TIMEOUT); - break; - } - - /* Recompute time-out argument for GetQueuedCompletionStatus. */ - gqcs_timeout = (DWORD)(due - now); - } - - port__update_events_if_polling(port_state); - - LeaveCriticalSection(&port_state->lock); - - if (iocp_events != stack_iocp_events) - free(iocp_events); - - if (result >= 0) - return result; - else if (GetLastError() == WAIT_TIMEOUT) - return 0; - else - return -1; -} - -static inline int port__ctl_add(port_state_t* port_state, - SOCKET sock, - struct epoll_event* ev) -{ - sock_state_t* sock_state = sock_new(port_state, sock); - if (sock_state == NULL) - return -1; - - if (sock_set_event(port_state, sock_state, ev) < 0) - { - sock_delete(port_state, sock_state); - return -1; - } - - port__update_events_if_polling(port_state); - - return 0; -} - -static inline int port__ctl_mod(port_state_t* port_state, - SOCKET sock, - struct epoll_event* ev) -{ - sock_state_t* sock_state = port_find_socket(port_state, sock); - if (sock_state == NULL) - return -1; - - if (sock_set_event(port_state, sock_state, ev) < 0) - return -1; - - port__update_events_if_polling(port_state); - - return 0; -} - -static inline int port__ctl_del(port_state_t* port_state, SOCKET sock) -{ - sock_state_t* sock_state = port_find_socket(port_state, sock); - if (sock_state == NULL) - return -1; - - sock_delete(port_state, sock_state); - - return 0; -} - -static inline int port__ctl_op(port_state_t* port_state, - int op, - SOCKET sock, - struct epoll_event* ev) -{ - switch (op) - { - case EPOLL_CTL_ADD: - return port__ctl_add(port_state, sock, ev); - case EPOLL_CTL_MOD: - return port__ctl_mod(port_state, sock, ev); - case EPOLL_CTL_DEL: - return port__ctl_del(port_state, sock); - default: - return_set_error(-1, ERROR_INVALID_PARAMETER); - } -} - -int port_ctl(port_state_t* port_state, - int op, - SOCKET sock, - struct epoll_event* ev) -{ - int result; - - EnterCriticalSection(&port_state->lock); - result = port__ctl_op(port_state, op, sock, ev); - LeaveCriticalSection(&port_state->lock); - - return result; -} - -int port_register_socket(port_state_t* port_state, - sock_state_t* sock_state, - SOCKET socket) -{ - if (tree_add(&port_state->sock_tree, - sock_state_to_tree_node(sock_state), - socket) < 0) - return_set_error(-1, ERROR_ALREADY_EXISTS); - return 0; -} - -void port_unregister_socket(port_state_t* port_state, sock_state_t* sock_state) -{ - tree_del(&port_state->sock_tree, sock_state_to_tree_node(sock_state)); -} - -sock_state_t* port_find_socket(port_state_t* port_state, SOCKET socket) -{ - tree_node_t* tree_node = tree_find(&port_state->sock_tree, socket); - if (tree_node == NULL) - return_set_error(NULL, ERROR_NOT_FOUND); - return sock_state_from_tree_node(tree_node); -} - -void port_request_socket_update(port_state_t* port_state, - sock_state_t* sock_state) -{ - if (queue_is_enqueued(sock_state_to_queue_node(sock_state))) - return; - queue_append(&port_state->sock_update_queue, - sock_state_to_queue_node(sock_state)); -} - -void port_cancel_socket_update(port_state_t* port_state, - sock_state_t* sock_state) -{ - unused_var(port_state); - if (!queue_is_enqueued(sock_state_to_queue_node(sock_state))) - return; - queue_remove(sock_state_to_queue_node(sock_state)); -} - -void port_add_deleted_socket(port_state_t* port_state, sock_state_t* sock_state) -{ - if (queue_is_enqueued(sock_state_to_queue_node(sock_state))) - return; - queue_append(&port_state->sock_deleted_queue, - sock_state_to_queue_node(sock_state)); -} - -void port_remove_deleted_socket(port_state_t* port_state, - sock_state_t* sock_state) -{ - unused_var(port_state); - if (!queue_is_enqueued(sock_state_to_queue_node(sock_state))) - return; - queue_remove(sock_state_to_queue_node(sock_state)); -} - -HANDLE port_get_iocp_handle(port_state_t* port_state) -{ - assert(port_state->iocp_handle != NULL); - return port_state->iocp_handle; -} - -queue_t* port_get_poll_group_queue(port_state_t* port_state) -{ - return &port_state->poll_group_queue; -} - -port_state_t* port_state_from_handle_tree_node(ts_tree_node_t* tree_node) -{ - return container_of(tree_node, port_state_t, handle_tree_node); -} - -ts_tree_node_t* port_state_to_handle_tree_node(port_state_t* port_state) -{ - return &port_state->handle_tree_node; -} - -void queue_init(queue_t* queue) -{ - queue_node_init(&queue->head); -} - -void queue_node_init(queue_node_t* node) -{ - node->prev = node; - node->next = node; -} - -static inline void queue__detach_node(queue_node_t* node) -{ - node->prev->next = node->next; - node->next->prev = node->prev; -} - -queue_node_t* queue_first(const queue_t* queue) -{ - return !queue_is_empty(queue) ? queue->head.next : NULL; -} - -queue_node_t* queue_last(const queue_t* queue) -{ - return !queue_is_empty(queue) ? queue->head.prev : NULL; -} - -void queue_prepend(queue_t* queue, queue_node_t* node) -{ - node->next = queue->head.next; - node->prev = &queue->head; - node->next->prev = node; - queue->head.next = node; -} - -void queue_append(queue_t* queue, queue_node_t* node) -{ - node->next = &queue->head; - node->prev = queue->head.prev; - node->prev->next = node; - queue->head.prev = node; -} - -void queue_move_to_start(queue_t* queue, queue_node_t* node) -{ - queue__detach_node(node); - queue_prepend(queue, node); -} - -void queue_move_to_end(queue_t* queue, queue_node_t* node) -{ - queue__detach_node(node); - queue_append(queue, node); -} - -void queue_remove(queue_node_t* node) -{ - queue__detach_node(node); - queue_node_init(node); -} - -bool queue_is_empty(const queue_t* queue) -{ - return !queue_is_enqueued(&queue->head); -} - -bool queue_is_enqueued(const queue_node_t* node) -{ - return node->prev != node; -} - -#define REFLOCK__REF ((long)0x00000001UL) -#define REFLOCK__REF_MASK ((long)0x0fffffffUL) -#define REFLOCK__DESTROY ((long)0x10000000UL) -#define REFLOCK__DESTROY_MASK ((long)0xf0000000UL) -#define REFLOCK__POISON ((long)0x300dead0UL) - -static HANDLE reflock__keyed_event = NULL; - -int reflock_global_init(void) -{ - NTSTATUS status = NtCreateKeyedEvent(&reflock__keyed_event, - KEYEDEVENT_ALL_ACCESS, - NULL, - 0); - if (status != STATUS_SUCCESS) - return_set_error(-1, RtlNtStatusToDosError(status)); - return 0; -} - -void reflock_init(reflock_t* reflock) -{ - reflock->state = 0; -} - -static void reflock__signal_event(void* address) -{ - NTSTATUS status = - NtReleaseKeyedEvent(reflock__keyed_event, address, FALSE, NULL); - if (status != STATUS_SUCCESS) - abort(); -} - -static void reflock__await_event(void* address) -{ - NTSTATUS status = - NtWaitForKeyedEvent(reflock__keyed_event, address, FALSE, NULL); - if (status != STATUS_SUCCESS) - abort(); -} - -void reflock_ref(reflock_t* reflock) -{ - long state = InterlockedAdd(&reflock->state, REFLOCK__REF); - - /* Verify that the counter didn't overflow and the lock isn't destroyed. */ - assert((state & REFLOCK__DESTROY_MASK) == 0); - unused_var(state); -} - -void reflock_unref(reflock_t* reflock) -{ - long state = InterlockedAdd(&reflock->state, -REFLOCK__REF); - - /* Verify that the lock was referenced and not already destroyed. */ - assert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0); - - if (state == REFLOCK__DESTROY) - reflock__signal_event(reflock); -} - -void reflock_unref_and_destroy(reflock_t* reflock) -{ - long state = - InterlockedAdd(&reflock->state, REFLOCK__DESTROY - REFLOCK__REF); - long ref_count = state & REFLOCK__REF_MASK; - - /* Verify that the lock was referenced and not already destroyed. */ - assert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY); - - if (ref_count != 0) - reflock__await_event(reflock); - - state = InterlockedExchange(&reflock->state, REFLOCK__POISON); - assert(state == REFLOCK__DESTROY); -} - -#define SOCK__KNOWN_EPOLL_EVENTS \ - (EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM | \ - EPOLLRDBAND | EPOLLWRNORM | EPOLLWRBAND | EPOLLMSG | EPOLLRDHUP) - -typedef enum sock__poll_status -{ - SOCK__POLL_IDLE = 0, - SOCK__POLL_PENDING, - SOCK__POLL_CANCELLED -} sock__poll_status_t; - -typedef struct sock_state -{ - IO_STATUS_BLOCK io_status_block; - AFD_POLL_INFO poll_info; - queue_node_t queue_node; - tree_node_t tree_node; - poll_group_t* poll_group; - SOCKET base_socket; - epoll_data_t user_data; - uint32_t user_events; - uint32_t pending_events; - sock__poll_status_t poll_status; - bool delete_pending; -} sock_state_t; - -static inline sock_state_t* sock__alloc(void) -{ - sock_state_t* sock_state = malloc(sizeof *sock_state); - if (sock_state == NULL) - return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY); - return sock_state; -} - -static inline void sock__free(sock_state_t* sock_state) -{ - assert(sock_state != NULL); - free(sock_state); -} - -static inline int sock__cancel_poll(sock_state_t* sock_state) -{ - assert(sock_state->poll_status == SOCK__POLL_PENDING); - - if (afd_cancel_poll(poll_group_get_afd_device_handle( - sock_state->poll_group), - &sock_state->io_status_block) < 0) - return -1; - - sock_state->poll_status = SOCK__POLL_CANCELLED; - sock_state->pending_events = 0; - return 0; -} - -sock_state_t* sock_new(port_state_t* port_state, SOCKET socket) -{ - SOCKET base_socket; - poll_group_t* poll_group; - sock_state_t* sock_state; - - if (socket == 0 || socket == INVALID_SOCKET) - return_set_error(NULL, ERROR_INVALID_HANDLE); - - base_socket = ws_get_base_socket(socket); - if (base_socket == INVALID_SOCKET) - return NULL; - - poll_group = poll_group_acquire(port_state); - if (poll_group == NULL) - return NULL; - - sock_state = sock__alloc(); - if (sock_state == NULL) - goto err1; - - memset(sock_state, 0, sizeof *sock_state); - - sock_state->base_socket = base_socket; - sock_state->poll_group = poll_group; - - tree_node_init(&sock_state->tree_node); - queue_node_init(&sock_state->queue_node); - - if (port_register_socket(port_state, sock_state, socket) < 0) - goto err2; - - return sock_state; - -err2: - sock__free(sock_state); -err1: - poll_group_release(poll_group); - - return NULL; -} - -static int sock__delete(port_state_t* port_state, - sock_state_t* sock_state, - bool force) -{ - if (!sock_state->delete_pending) - { - if (sock_state->poll_status == SOCK__POLL_PENDING) - sock__cancel_poll(sock_state); - - port_cancel_socket_update(port_state, sock_state); - port_unregister_socket(port_state, sock_state); - - sock_state->delete_pending = true; - } - - /* If the poll request still needs to complete, the sock_state object can't - * be free()d yet. `sock_feed_event()` or `port_close()` will take care - * of this later. */ - if (force || sock_state->poll_status == SOCK__POLL_IDLE) - { - /* Free the sock_state now. */ - port_remove_deleted_socket(port_state, sock_state); - poll_group_release(sock_state->poll_group); - sock__free(sock_state); - } - else - { - /* Free the socket later. */ - port_add_deleted_socket(port_state, sock_state); - } - - return 0; -} - -void sock_delete(port_state_t* port_state, sock_state_t* sock_state) -{ - sock__delete(port_state, sock_state, false); -} - -void sock_force_delete(port_state_t* port_state, sock_state_t* sock_state) -{ - sock__delete(port_state, sock_state, true); -} - -int sock_set_event(port_state_t* port_state, - sock_state_t* sock_state, - const struct epoll_event* ev) -{ - /* EPOLLERR and EPOLLHUP are always reported, even when not requested by the - * caller. However they are disabled after a event has been reported for a - * socket for which the EPOLLONESHOT flag was set. */ - uint32_t events = ev->events | EPOLLERR | EPOLLHUP; - - sock_state->user_events = events; - sock_state->user_data = ev->data; - - if ((events & SOCK__KNOWN_EPOLL_EVENTS & ~sock_state->pending_events) != 0) - port_request_socket_update(port_state, sock_state); - - return 0; -} - -static inline DWORD sock__epoll_events_to_afd_events(uint32_t epoll_events) -{ - /* Always monitor for AFD_POLL_LOCAL_CLOSE, which is triggered when the - * socket is closed with closesocket() or CloseHandle(). */ - DWORD afd_events = AFD_POLL_LOCAL_CLOSE; - - if (epoll_events & (EPOLLIN | EPOLLRDNORM)) - afd_events |= AFD_POLL_RECEIVE | AFD_POLL_ACCEPT; - if (epoll_events & (EPOLLPRI | EPOLLRDBAND)) - afd_events |= AFD_POLL_RECEIVE_EXPEDITED; - if (epoll_events & (EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND)) - afd_events |= AFD_POLL_SEND; - if (epoll_events & (EPOLLIN | EPOLLRDNORM | EPOLLRDHUP)) - afd_events |= AFD_POLL_DISCONNECT; - if (epoll_events & EPOLLHUP) - afd_events |= AFD_POLL_ABORT; - if (epoll_events & EPOLLERR) - afd_events |= AFD_POLL_CONNECT_FAIL; - - return afd_events; -} - -static inline uint32_t sock__afd_events_to_epoll_events(DWORD afd_events) -{ - uint32_t epoll_events = 0; - - if (afd_events & (AFD_POLL_RECEIVE | AFD_POLL_ACCEPT)) - epoll_events |= EPOLLIN | EPOLLRDNORM; - if (afd_events & AFD_POLL_RECEIVE_EXPEDITED) - epoll_events |= EPOLLPRI | EPOLLRDBAND; - if (afd_events & AFD_POLL_SEND) - epoll_events |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; - if (afd_events & AFD_POLL_DISCONNECT) - epoll_events |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; - if (afd_events & AFD_POLL_ABORT) - epoll_events |= EPOLLHUP; - if (afd_events & AFD_POLL_CONNECT_FAIL) - /* Linux reports all these events after connect() has failed. */ - epoll_events |= EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLRDNORM | - EPOLLWRNORM | EPOLLRDHUP; - - return epoll_events; -} - -int sock_update(port_state_t* port_state, sock_state_t* sock_state) -{ - assert(!sock_state->delete_pending); - - if ((sock_state->poll_status == SOCK__POLL_PENDING) && - (sock_state->user_events & SOCK__KNOWN_EPOLL_EVENTS & - ~sock_state->pending_events) == 0) - { - /* All the events the user is interested in are already being monitored - * by the pending poll operation. It might spuriously complete because - * of an event that we're no longer interested in; when that happens - * we'll submit a new poll operation with the updated event mask. */ - } - else if (sock_state->poll_status == SOCK__POLL_PENDING) - { - /* A poll operation is already pending, but it's not monitoring for all - * the events that the user is interested in. Therefore, cancel the - * pending poll operation; when we receive it's completion package, a - * new poll operation will be submitted with the correct event mask. */ - if (sock__cancel_poll(sock_state) < 0) - return -1; - } - else if (sock_state->poll_status == SOCK__POLL_CANCELLED) - { - /* The poll operation has already been cancelled, we're still waiting - * for it to return. For now, there's nothing that needs to be done. */ - } - else if (sock_state->poll_status == SOCK__POLL_IDLE) - { - /* No poll operation is pending; start one. */ - sock_state->poll_info.Exclusive = FALSE; - sock_state->poll_info.NumberOfHandles = 1; - sock_state->poll_info.Timeout.QuadPart = INT64_MAX; - sock_state->poll_info.Handles[0].Handle = - (HANDLE)sock_state->base_socket; - sock_state->poll_info.Handles[0].Status = 0; - sock_state->poll_info.Handles[0].Events = - sock__epoll_events_to_afd_events(sock_state->user_events); - - if (afd_poll(poll_group_get_afd_device_handle(sock_state->poll_group), - &sock_state->poll_info, - &sock_state->io_status_block) < 0) - { - switch (GetLastError()) - { - case ERROR_IO_PENDING: - /* Overlapped poll operation in progress; this is expected. - */ - break; - case ERROR_INVALID_HANDLE: - /* Socket closed; it'll be dropped from the epoll set. */ - return sock__delete(port_state, sock_state, false); - default: - /* Other errors are propagated to the caller. */ - return_map_error(-1); - } - } - - /* The poll request was successfully submitted. */ - sock_state->poll_status = SOCK__POLL_PENDING; - sock_state->pending_events = sock_state->user_events; - } - else - { - /* Unreachable. */ - assert(false); - } - - port_cancel_socket_update(port_state, sock_state); - return 0; -} - -int sock_feed_event(port_state_t* port_state, - IO_STATUS_BLOCK* io_status_block, - struct epoll_event* ev) -{ - sock_state_t* sock_state = - container_of(io_status_block, sock_state_t, io_status_block); - AFD_POLL_INFO* poll_info = &sock_state->poll_info; - uint32_t epoll_events = 0; - - sock_state->poll_status = SOCK__POLL_IDLE; - sock_state->pending_events = 0; - - if (sock_state->delete_pending) - { - /* Socket has been deleted earlier and can now be freed. */ - return sock__delete(port_state, sock_state, false); - } - else if (io_status_block->Status == STATUS_CANCELLED) - { - /* The poll request was cancelled by CancelIoEx. */ - } - else if (!NT_SUCCESS(io_status_block->Status)) - { - /* The overlapped request itself failed in an unexpected way. */ - epoll_events = EPOLLERR; - } - else if (poll_info->NumberOfHandles < 1) - { - /* This poll operation succeeded but didn't report any socket events. */ - } - else if (poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) - { - /* The poll operation reported that the socket was closed. */ - return sock__delete(port_state, sock_state, false); - } - else - { - /* Events related to our socket were reported. */ - epoll_events = - sock__afd_events_to_epoll_events(poll_info->Handles[0].Events); - } - - /* Requeue the socket so a new poll request will be submitted. */ - port_request_socket_update(port_state, sock_state); - - /* Filter out events that the user didn't ask for. */ - epoll_events &= sock_state->user_events; - - /* Return if there are no epoll events to report. */ - if (epoll_events == 0) - return 0; - - /* If the the socket has the EPOLLONESHOT flag set, unmonitor all events, - * even EPOLLERR and EPOLLHUP. But always keep looking for closed sockets. - */ - if (sock_state->user_events & EPOLLONESHOT) - sock_state->user_events = 0; - - ev->data = sock_state->user_data; - ev->events = epoll_events; - return 1; -} - -sock_state_t* sock_state_from_queue_node(queue_node_t* queue_node) -{ - return container_of(queue_node, sock_state_t, queue_node); -} - -queue_node_t* sock_state_to_queue_node(sock_state_t* sock_state) -{ - return &sock_state->queue_node; -} - -sock_state_t* sock_state_from_tree_node(tree_node_t* tree_node) -{ - return container_of(tree_node, sock_state_t, tree_node); -} - -tree_node_t* sock_state_to_tree_node(sock_state_t* sock_state) -{ - return &sock_state->tree_node; -} - -void ts_tree_init(ts_tree_t* ts_tree) -{ - tree_init(&ts_tree->tree); - InitializeSRWLock(&ts_tree->lock); -} - -void ts_tree_node_init(ts_tree_node_t* node) -{ - tree_node_init(&node->tree_node); - reflock_init(&node->reflock); -} - -int ts_tree_add(ts_tree_t* ts_tree, ts_tree_node_t* node, uintptr_t key) -{ - int r; - - AcquireSRWLockExclusive(&ts_tree->lock); - r = tree_add(&ts_tree->tree, &node->tree_node, key); - ReleaseSRWLockExclusive(&ts_tree->lock); - - return r; -} - -static inline ts_tree_node_t* ts_tree__find_node(ts_tree_t* ts_tree, - uintptr_t key) -{ - tree_node_t* tree_node = tree_find(&ts_tree->tree, key); - if (tree_node == NULL) - return NULL; - - return container_of(tree_node, ts_tree_node_t, tree_node); -} - -ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree, uintptr_t key) -{ - ts_tree_node_t* ts_tree_node; - - AcquireSRWLockExclusive(&ts_tree->lock); - - ts_tree_node = ts_tree__find_node(ts_tree, key); - if (ts_tree_node != NULL) - { - tree_del(&ts_tree->tree, &ts_tree_node->tree_node); - reflock_ref(&ts_tree_node->reflock); - } - - ReleaseSRWLockExclusive(&ts_tree->lock); - - return ts_tree_node; -} - -ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree, uintptr_t key) -{ - ts_tree_node_t* ts_tree_node; - - AcquireSRWLockShared(&ts_tree->lock); - - ts_tree_node = ts_tree__find_node(ts_tree, key); - if (ts_tree_node != NULL) - reflock_ref(&ts_tree_node->reflock); - - ReleaseSRWLockShared(&ts_tree->lock); - - return ts_tree_node; -} - -void ts_tree_node_unref(ts_tree_node_t* node) -{ - reflock_unref(&node->reflock); -} - -void ts_tree_node_unref_and_destroy(ts_tree_node_t* node) -{ - reflock_unref_and_destroy(&node->reflock); -} - -void tree_init(tree_t* tree) -{ - memset(tree, 0, sizeof *tree); -} - -void tree_node_init(tree_node_t* node) -{ - memset(node, 0, sizeof *node); -} - -#define TREE__ROTATE(cis, trans) \ - tree_node_t* p = node; \ - tree_node_t* q = node->trans; \ - tree_node_t* parent = p->parent; \ - \ - if (parent) \ - { \ - if (parent->left == p) \ - parent->left = q; \ - else \ - parent->right = q; \ - } \ - else \ - { \ - tree->root = q; \ - } \ - \ - q->parent = parent; \ - p->parent = q; \ - p->trans = q->cis; \ - if (p->trans) \ - p->trans->parent = p; \ - q->cis = p; - -static inline void tree__rotate_left(tree_t* tree, tree_node_t* node) -{ - TREE__ROTATE(left, right) -} - -static inline void tree__rotate_right(tree_t* tree, tree_node_t* node) -{ - TREE__ROTATE(right, left) -} - -#define TREE__INSERT_OR_DESCEND(side) \ - if (parent->side) \ - { \ - parent = parent->side; \ - } \ - else \ - { \ - parent->side = node; \ - break; \ - } - -#define TREE__REBALANCE_AFTER_INSERT(cis, trans) \ - tree_node_t* grandparent = parent->parent; \ - tree_node_t* uncle = grandparent->trans; \ - \ - if (uncle && uncle->red) \ - { \ - parent->red = uncle->red = false; \ - grandparent->red = true; \ - node = grandparent; \ - } \ - else \ - { \ - if (node == parent->trans) \ - { \ - tree__rotate_##cis(tree, parent); \ - node = parent; \ - parent = node->parent; \ - } \ - parent->red = false; \ - grandparent->red = true; \ - tree__rotate_##trans(tree, grandparent); \ - } - -int tree_add(tree_t* tree, tree_node_t* node, uintptr_t key) -{ - tree_node_t* parent; - - parent = tree->root; - if (parent) - { - for (;;) - { - if (key < parent->key) - { - TREE__INSERT_OR_DESCEND(left) - } - else if (key > parent->key) - { - TREE__INSERT_OR_DESCEND(right) - } - else - { - return -1; - } - } - } - else - { - tree->root = node; - } - - node->key = key; - node->left = node->right = NULL; - node->parent = parent; - node->red = true; - - for (; parent && parent->red; parent = node->parent) - { - if (parent == parent->parent->left) - { - TREE__REBALANCE_AFTER_INSERT(left, right) - } - else - { - TREE__REBALANCE_AFTER_INSERT(right, left) - } - } - tree->root->red = false; - - return 0; -} - -#define TREE__REBALANCE_AFTER_REMOVE(cis, trans) \ - tree_node_t* sibling = parent->trans; \ - \ - if (sibling->red) \ - { \ - sibling->red = false; \ - parent->red = true; \ - tree__rotate_##cis(tree, parent); \ - sibling = parent->trans; \ - } \ - if ((sibling->left && sibling->left->red) || \ - (sibling->right && sibling->right->red)) \ - { \ - if (!sibling->trans || !sibling->trans->red) \ - { \ - sibling->cis->red = false; \ - sibling->red = true; \ - tree__rotate_##trans(tree, sibling); \ - sibling = parent->trans; \ - } \ - sibling->red = parent->red; \ - parent->red = sibling->trans->red = false; \ - tree__rotate_##cis(tree, parent); \ - node = tree->root; \ - break; \ - } \ - sibling->red = true; - -void tree_del(tree_t* tree, tree_node_t* node) -{ - tree_node_t* parent = node->parent; - tree_node_t* left = node->left; - tree_node_t* right = node->right; - tree_node_t* next; - bool red; - - if (!left) - { - next = right; - } - else if (!right) - { - next = left; - } - else - { - next = right; - while (next->left) - next = next->left; - } - - if (parent) - { - if (parent->left == node) - parent->left = next; - else - parent->right = next; - } - else - { - tree->root = next; - } - - if (left && right) - { - red = next->red; - next->red = node->red; - next->left = left; - left->parent = next; - if (next != right) - { - parent = next->parent; - next->parent = node->parent; - node = next->right; - parent->left = node; - next->right = right; - right->parent = next; - } - else - { - next->parent = parent; - parent = next; - node = next->right; - } - } - else - { - red = node->red; - node = next; - } - - if (node) - node->parent = parent; - if (red) - return; - if (node && node->red) - { - node->red = false; - return; - } - - do - { - if (node == tree->root) - break; - if (node == parent->left) - { - TREE__REBALANCE_AFTER_REMOVE(left, right) - } - else - { - TREE__REBALANCE_AFTER_REMOVE(right, left) - } - node = parent; - parent = parent->parent; - } while (!node->red); - - if (node) - node->red = false; -} - -tree_node_t* tree_find(const tree_t* tree, uintptr_t key) -{ - tree_node_t* node = tree->root; - while (node) - { - if (key < node->key) - node = node->left; - else if (key > node->key) - node = node->right; - else - return node; - } - return NULL; -} - -tree_node_t* tree_root(const tree_t* tree) -{ - return tree->root; -} - -#ifndef SIO_BSP_HANDLE_POLL -#define SIO_BSP_HANDLE_POLL 0x4800001D -#endif - -#ifndef SIO_BASE_HANDLE -#define SIO_BASE_HANDLE 0x48000022 -#endif - -int ws_global_init(void) -{ - int r; - WSADATA wsa_data; - - r = WSAStartup(MAKEWORD(2, 2), &wsa_data); - if (r != 0) - return_set_error(-1, (DWORD)r); - - return 0; -} - -static inline SOCKET ws__ioctl_get_bsp_socket(SOCKET socket, DWORD ioctl) -{ - SOCKET bsp_socket; - DWORD bytes; - - if (WSAIoctl(socket, - ioctl, - NULL, - 0, - &bsp_socket, - sizeof bsp_socket, - &bytes, - NULL, - NULL) != SOCKET_ERROR) - return bsp_socket; - else - return INVALID_SOCKET; -} - -void epoll_post_signal(HANDLE port_handle, uint64_t event) -{ - ULONG_PTR ev; - ev = (ULONG_PTR)event; - PostQueuedCompletionStatus(port_handle, 1, ev, NULL); -} - -SOCKET ws_get_base_socket(SOCKET socket) -{ - SOCKET base_socket; - DWORD error; - - for (;;) - { - base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BASE_HANDLE); - if (base_socket != INVALID_SOCKET) - return base_socket; - - error = GetLastError(); - if (error == WSAENOTSOCK) - return_set_error(INVALID_SOCKET, error); - - /* Even though Microsoft documentation clearly states that LSPs should - * never intercept the `SIO_BASE_HANDLE` ioctl [1], Komodia based LSPs - * do so anyway, breaking it, with the apparent intention of preventing - * LSP bypass [2]. Fortunately they don't handle `SIO_BSP_HANDLE_POLL`, - * which will at least let us obtain the socket associated with the next - * winsock protocol chain entry. If this succeeds, loop around and call - * `SIO_BASE_HANDLE` again with the returned BSP socket, to make sure - * that we unwrap all layers and retrieve the actual base socket. [1] - * https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls - * [2] - * https://www.komodia.com/newwiki/index.php?title=Komodia%27s_Redirector_bug_fixes#Version_2.2.2.6 - */ - base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BSP_HANDLE_POLL); - if (base_socket != INVALID_SOCKET && base_socket != socket) - socket = base_socket; - else - return_set_error(INVALID_SOCKET, error); - } -} diff --git a/modules/trantor/trantor/third_party/wepoll/Wepoll.h b/modules/trantor/trantor/third_party/wepoll/Wepoll.h deleted file mode 100644 index 8ff6de3..0000000 --- a/modules/trantor/trantor/third_party/wepoll/Wepoll.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * wepoll - epoll for Windows - * https://github.com/piscisaureus/wepoll - * - * Copyright 2012-2020, Bert Belder - * 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. - * - * 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 WEPOLL_H_ -#define WEPOLL_H_ - -#ifndef WEPOLL_EXPORT -#define WEPOLL_EXPORT -#endif - -#include - -enum EPOLL_EVENTS -{ - EPOLLIN = (int)(1U << 0), - EPOLLPRI = (int)(1U << 1), - EPOLLOUT = (int)(1U << 2), - EPOLLERR = (int)(1U << 3), - EPOLLHUP = (int)(1U << 4), - EPOLLRDNORM = (int)(1U << 6), - EPOLLRDBAND = (int)(1U << 7), - EPOLLWRNORM = (int)(1U << 8), - EPOLLWRBAND = (int)(1U << 9), - EPOLLMSG = (int)(1U << 10), /* Never reported. */ - EPOLLRDHUP = (int)(1U << 13), - EPOLLEVENT = (int)(1U << 14), - EPOLLONESHOT = (int)(1U << 31) -}; - -#define EPOLLIN (1U << 0) -#define EPOLLPRI (1U << 1) -#define EPOLLOUT (1U << 2) -#define EPOLLERR (1U << 3) -#define EPOLLHUP (1U << 4) -#define EPOLLRDNORM (1U << 6) -#define EPOLLRDBAND (1U << 7) -#define EPOLLWRNORM (1U << 8) -#define EPOLLWRBAND (1U << 9) -#define EPOLLMSG (1U << 10) -#define EPOLLRDHUP (1U << 13) -#define EPOLLEVENT (1U << 14) -#define EPOLLONESHOT (1U << 31) - -#define EPOLL_CTL_ADD 1 -#define EPOLL_CTL_MOD 2 -#define EPOLL_CTL_DEL 3 - -typedef void* HANDLE; -typedef uintptr_t SOCKET; - -typedef union epoll_data -{ - void* ptr; - int fd; - uint32_t u32; - uint64_t u64; - SOCKET sock; /* Windows specific */ - HANDLE hnd; /* Windows specific */ -} epoll_data_t; - -struct epoll_event -{ - uint32_t events; /* Epoll events and flags */ - epoll_data_t data; /* User data variable */ -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - WEPOLL_EXPORT HANDLE epoll_create(int size); - WEPOLL_EXPORT HANDLE epoll_create1(int flags); - - WEPOLL_EXPORT int epoll_close(HANDLE ephnd); - - WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd, - int op, - SOCKET sock, - struct epoll_event* event); - - WEPOLL_EXPORT int epoll_wait(HANDLE ephnd, - struct epoll_event* events, - int maxevents, - int timeout); - WEPOLL_EXPORT void epoll_post_signal(HANDLE ephnd, uint64_t event); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* WEPOLL_H_ */ diff --git a/modules/trantor/trantor/unittests/CMakeLists.txt b/modules/trantor/trantor/unittests/CMakeLists.txt deleted file mode 100644 index 4c7f492..0000000 --- a/modules/trantor/trantor/unittests/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -find_package(GTest REQUIRED) -add_executable(msgbuffer_unittest MsgBufferUnittest.cc) -add_executable(inetaddress_unittest InetAddressUnittest.cc) -add_executable(date_unittest DateUnittest.cc) -add_executable(split_string_unittest splitStringUnittest.cc) -set(UNITTEST_TARGETS - msgbuffer_unittest - inetaddress_unittest - date_unittest - split_string_unittest) -set_property(TARGET ${UNITTEST_TARGETS} PROPERTY CXX_STANDARD 14) -set_property(TARGET ${UNITTEST_TARGETS} PROPERTY CXX_STANDARD_REQUIRED ON) -set_property(TARGET ${UNITTEST_TARGETS} PROPERTY CXX_EXTENSIONS OFF) - -include(GoogleTest) -foreach(T ${UNITTEST_TARGETS}) - target_link_libraries(${T} PRIVATE trantor GTest::GTest) - gtest_discover_tests(${T}) -endforeach() diff --git a/modules/trantor/trantor/unittests/DateUnittest.cc b/modules/trantor/trantor/unittests/DateUnittest.cc deleted file mode 100644 index 255ce28..0000000 --- a/modules/trantor/trantor/unittests/DateUnittest.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -using namespace trantor; -TEST(Date, constructorTest) -{ - EXPECT_STREQ("1985-01-01 00:00:00", - trantor::Date(1985, 1, 1) - .toCustomedFormattedStringLocal("%Y-%m-%d %H:%M:%S") - .c_str()); - EXPECT_STREQ("2004-02-29 00:00:00.000000", - trantor::Date(2004, 2, 29) - .toCustomedFormattedStringLocal("%Y-%m-%d %H:%M:%S", true) - .c_str()); - EXPECT_STRNE("2001-02-29 00:00:00.000000", - trantor::Date(2001, 2, 29) - .toCustomedFormattedStringLocal("%Y-%m-%d %H:%M:%S", true) - .c_str()); - EXPECT_STREQ("2018-01-01 00:00:00.000000", - trantor::Date(2018, 1, 1, 12, 12, 12, 2321) - .roundDay() - .toCustomedFormattedStringLocal("%Y-%m-%d %H:%M:%S", true) - .c_str()); -} -TEST(Date, DatabaseStringTest) -{ - auto now = trantor::Date::now(); - EXPECT_EQ(now, trantor::Date::fromDbStringLocal(now.toDbStringLocal())); - std::string dbString = "2018-01-01 00:00:00.123"; - auto dbDate = trantor::Date::fromDbStringLocal(dbString); - auto ms = (dbDate.microSecondsSinceEpoch() % 1000000) / 1000; - EXPECT_EQ(ms, 123); - dbString = "2018-01-01 00:00:00"; - dbDate = trantor::Date::fromDbStringLocal(dbString); - ms = (dbDate.microSecondsSinceEpoch() % 1000000) / 1000; - EXPECT_EQ(ms, 0); -} -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/modules/trantor/trantor/unittests/InetAddressUnittest.cc b/modules/trantor/trantor/unittests/InetAddressUnittest.cc deleted file mode 100644 index 487ee37..0000000 --- a/modules/trantor/trantor/unittests/InetAddressUnittest.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include -#include -using namespace trantor; -TEST(InetAddress, innerIpTest) -{ - EXPECT_EQ(true, InetAddress("192.168.0.1", 0).isIntranetIp()); - EXPECT_EQ(true, InetAddress("192.168.12.1", 0).isIntranetIp()); - EXPECT_EQ(true, InetAddress("10.168.0.1", 0).isIntranetIp()); - EXPECT_EQ(true, InetAddress("10.0.0.1", 0).isIntranetIp()); - EXPECT_EQ(true, InetAddress("172.31.10.1", 0).isIntranetIp()); - EXPECT_EQ(true, InetAddress("127.0.0.1", 0).isIntranetIp()); - EXPECT_EQ(true, InetAddress("example.com", 0).isUnspecified()); - EXPECT_EQ(false, InetAddress("127.0.0.2", 0).isUnspecified()); - EXPECT_EQ(false, InetAddress("0.0.0.0", 0).isUnspecified()); -} -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/modules/trantor/trantor/unittests/MsgBufferUnittest.cc b/modules/trantor/trantor/unittests/MsgBufferUnittest.cc deleted file mode 100644 index 9addd2c..0000000 --- a/modules/trantor/trantor/unittests/MsgBufferUnittest.cc +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -using namespace trantor; -TEST(MsgBufferTest, readableTest) -{ - MsgBuffer buffer; - - EXPECT_EQ(0, buffer.readableBytes()); - buffer.append(std::string(128, 'a')); - EXPECT_EQ(128, buffer.readableBytes()); - buffer.retrieve(100); - EXPECT_EQ(28, buffer.readableBytes()); - EXPECT_EQ('a', buffer.peekInt8()); - buffer.retrieveAll(); - EXPECT_EQ(0, buffer.readableBytes()); -} -TEST(MsgBufferTest, writableTest) -{ - MsgBuffer buffer(100); - - EXPECT_EQ(100, buffer.writableBytes()); - buffer.append("abcde"); - EXPECT_EQ(95, buffer.writableBytes()); - buffer.append(std::string(100, 'x')); - EXPECT_EQ(111, buffer.writableBytes()); - buffer.retrieve(100); - EXPECT_EQ(111, buffer.writableBytes()); - buffer.append(std::string(112, 'c')); - EXPECT_EQ(99, buffer.writableBytes()); - buffer.retrieveAll(); - EXPECT_EQ(216, buffer.writableBytes()); -} - -TEST(MsgBufferTest, addInFrontTest) -{ - MsgBuffer buffer(100); - - EXPECT_EQ(100, buffer.writableBytes()); - buffer.addInFrontInt8('a'); - EXPECT_EQ(100, buffer.writableBytes()); - buffer.addInFrontInt64(123); - EXPECT_EQ(92, buffer.writableBytes()); - buffer.addInFrontInt64(100); - EXPECT_EQ(84, buffer.writableBytes()); - buffer.addInFrontInt8(1); - EXPECT_EQ(84, buffer.writableBytes()); -} - -TEST(MsgBuffer, MoveContrustor) -{ - MsgBuffer buf1(100); - const char *bufptr1 = buf1.peek(); - MsgBuffer buffnew1 = std::move(buf1); - EXPECT_EQ(bufptr1, buffnew1.peek()); - - MsgBuffer buf2(100); - const char *bufptr2 = buf2.peek(); - MsgBuffer buffnew2(std::move(buf2)); - EXPECT_EQ(bufptr2, buffnew2.peek()); -} - -TEST(Msgbuffer, MoveAssignmentOperator) -{ - MsgBuffer buf(100); - const char *bufptr = buf.peek(); - size_t writable = buf.writableBytes(); - MsgBuffer buffnew(1000); - buffnew = std::move(buf); - EXPECT_EQ(bufptr, buffnew.peek()); - EXPECT_EQ(writable, buffnew.writableBytes()); -} -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/modules/trantor/trantor/unittests/splitStringUnittest.cc b/modules/trantor/trantor/unittests/splitStringUnittest.cc deleted file mode 100644 index efa64af..0000000 --- a/modules/trantor/trantor/unittests/splitStringUnittest.cc +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include -#include -#include -using namespace trantor; -TEST(splitString, ACCEPT_EMPTY_STRING1) -{ - std::string originString = "1,2,3"; - auto out = splitString(originString, ",", true); - EXPECT_EQ(out.size(), 3); -} -TEST(splitString, ACCEPT_EMPTY_STRING2) -{ - std::string originString = ",1,2,3"; - auto out = splitString(originString, ",", true); - EXPECT_EQ(out.size(), 4); - EXPECT_TRUE(out[0].empty()); -} -TEST(splitString, ACCEPT_EMPTY_STRING3) -{ - std::string originString = ",1,2,3,"; - auto out = splitString(originString, ",", true); - EXPECT_EQ(out.size(), 5); - EXPECT_TRUE(out[0].empty()); -} -TEST(splitString, ACCEPT_EMPTY_STRING4) -{ - std::string originString = ",1,2,3,"; - auto out = splitString(originString, ":", true); - EXPECT_EQ(out.size(), 1); - EXPECT_STREQ(out[0].data(), ",1,2,3,"); -} -TEST(splitString, ACCEPT_EMPTY_STRING5) -{ - std::string originString = "trantor::splitString"; - auto out = splitString(originString, "::", true); - EXPECT_EQ(out.size(), 2); - EXPECT_STREQ(out[0].data(), "trantor"); - EXPECT_STREQ(out[1].data(), "splitString"); -} -TEST(splitString, ACCEPT_EMPTY_STRING6) -{ - std::string originString = "trantor::::splitString"; - auto out = splitString(originString, "::", true); - EXPECT_EQ(out.size(), 3); - EXPECT_STREQ(out[0].data(), "trantor"); - EXPECT_STREQ(out[1].data(), ""); - EXPECT_STREQ(out[2].data(), "splitString"); -} -TEST(splitString, ACCEPT_EMPTY_STRING7) -{ - std::string originString = "trantor:::splitString"; - auto out = splitString(originString, "::", true); - EXPECT_EQ(out.size(), 2); - EXPECT_STREQ(out[0].data(), "trantor"); - EXPECT_STREQ(out[1].data(), ":splitString"); -} -TEST(splitString, ACCEPT_EMPTY_STRING8) -{ - std::string originString = "trantor:::splitString"; - auto out = splitString(originString, "trantor:::splitString", true); - EXPECT_EQ(out.size(), 2); - EXPECT_STREQ(out[0].data(), ""); - EXPECT_STREQ(out[1].data(), ""); -} -TEST(splitString, ACCEPT_EMPTY_STRING9) -{ - std::string originString = ""; - auto out = splitString(originString, ",", true); - EXPECT_EQ(out.size(), 1); - EXPECT_STREQ(out[0].data(), ""); -} -TEST(splitString, ACCEPT_EMPTY_STRING10) -{ - std::string originString = "trantor"; - auto out = splitString(originString, "", true); - EXPECT_EQ(out.size(), 0); -} -TEST(splitString, ACCEPT_EMPTY_STRING11) -{ - std::string originString = ""; - auto out = splitString(originString, "", true); - EXPECT_EQ(out.size(), 0); -} - -TEST(splitString, NO_ACCEPT_EMPTY_STRING1) -{ - std::string originString = ",1,2,3"; - auto out = splitString(originString, ","); - EXPECT_EQ(out.size(), 3); - EXPECT_STREQ(out[0].data(), "1"); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING2) -{ - std::string originString = ",1,2,3,"; - auto out = splitString(originString, ","); - EXPECT_EQ(out.size(), 3); - EXPECT_STREQ(out[0].data(), "1"); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING3) -{ - std::string originString = ",1,2,3,"; - auto out = splitString(originString, ":"); - EXPECT_EQ(out.size(), 1); - EXPECT_STREQ(out[0].data(), ",1,2,3,"); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING4) -{ - std::string originString = "trantor::splitString"; - auto out = splitString(originString, "::"); - EXPECT_EQ(out.size(), 2); - EXPECT_STREQ(out[0].data(), "trantor"); - EXPECT_STREQ(out[1].data(), "splitString"); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING5) -{ - std::string originString = "trantor::::splitString"; - auto out = splitString(originString, "::"); - EXPECT_EQ(out.size(), 2); - EXPECT_STREQ(out[0].data(), "trantor"); - EXPECT_STREQ(out[1].data(), "splitString"); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING6) -{ - std::string originString = "trantor:::splitString"; - auto out = splitString(originString, "::"); - EXPECT_EQ(out.size(), 2); - EXPECT_STREQ(out[0].data(), "trantor"); - EXPECT_STREQ(out[1].data(), ":splitString"); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING7) -{ - std::string originString = "trantor:::splitString"; - auto out = splitString(originString, "trantor:::splitString"); - EXPECT_EQ(out.size(), 0); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING8) -{ - std::string originString = ""; - auto out = splitString(originString, ","); - EXPECT_EQ(out.size(), 0); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING9) -{ - std::string originString = "trantor"; - auto out = splitString(originString, ""); - EXPECT_EQ(out.size(), 0); -} -TEST(splitString, NO_ACCEPT_EMPTY_STRING10) -{ - std::string originString = ""; - auto out = splitString(originString, ""); - EXPECT_EQ(out.size(), 0); -} -int main(int argc, char **argv) -{ - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/modules/trantor/trantor/utils/AsyncFileLogger.cc b/modules/trantor/trantor/utils/AsyncFileLogger.cc deleted file mode 100644 index e754d48..0000000 --- a/modules/trantor/trantor/utils/AsyncFileLogger.cc +++ /dev/null @@ -1,253 +0,0 @@ -/** - * - * AsyncFileLogger.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#ifndef _WIN32 -#include -#ifdef __linux__ -#include -#endif -#endif -#include -#include -#include -#include - -namespace trantor -{ -static constexpr std::chrono::seconds kLogFlushTimeout{1}; -static constexpr size_t kMemBufferSize{4 * 1024 * 1024}; -extern const char *strerror_tl(int savedErrno); -} // namespace trantor - -using namespace trantor; - -AsyncFileLogger::AsyncFileLogger() - : logBufferPtr_(new std::string), nextBufferPtr_(new std::string) -{ - logBufferPtr_->reserve(kMemBufferSize); - nextBufferPtr_->reserve(kMemBufferSize); -} - -AsyncFileLogger::~AsyncFileLogger() -{ - // std::cout << "~AsyncFileLogger" << std::endl; - stopFlag_ = true; - if (threadPtr_) - { - cond_.notify_all(); - threadPtr_->join(); - } - // std::cout << "thread exit" << std::endl; - { - std::lock_guard guard_(mutex_); - if (logBufferPtr_->length() > 0) - { - writeBuffers_.push(logBufferPtr_); - } - while (!writeBuffers_.empty()) - { - StringPtr tmpPtr = (StringPtr &&) writeBuffers_.front(); - writeBuffers_.pop(); - writeLogToFile(tmpPtr); - } - } -} - -void AsyncFileLogger::output(const char *msg, const uint64_t len) -{ - std::lock_guard guard_(mutex_); - if (len > kMemBufferSize) - return; - if (!logBufferPtr_) - { - logBufferPtr_ = std::make_shared(); - logBufferPtr_->reserve(kMemBufferSize); - } - if (logBufferPtr_->capacity() - logBufferPtr_->length() < len) - { - swapBuffer(); - cond_.notify_one(); - } - if (writeBuffers_.size() > 25) // 100M bytes logs in buffer - { - ++lostCounter_; - return; - } - - if (lostCounter_ > 0) - { - char logErr[128]; - auto strlen = - snprintf(logErr, - sizeof(logErr), - "%llu log information is lost\n", - static_cast(lostCounter_)); - lostCounter_ = 0; - logBufferPtr_->append(logErr, strlen); - } - logBufferPtr_->append(msg, len); -} - -void AsyncFileLogger::flush() -{ - std::lock_guard guard_(mutex_); - if (logBufferPtr_->length() > 0) - { - // std::cout<<"flush log buffer - // len:"<length()<( - new LoggerFile(filePath_, fileBaseName_, fileExtName_)); - } - loggerFilePtr_->writeLog(buf); - if (loggerFilePtr_->getLength() > sizeLimit_) - { - loggerFilePtr_.reset(); - } -} - -void AsyncFileLogger::logThreadFunc() -{ -#ifdef __linux__ - prctl(PR_SET_NAME, "AsyncFileLogger"); -#endif - while (!stopFlag_) - { - { - std::unique_lock lock(mutex_); - while (writeBuffers_.size() == 0 && !stopFlag_) - { - if (cond_.wait_for(lock, kLogFlushTimeout) == - std::cv_status::timeout) - { - if (logBufferPtr_->length() > 0) - { - swapBuffer(); - } - break; - } - } - tmpBuffers_.swap(writeBuffers_); - } - - while (!tmpBuffers_.empty()) - { - StringPtr tmpPtr = (StringPtr &&) tmpBuffers_.front(); - tmpBuffers_.pop(); - writeLogToFile(tmpPtr); - tmpPtr->clear(); - { - std::unique_lock lock(mutex_); - nextBufferPtr_ = tmpPtr; - } - } - if (loggerFilePtr_) - loggerFilePtr_->flush(); - } -} - -void AsyncFileLogger::startLogging() -{ - threadPtr_ = std::unique_ptr( - new std::thread(std::bind(&AsyncFileLogger::logThreadFunc, this))); -} - -AsyncFileLogger::LoggerFile::LoggerFile(const std::string &filePath, - const std::string &fileBaseName, - const std::string &fileExtName) - : creationDate_(Date::date()), - filePath_(filePath), - fileBaseName_(fileBaseName), - fileExtName_(fileExtName) -{ - fileFullName_ = filePath + fileBaseName + fileExtName; -#ifndef _MSC_VER - fp_ = fopen(fileFullName_.c_str(), "a"); -#else - fp_ = _fsopen(fileFullName_.c_str(), "a+", _SH_DENYWR); -#endif - if (fp_ == nullptr) - { - std::cout << strerror_tl(errno) << std::endl; - } -} - -uint64_t AsyncFileLogger::LoggerFile::fileSeq_{0}; -void AsyncFileLogger::LoggerFile::writeLog(const StringPtr buf) -{ - if (fp_) - { - // std::cout<<"write "<length()<<" bytes to file"<c_str(), 1, buf->length(), fp_); - } -} - -void AsyncFileLogger::LoggerFile::flush() -{ - if (fp_) - { - fflush(fp_); - } -} - -uint64_t AsyncFileLogger::LoggerFile::getLength() -{ - if (fp_) - return ftell(fp_); - return 0; -} - -AsyncFileLogger::LoggerFile::~LoggerFile() -{ - if (fp_) - { - fclose(fp_); - char seq[12]; - snprintf(seq, - sizeof(seq), - ".%06llu", - static_cast(fileSeq_ % 1000000)); - ++fileSeq_; - std::string newName = - filePath_ + fileBaseName_ + "." + - creationDate_.toCustomedFormattedString("%y%m%d-%H%M%S") + - std::string(seq) + fileExtName_; - rename(fileFullName_.c_str(), newName.c_str()); - } -} - -void AsyncFileLogger::swapBuffer() -{ - writeBuffers_.push(logBufferPtr_); - if (nextBufferPtr_) - { - logBufferPtr_ = nextBufferPtr_; - nextBufferPtr_.reset(); - logBufferPtr_->clear(); - } - else - { - logBufferPtr_ = std::make_shared(); - logBufferPtr_->reserve(kMemBufferSize); - } -} diff --git a/modules/trantor/trantor/utils/AsyncFileLogger.h b/modules/trantor/trantor/utils/AsyncFileLogger.h deleted file mode 100644 index 0f54c67..0000000 --- a/modules/trantor/trantor/utils/AsyncFileLogger.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * - * @file AsyncFileLogger.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -using StringPtr = std::shared_ptr; -using StringPtrQueue = std::queue; - -/** - * @brief This class implements utility functions for writing logs to files - * asynchronously. - * - */ -class TRANTOR_EXPORT AsyncFileLogger : NonCopyable -{ - 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 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 : NonCopyable - { - 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 loggerFilePtr_; - - uint64_t lostCounter_{0}; - void swapBuffer(); -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/ConcurrentTaskQueue.cc b/modules/trantor/trantor/utils/ConcurrentTaskQueue.cc deleted file mode 100644 index 8054755..0000000 --- a/modules/trantor/trantor/utils/ConcurrentTaskQueue.cc +++ /dev/null @@ -1,95 +0,0 @@ -/** - * - * ConcurrentTaskQueue.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include -#include -#ifdef __linux__ -#include -#endif -using namespace trantor; -ConcurrentTaskQueue::ConcurrentTaskQueue(size_t threadNum, - const std::string &name) - : queueCount_(threadNum), queueName_(name), stop_(false) -{ - assert(threadNum > 0); - for (unsigned int i = 0; i < queueCount_; ++i) - { - threads_.push_back( - std::thread(std::bind(&ConcurrentTaskQueue::queueFunc, this, i))); - } -} -void ConcurrentTaskQueue::runTaskInQueue(const std::function &task) -{ - LOG_TRACE << "copy task into queue"; - std::lock_guard lock(taskMutex_); - taskQueue_.push(task); - taskCond_.notify_one(); -} -void ConcurrentTaskQueue::runTaskInQueue(std::function &&task) -{ - LOG_TRACE << "move task into queue"; - std::lock_guard lock(taskMutex_); - taskQueue_.push(std::move(task)); - taskCond_.notify_one(); -} -void ConcurrentTaskQueue::queueFunc(int queueNum) -{ - char tmpName[32]; - snprintf(tmpName, sizeof(tmpName), "%s%d", queueName_.c_str(), queueNum); -#ifdef __linux__ - ::prctl(PR_SET_NAME, tmpName); -#endif - while (!stop_) - { - std::function r; - { - std::unique_lock lock(taskMutex_); - while (!stop_ && taskQueue_.size() == 0) - { - taskCond_.wait(lock); - } - if (taskQueue_.size() > 0) - { - LOG_TRACE << "got a new task!"; - r = std::move(taskQueue_.front()); - taskQueue_.pop(); - } - else - continue; - } - r(); - } -} - -size_t ConcurrentTaskQueue::getTaskCount() -{ - std::lock_guard guard(taskMutex_); - return taskQueue_.size(); -} - -void ConcurrentTaskQueue::stop() -{ - if (!stop_) - { - stop_ = true; - taskCond_.notify_all(); - for (auto &t : threads_) - t.join(); - } -} -ConcurrentTaskQueue::~ConcurrentTaskQueue() -{ - stop(); -} diff --git a/modules/trantor/trantor/utils/ConcurrentTaskQueue.h b/modules/trantor/trantor/utils/ConcurrentTaskQueue.h deleted file mode 100644 index bcde18c..0000000 --- a/modules/trantor/trantor/utils/ConcurrentTaskQueue.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * - * @file ConcurrentTaskQueue.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -/** - * @brief This class implements a task queue running in parallel. Basically this - * can be called a threads pool. - * - */ -class TRANTOR_EXPORT ConcurrentTaskQueue : public TaskQueue -{ - public: - /** - * @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 &task); - virtual void runTaskInQueue(std::function &&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> taskQueue_; - std::vector threads_; - - std::mutex taskMutex_; - std::condition_variable taskCond_; - std::atomic_bool stop_; - void queueFunc(int queueNum); -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/Date.cc b/modules/trantor/trantor/utils/Date.cc deleted file mode 100644 index 14bc83e..0000000 --- a/modules/trantor/trantor/utils/Date.cc +++ /dev/null @@ -1,359 +0,0 @@ -/** - * - * Date.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include "Date.h" -#include "Funcs.h" -#ifndef _WIN32 -#include -#endif -#include -#include -#include -#ifdef _WIN32 -#include -#include -#endif - -namespace trantor -{ -#ifdef _WIN32 -int gettimeofday(timeval *tp, void *tzp) -{ - time_t clock; - struct tm tm; - SYSTEMTIME wtm; - - GetLocalTime(&wtm); - tm.tm_year = wtm.wYear - 1900; - tm.tm_mon = wtm.wMonth - 1; - tm.tm_mday = wtm.wDay; - tm.tm_hour = wtm.wHour; - tm.tm_min = wtm.wMinute; - tm.tm_sec = wtm.wSecond; - tm.tm_isdst = -1; - clock = mktime(&tm); - tp->tv_sec = static_cast(clock); - tp->tv_usec = wtm.wMilliseconds * 1000; - - return (0); -} -#endif -const Date Date::date() -{ -#ifndef _WIN32 - struct timeval tv; - gettimeofday(&tv, NULL); - int64_t seconds = tv.tv_sec; - return Date(seconds * MICRO_SECONDS_PRE_SEC + tv.tv_usec); -#else - timeval tv; - gettimeofday(&tv, NULL); - int64_t seconds = tv.tv_sec; - return Date(seconds * MICRO_SECONDS_PRE_SEC + tv.tv_usec); -#endif -} -const Date Date::after(double second) const -{ - return Date(static_cast(microSecondsSinceEpoch_ + - second * MICRO_SECONDS_PRE_SEC)); -} -const Date Date::roundSecond() const -{ - return Date(microSecondsSinceEpoch_ - - (microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC)); -} -const Date Date::roundDay() const -{ - struct tm t; - time_t seconds = - static_cast(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); -#ifndef _WIN32 - localtime_r(&seconds, &t); -#else - localtime_s(&t, &seconds); -#endif - t.tm_hour = 0; - t.tm_min = 0; - t.tm_sec = 0; - return Date(mktime(&t) * MICRO_SECONDS_PRE_SEC); -} -struct tm Date::tmStruct() const -{ - time_t seconds = - static_cast(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - gmtime_r(&seconds, &tm_time); -#else - gmtime_s(&tm_time, &seconds); -#endif - return tm_time; -} -std::string Date::toFormattedString(bool showMicroseconds) const -{ - // std::cout<<"toFormattedString"<(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - gmtime_r(&seconds, &tm_time); -#else - gmtime_s(&tm_time, &seconds); -#endif - - if (showMicroseconds) - { - int microseconds = - static_cast(microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC); - snprintf(buf, - sizeof(buf), - "%4d%02d%02d %02d:%02d:%02d.%06d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec, - microseconds); - } - else - { - snprintf(buf, - sizeof(buf), - "%4d%02d%02d %02d:%02d:%02d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec); - } - return buf; -} -std::string Date::toCustomedFormattedString(const std::string &fmtStr, - bool showMicroseconds) const -{ - char buf[256] = {0}; - time_t seconds = - static_cast(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - gmtime_r(&seconds, &tm_time); -#else - gmtime_s(&tm_time, &seconds); -#endif - strftime(buf, sizeof(buf), fmtStr.c_str(), &tm_time); - if (!showMicroseconds) - return std::string(buf); - char decimals[12] = {0}; - int microseconds = - static_cast(microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC); - snprintf(decimals, sizeof(decimals), ".%06d", microseconds); - return std::string(buf) + decimals; -} -void Date::toCustomedFormattedString(const std::string &fmtStr, - char *str, - size_t len) const -{ - // not safe - time_t seconds = - static_cast(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - gmtime_r(&seconds, &tm_time); -#else - gmtime_s(&tm_time, &seconds); -#endif - strftime(str, len, fmtStr.c_str(), &tm_time); -} -std::string Date::toFormattedStringLocal(bool showMicroseconds) const -{ - // std::cout<<"toFormattedString"<(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - localtime_r(&seconds, &tm_time); -#else - localtime_s(&tm_time, &seconds); -#endif - - if (showMicroseconds) - { - int microseconds = - static_cast(microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC); - snprintf(buf, - sizeof(buf), - "%4d%02d%02d %02d:%02d:%02d.%06d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec, - microseconds); - } - else - { - snprintf(buf, - sizeof(buf), - "%4d%02d%02d %02d:%02d:%02d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec); - } - return buf; -} -std::string Date::toDbStringLocal() const -{ - char buf[128] = {0}; - time_t seconds = - static_cast(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - localtime_r(&seconds, &tm_time); -#else - localtime_s(&tm_time, &seconds); -#endif - bool showMicroseconds = - (microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC != 0); - if (showMicroseconds) - { - int microseconds = - static_cast(microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC); - snprintf(buf, - sizeof(buf), - "%4d-%02d-%02d %02d:%02d:%02d.%06d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec, - microseconds); - } - else - { - if (*this == roundDay()) - { - snprintf(buf, - sizeof(buf), - "%4d-%02d-%02d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday); - } - else - { - snprintf(buf, - sizeof(buf), - "%4d-%02d-%02d %02d:%02d:%02d", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec); - } - } - return buf; -} -Date Date::fromDbStringLocal(const std::string &datetime) -{ - unsigned int year = {0}, month = {0}, day = {0}, hour = {0}, minute = {0}, - second = {0}, microSecond = {0}; - std::vector &&v = splitString(datetime, " "); - if (2 == v.size()) - { - // date - std::vector date = splitString(v[0], "-"); - if (3 == date.size()) - { - year = std::stol(date[0]); - month = std::stol(date[1]); - day = std::stol(date[2]); - std::vector time = splitString(v[1], ":"); - if (2 < time.size()) - { - hour = std::stol(time[0]); - minute = std::stol(time[1]); - auto seconds = splitString(time[2], "."); - second = std::stol(seconds[0]); - if (1 < seconds.size()) - { - if (seconds[1].length() > 6) - { - seconds[1].resize(6); - } - else if (seconds[1].length() < 6) - { - seconds[1].append(6 - seconds[1].length(), '0'); - } - microSecond = std::stol(seconds[1]); - } - } - } - } - return std::move( - trantor::Date(year, month, day, hour, minute, second, microSecond)); -} -std::string Date::toCustomedFormattedStringLocal(const std::string &fmtStr, - bool showMicroseconds) const -{ - char buf[256] = {0}; - time_t seconds = - static_cast(microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC); - struct tm tm_time; -#ifndef _WIN32 - localtime_r(&seconds, &tm_time); -#else - localtime_s(&tm_time, &seconds); -#endif - strftime(buf, sizeof(buf), fmtStr.c_str(), &tm_time); - if (!showMicroseconds) - return std::string(buf); - char decimals[12] = {0}; - int microseconds = - static_cast(microSecondsSinceEpoch_ % MICRO_SECONDS_PRE_SEC); - snprintf(decimals, sizeof(decimals), ".%06d", microseconds); - return std::string(buf) + decimals; -} -Date::Date(unsigned int year, - unsigned int month, - unsigned int day, - unsigned int hour, - unsigned int minute, - unsigned int second, - unsigned int microSecond) -{ - struct tm tm; - memset(&tm, 0, sizeof(tm)); - tm.tm_isdst = -1; - time_t epoch; - tm.tm_year = year - 1900; - tm.tm_mon = month - 1; - tm.tm_mday = day; - tm.tm_hour = hour; - tm.tm_min = minute; - tm.tm_sec = second; - epoch = mktime(&tm); - microSecondsSinceEpoch_ = epoch * MICRO_SECONDS_PRE_SEC + microSecond; -} - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/Date.h b/modules/trantor/trantor/utils/Date.h deleted file mode 100644 index 8543a2d..0000000 --- a/modules/trantor/trantor/utils/Date.h +++ /dev/null @@ -1,281 +0,0 @@ -/** - * - * @file Date.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include - -#define MICRO_SECONDS_PRE_SEC 1000000 - -namespace trantor -{ -/** - * @brief This class represents a time point. - * - */ -class TRANTOR_EXPORT Date -{ - public: - Date() : microSecondsSinceEpoch_(0){}; - - /** - * @brief Construct a new Date instance. - * - * @param microSec The microseconds from 1970-01-01 00:00:00. - */ - explicit Date(int64_t microSec) : microSecondsSinceEpoch_(microSec){}; - - /** - * @brief Construct a new Date instance. - * - * @param year - * @param month - * @param day - * @param hour - * @param minute - * @param second - * @param microSecond - */ - Date(unsigned int year, - unsigned int month, - unsigned int day, - unsigned int hour = 0, - unsigned int minute = 0, - unsigned int second = 0, - unsigned int microSecond = 0); - - /** - * @brief Create a Date object that represents the current time. - * - * @return const Date - */ - static const Date date(); - - /** - * @brief Same as the date() method. - * - * @return const Date - */ - static const Date now() - { - return Date::date(); - } - - /** - * @brief Return a new Date instance that represents the time after some - * seconds from *this. - * - * @param second - * @return const Date - */ - const Date after(double second) const; - - /** - * @brief Return a new Date instance that equals to *this, but with zero - * microseconds. - * - * @return const Date - */ - const Date roundSecond() const; - - /// Create a Date object equal to * this, but numbers of hours, minutes, - /// seconds and microseconds are zero. - - /** - * @brief Return a new Date instance that equals to * this, but with zero - * hours, minutes, seconds and microseconds. - * - * @return const Date - */ - const Date roundDay() const; - - ~Date(){}; - - /** - * @brief Return true if the time point is equal to another. - * - */ - bool operator==(const Date &date) const - { - return microSecondsSinceEpoch_ == date.microSecondsSinceEpoch_; - } - - /** - * @brief Return true if the time point is not equal to another. - * - */ - bool operator!=(const Date &date) const - { - return microSecondsSinceEpoch_ != date.microSecondsSinceEpoch_; - } - - /** - * @brief Return true if the time point is earlier than another. - * - */ - bool operator<(const Date &date) const - { - return microSecondsSinceEpoch_ < date.microSecondsSinceEpoch_; - } - - /** - * @brief Return true if the time point is later than another. - * - */ - bool operator>(const Date &date) const - { - return microSecondsSinceEpoch_ > date.microSecondsSinceEpoch_; - } - - /** - * @brief Return true if the time point is not earlier than another. - * - */ - bool operator>=(const Date &date) const - { - return microSecondsSinceEpoch_ >= date.microSecondsSinceEpoch_; - } - - /** - * @brief Return true if the time point is not later than another. - * - */ - bool operator<=(const Date &date) const - { - return microSecondsSinceEpoch_ <= date.microSecondsSinceEpoch_; - } - - /** - * @brief Get the number of milliseconds since 1970-01-01 00:00. - * - * @return int64_t - */ - int64_t microSecondsSinceEpoch() const - { - return microSecondsSinceEpoch_; - } - - /** - * @brief Get the number of seconds since 1970-01-01 00:00. - * - * @return int64_t - */ - int64_t secondsSinceEpoch() const - { - return microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC; - } - - /** - * @brief Get the tm struct for the time point. - * - * @return struct tm - */ - struct tm tmStruct() const; - - /** - * @brief Generate a UTC time string - * @example: - * 20180101 10:10:25 //If the @param showMicroseconds is false - * 20180101 10:10:25:102414 //If the @param showMicroseconds is true - */ - std::string toFormattedString(bool showMicroseconds) const; - - /** - * @brief Generate a UTC time string formated by the @param fmtStr - * The @param fmtStr is the format string for the function strftime() - * @example: - * 2018-01-01 10:10:25 //If the @param fmtStr is "%Y-%m-%d - * %H:%M:%S" and the @param showMicroseconds is false 2018-01-01 - * 10:10:25:102414 //If the @param fmtStr is "%Y-%m-%d %H:%M:%S" and the - * @param showMicroseconds is true - */ - std::string toCustomedFormattedString(const std::string &fmtStr, - bool showMicroseconds = false) const; - - /** - * @brief Generate a local time zone string, the format of the string is - * same as the mothed toFormattedString - * - * @param showMicroseconds - * @return std::string - */ - std::string toFormattedStringLocal(bool showMicroseconds) const; - - /** - * @brief Generate a local time zone string formated by the @param fmtStr - * - * @param fmtStr - * @param showMicroseconds - * @return std::string - */ - std::string toCustomedFormattedStringLocal( - const std::string &fmtStr, - bool showMicroseconds = false) const; - - /** - * @brief Generate a local time zone string for database. - * @example: - * 2018-01-01 //If hours, minutes, seconds and - * microseconds are zero 2018-01-01 10:10:25 //If the microsecond - * is zero 2018-01-01 10:10:25:102414 //If the microsecond is not zero - */ - std::string toDbStringLocal() const; - - /** - * @brief From DB string to trantor local time zone. - * - * Inverse of toDbStringLocal() - */ - static Date fromDbStringLocal(const std::string &datetime); - - /** - * @brief Generate a UTC time string. - * - * @param fmtStr The format string. - * @param str The string buffer for the generated time string. - * @param len The length of the string buffer. - */ - void toCustomedFormattedString(const std::string &fmtStr, - char *str, - size_t len) const; // UTC - - /** - * @brief Return true if the time point is in a same second as another. - * - * @param date - * @return true - * @return false - */ - bool isSameSecond(const Date &date) const - { - return microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC == - date.microSecondsSinceEpoch_ / MICRO_SECONDS_PRE_SEC; - } - - /** - * @brief Swap the time point with another. - * - * @param that - */ - void swap(Date &that) - { - std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_); - } - - private: - int64_t microSecondsSinceEpoch_{0}; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/utils/Funcs.h b/modules/trantor/trantor/utils/Funcs.h deleted file mode 100644 index 7a13273..0000000 --- a/modules/trantor/trantor/utils/Funcs.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * - * Funcs.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once -#include -#include -namespace trantor -{ -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(&n); - std::reverse(ptr, ptr + sizeof(uint64_t)); - return n; -} -inline uint64_t ntoh64(uint64_t n) -{ - return hton64(n); -} -inline std::vector splitString(const std::string &s, - const std::string &delimiter, - bool acceptEmptyString = false) -{ - if (delimiter.empty()) - return std::vector{}; - std::vector 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; -} -} // namespace trantor diff --git a/modules/trantor/trantor/utils/LockFreeQueue.h b/modules/trantor/trantor/utils/LockFreeQueue.h deleted file mode 100644 index f608a90..0000000 --- a/modules/trantor/trantor/utils/LockFreeQueue.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * - * @file LockFreeQueue.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once -#include -#include -#include -#include -#include -namespace trantor -{ -/** - * @brief This class template represents a lock-free multiple producers single - * consumer queue - * - * @tparam T The type of the items in the queue. - */ -template -class MpscQueue : public NonCopyable -{ - 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 next_{nullptr}; - }; - - std::atomic head_; - std::atomic tail_; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/LogStream.cc b/modules/trantor/trantor/utils/LogStream.cc deleted file mode 100644 index bbb6bd5..0000000 --- a/modules/trantor/trantor/utils/LogStream.cc +++ /dev/null @@ -1,273 +0,0 @@ -/** - * - * LogStream.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -// taken from muduo lib - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace trantor; -using namespace trantor::detail; - -namespace trantor -{ -namespace detail -{ -const char digits[] = "9876543210123456789"; -const char *zero = digits + 9; - -const char digitsHex[] = "0123456789ABCDEF"; - -// Efficient Integer to String Conversions, by Matthew Wilson. -template -size_t convert(char buf[], T value) -{ - T i = value; - char *p = buf; - - do - { - int lsd = static_cast(i % 10); - i /= 10; - *p++ = zero[lsd]; - } while (i != 0); - - if (value < 0) - { - *p++ = '-'; - } - *p = '\0'; - std::reverse(buf, p); - - return p - buf; -} - -size_t convertHex(char buf[], uintptr_t value) -{ - uintptr_t i = value; - char *p = buf; - - do - { - int lsd = static_cast(i % 16); - i /= 16; - *p++ = digitsHex[lsd]; - } while (i != 0); - - *p = '\0'; - std::reverse(buf, p); - - return p - buf; -} - -template class FixedBuffer; -template class FixedBuffer; - -} // namespace detail -} // namespace trantor - -template -const char *FixedBuffer::debugString() -{ - *cur_ = '\0'; - return data_; -} - -template -void FixedBuffer::cookieStart() -{ -} - -template -void FixedBuffer::cookieEnd() -{ -} - -template -void LogStream::formatInteger(T v) -{ - constexpr static int kMaxNumericSize = std::numeric_limits::digits10 + 4; - if (exBuffer_.empty()) - { - if (buffer_.avail() >= kMaxNumericSize) - { - size_t len = convert(buffer_.current(), v); - buffer_.add(len); - return; - } - else - { - exBuffer_.append(buffer_.data(), buffer_.length()); - } - } - auto oldLen = exBuffer_.length(); - exBuffer_.resize(oldLen + kMaxNumericSize); - size_t len = convert(&exBuffer_[oldLen], v); - exBuffer_.resize(oldLen + len); -} - -LogStream &LogStream::operator<<(short v) -{ - *this << static_cast(v); - return *this; -} - -LogStream &LogStream::operator<<(unsigned short v) -{ - *this << static_cast(v); - return *this; -} - -LogStream &LogStream::operator<<(int v) -{ - formatInteger(v); - return *this; -} - -LogStream &LogStream::operator<<(unsigned int v) -{ - formatInteger(v); - return *this; -} - -LogStream &LogStream::operator<<(long v) -{ - formatInteger(v); - return *this; -} - -LogStream &LogStream::operator<<(unsigned long v) -{ - formatInteger(v); - return *this; -} - -LogStream &LogStream::operator<<(const long long &v) -{ - formatInteger(v); - return *this; -} - -LogStream &LogStream::operator<<(const unsigned long long &v) -{ - formatInteger(v); - return *this; -} - -LogStream &LogStream::operator<<(const void *p) -{ - uintptr_t v = reinterpret_cast(p); - constexpr static int kMaxNumericSize = - std::numeric_limits::digits / 4 + 4; - if (exBuffer_.empty()) - { - if (buffer_.avail() >= kMaxNumericSize) - { - char *buf = buffer_.current(); - buf[0] = '0'; - buf[1] = 'x'; - size_t len = convertHex(buf + 2, v); - buffer_.add(len + 2); - return *this; - } - else - { - exBuffer_.append(buffer_.data(), buffer_.length()); - } - } - auto oldLen = exBuffer_.length(); - exBuffer_.resize(oldLen + kMaxNumericSize); - char *buf = &exBuffer_[oldLen]; - buf[0] = '0'; - buf[1] = 'x'; - size_t len = convertHex(buf + 2, v); - exBuffer_.resize(oldLen + len + 2); - return *this; -} - -// TODO: replace this with Grisu3 by Florian Loitsch. -LogStream &LogStream::operator<<(const double &v) -{ - constexpr static int kMaxNumericSize = 32; - if (exBuffer_.empty()) - { - if (buffer_.avail() >= kMaxNumericSize) - { - int len = snprintf(buffer_.current(), kMaxNumericSize, "%.12g", v); - buffer_.add(len); - return *this; - } - else - { - exBuffer_.append(buffer_.data(), buffer_.length()); - } - } - auto oldLen = exBuffer_.length(); - exBuffer_.resize(oldLen + kMaxNumericSize); - int len = snprintf(&(exBuffer_[oldLen]), kMaxNumericSize, "%.12g", v); - exBuffer_.resize(oldLen + len); - return *this; -} - -LogStream &LogStream::operator<<(const long double &v) -{ - constexpr static int kMaxNumericSize = 48; - if (exBuffer_.empty()) - { - if (buffer_.avail() >= kMaxNumericSize) - { - int len = snprintf(buffer_.current(), kMaxNumericSize, "%.12Lg", v); - buffer_.add(len); - return *this; - } - else - { - exBuffer_.append(buffer_.data(), buffer_.length()); - } - } - auto oldLen = exBuffer_.length(); - exBuffer_.resize(oldLen + kMaxNumericSize); - int len = snprintf(&(exBuffer_[oldLen]), kMaxNumericSize, "%.12Lg", v); - exBuffer_.resize(oldLen + len); - return *this; -} - -template -Fmt::Fmt(const char *fmt, T val) -{ - length_ = snprintf(buf_, sizeof buf_, fmt, val); - assert(static_cast(length_) < sizeof buf_); -} - -// Explicit instantiations - -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, char); - -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, short); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, unsigned short); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, int); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, unsigned int); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, long); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, unsigned long); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, long long); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, unsigned long long); - -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, float); -template TRANTOR_EXPORT Fmt::Fmt(const char *fmt, double); diff --git a/modules/trantor/trantor/utils/LogStream.h b/modules/trantor/trantor/utils/LogStream.h deleted file mode 100644 index d668434..0000000 --- a/modules/trantor/trantor/utils/LogStream.h +++ /dev/null @@ -1,277 +0,0 @@ -/** - * - * @file LogStream.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -// Taken from muduo lib and modified. Classes in this file are used internally. -#include -#include - -#include -#include // memcpy -#include - -namespace trantor -{ -namespace detail -{ -static constexpr size_t kSmallBuffer{4000}; -static constexpr size_t kLargeBuffer{4000 * 1000}; - -template -class TRANTOR_EXPORT FixedBuffer : NonCopyable -{ - 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(cur_ - data_); - } - - // write to data_ directly - char *current() - { - return cur_; - } - int avail() const - { - return static_cast(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 TRANTOR_EXPORT LogStream : NonCopyable -{ - using self = LogStream; - - public: - using Buffer = detail::FixedBuffer; - - 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(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 - 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(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(); - } - - private: - template - void formatInteger(T); - - Buffer buffer_; - std::string exBuffer_; -}; - -class TRANTOR_EXPORT Fmt // : boost::noncopyable -{ - public: - template - 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; -} - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/Logger.cc b/modules/trantor/trantor/utils/Logger.cc deleted file mode 100644 index b407ef3..0000000 --- a/modules/trantor/trantor/utils/Logger.cc +++ /dev/null @@ -1,212 +0,0 @@ -/** - * - * Logger.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include -#include -#ifndef _WIN32 -#include -#include -#else -#include -#endif -#ifdef __FreeBSD__ -#include -#endif - -namespace trantor -{ -// 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(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; -} -} // namespace trantor -using namespace trantor; - -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(date_.secondsSinceEpoch()); - uint64_t microSec = - static_cast(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( - 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(microSec)); - logStream_ << T(tmp, 12); -#ifdef __linux__ - if (threadId_ == 0) - threadId_ = static_cast(::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_; -} diff --git a/modules/trantor/trantor/utils/Logger.h b/modules/trantor/trantor/utils/Logger.h deleted file mode 100644 index ddb6100..0000000 --- a/modules/trantor/trantor/utils/Logger.h +++ /dev/null @@ -1,383 +0,0 @@ -/** - * - * @file Logger.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace trantor -{ -/** - * @brief This class implements log functions. - * - */ -class TRANTOR_EXPORT Logger : public NonCopyable -{ - 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 - inline SourceFile(const char (&arr)[N]) : data_(arr), size_(N - 1) - { - // std::cout<(data_ - arr); - } - } - - explicit SourceFile(const char *filename) : data_(filename) - { - const char *slash = strrchr(filename, '/'); - if (slash) - { - data_ = slash + 1; - } - size_ = static_cast(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 outputFunc, - std::function 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 - &outputFunc_() - { - static std::function - outputFunc = Logger::defaultOutputFunction; - return outputFunc; - } - static std::function &flushFunc_() - { - static std::function flushFunc = Logger::defaultFlushFunction; - return flushFunc; - } - static std::function - &outputFunc_(size_t index) - { - static std::vector< - std::function> - outputFuncs; - if (index < outputFuncs.size()) - { - return outputFuncs[index]; - } - while (index >= outputFuncs.size()) - { - outputFuncs.emplace_back(outputFunc_()); - } - return outputFuncs[index]; - } - static std::function &flushFunc_(size_t index) - { - static std::vector> 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 TRANTOR_EXPORT RawLogger : public NonCopyable -{ - public: - ~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) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kTrace, __func__) \ - .stream() -#else -#define LOG_TRACE \ - if (trantor::Logger::logLevel() <= trantor::Logger::kTrace) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kTrace, __func__) \ - .stream() -#define LOG_TRACE_TO(index) \ - if (trantor::Logger::logLevel() <= trantor::Logger::kTrace) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kTrace, __func__) \ - .setIndex(index) \ - .stream() - -#endif - -#define LOG_DEBUG \ - if (trantor::Logger::logLevel() <= trantor::Logger::kDebug) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kDebug, __func__) \ - .stream() -#define LOG_DEBUG_TO(index) \ - if (trantor::Logger::logLevel() <= trantor::Logger::kDebug) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kDebug, __func__) \ - .setIndex(index) \ - .stream() -#define LOG_INFO \ - if (trantor::Logger::logLevel() <= trantor::Logger::kInfo) \ - trantor::Logger(__FILE__, __LINE__).stream() -#define LOG_INFO_TO(index) \ - if (trantor::Logger::logLevel() <= trantor::Logger::kInfo) \ - trantor::Logger(__FILE__, __LINE__).setIndex(index).stream() -#define LOG_WARN \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kWarn).stream() -#define LOG_WARN_TO(index) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kWarn) \ - .setIndex(index) \ - .stream() -#define LOG_ERROR \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kError).stream() -#define LOG_ERROR_TO(index) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kError) \ - .setIndex(index) \ - .stream() -#define LOG_FATAL \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kFatal).stream() -#define LOG_FATAL_TO(index) \ - trantor::Logger(__FILE__, __LINE__, trantor::Logger::kFatal) \ - .setIndex(index) \ - .stream() -#define LOG_SYSERR trantor::Logger(__FILE__, __LINE__, true).stream() -#define LOG_SYSERR_TO(index) \ - trantor::Logger(__FILE__, __LINE__, true).setIndex(index).stream() - -#define LOG_RAW trantor::RawLogger().stream() -#define LOG_RAW_TO(index) trantor::RawLogger().setIndex(index).stream() - -#define LOG_TRACE_IF(cond) \ - if ((trantor::Logger::logLevel() <= trantor::Logger::kTrace) && (cond)) \ - trantor::Logger(__FILE__, __LINE__, trantor::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) \ - trantor::Logger(__FILE__, __LINE__, trantor::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) \ - trantor::Logger(__FILE__, __LINE__, trantor::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 (trantor::Logger::logLevel() <= trantor::Logger::kTrace) \ - trantor::Logger(__FILE__, __LINE__, trantor::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 ((trantor::Logger::logLevel() <= trantor::Logger::kTrace) && (cond)) \ - trantor::Logger(__FILE__, __LINE__, trantor::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); -} // namespace trantor diff --git a/modules/trantor/trantor/utils/MsgBuffer.cc b/modules/trantor/trantor/utils/MsgBuffer.cc deleted file mode 100644 index 038f7ea..0000000 --- a/modules/trantor/trantor/utils/MsgBuffer.cc +++ /dev/null @@ -1,232 +0,0 @@ -/** - * - * MsgBuffer.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include -#include -#ifndef _WIN32 -#include -#include -#else -#include -#include -#endif -#include -#include - -using namespace trantor; -namespace trantor -{ -static constexpr size_t kBufferOffset{8}; -} - -MsgBuffer::MsgBuffer(size_t len) - : head_(kBufferOffset), initCap_(len), buffer_(len + head_), tail_(head_) -{ -} - -void MsgBuffer::ensureWritableBytes(size_t len) -{ - if (writableBytes() >= len) - return; - if (head_ + writableBytes() >= - (len + kBufferOffset)) // move readable bytes - { - std::copy(begin() + head_, begin() + tail_, begin() + kBufferOffset); - tail_ = kBufferOffset + (tail_ - head_); - head_ = kBufferOffset; - return; - } - // create new buffer - size_t newLen; - if ((buffer_.size() * 2) > (kBufferOffset + readableBytes() + len)) - newLen = buffer_.size() * 2; - else - newLen = kBufferOffset + readableBytes() + len; - MsgBuffer newbuffer(newLen); - newbuffer.append(*this); - swap(newbuffer); -} -void MsgBuffer::swap(MsgBuffer &buf) noexcept -{ - buffer_.swap(buf.buffer_); - std::swap(head_, buf.head_); - std::swap(tail_, buf.tail_); - std::swap(initCap_, buf.initCap_); -} -void MsgBuffer::append(const MsgBuffer &buf) -{ - ensureWritableBytes(buf.readableBytes()); - memcpy(&buffer_[tail_], buf.peek(), buf.readableBytes()); - tail_ += buf.readableBytes(); -} -void MsgBuffer::append(const char *buf, size_t len) -{ - ensureWritableBytes(len); - memcpy(&buffer_[tail_], buf, len); - tail_ += len; -} -void MsgBuffer::appendInt16(const uint16_t s) -{ - uint16_t ss = htons(s); - append(static_cast((void *)&ss), 2); -} -void MsgBuffer::appendInt32(const uint32_t i) -{ - uint32_t ii = htonl(i); - append(static_cast((void *)&ii), 4); -} -void MsgBuffer::appendInt64(const uint64_t l) -{ - uint64_t ll = hton64(l); - append(static_cast((void *)&ll), 8); -} - -void MsgBuffer::addInFrontInt16(const uint16_t s) -{ - uint16_t ss = htons(s); - addInFront(static_cast((void *)&ss), 2); -} -void MsgBuffer::addInFrontInt32(const uint32_t i) -{ - uint32_t ii = htonl(i); - addInFront(static_cast((void *)&ii), 4); -} -void MsgBuffer::addInFrontInt64(const uint64_t l) -{ - uint64_t ll = hton64(l); - addInFront(static_cast((void *)&ll), 8); -} - -uint16_t MsgBuffer::peekInt16() const -{ - assert(readableBytes() >= 2); - uint16_t rs = *(static_cast((void *)peek())); - return ntohs(rs); -} -uint32_t MsgBuffer::peekInt32() const -{ - assert(readableBytes() >= 4); - uint32_t rl = *(static_cast((void *)peek())); - return ntohl(rl); -} -uint64_t MsgBuffer::peekInt64() const -{ - assert(readableBytes() >= 8); - uint64_t rll = *(static_cast((void *)peek())); - return ntoh64(rll); -} - -void MsgBuffer::retrieve(size_t len) -{ - if (len >= readableBytes()) - { - retrieveAll(); - return; - } - head_ += len; -} -void MsgBuffer::retrieveAll() -{ - if (buffer_.size() > (initCap_ * 2)) - { - buffer_.resize(initCap_); - } - tail_ = head_ = kBufferOffset; -} -ssize_t MsgBuffer::readFd(int fd, int *retErrno) -{ - char extBuffer[8192]; - struct iovec vec[2]; - size_t writable = writableBytes(); - vec[0].iov_base = begin() + tail_; - vec[0].iov_len = static_cast(writable); - vec[1].iov_base = extBuffer; - vec[1].iov_len = sizeof(extBuffer); - const int iovcnt = (writable < sizeof extBuffer) ? 2 : 1; - ssize_t n = ::readv(fd, vec, iovcnt); - if (n < 0) - { - *retErrno = errno; - } - else if (static_cast(n) <= writable) - { - tail_ += n; - } - else - { - tail_ = buffer_.size(); - append(extBuffer, n - writable); - } - return n; -} - -std::string MsgBuffer::read(size_t len) -{ - if (len > readableBytes()) - len = readableBytes(); - std::string ret(peek(), len); - retrieve(len); - return ret; -} -uint8_t MsgBuffer::readInt8() -{ - uint8_t ret = peekInt8(); - retrieve(1); - return ret; -} -uint16_t MsgBuffer::readInt16() -{ - uint16_t ret = peekInt16(); - retrieve(2); - return ret; -} -uint32_t MsgBuffer::readInt32() -{ - uint32_t ret = peekInt32(); - retrieve(4); - return ret; -} -uint64_t MsgBuffer::readInt64() -{ - uint64_t ret = peekInt64(); - retrieve(8); - return ret; -} - -void MsgBuffer::addInFront(const char *buf, size_t len) -{ - if (head_ >= len) - { - memcpy(begin() + head_ - len, buf, len); - head_ -= len; - return; - } - if (len <= writableBytes()) - { - std::copy(begin() + head_, begin() + tail_, begin() + head_ + len); - memcpy(begin() + head_, buf, len); - tail_ += len; - return; - } - size_t newLen; - if (len + readableBytes() < initCap_) - newLen = initCap_; - else - newLen = len + readableBytes(); - MsgBuffer newBuf(newLen); - newBuf.append(buf, len); - newBuf.append(*this); - swap(newBuf); -} diff --git a/modules/trantor/trantor/utils/MsgBuffer.h b/modules/trantor/trantor/utils/MsgBuffer.h deleted file mode 100644 index 33c8633..0000000 --- a/modules/trantor/trantor/utils/MsgBuffer.h +++ /dev/null @@ -1,376 +0,0 @@ -/** - * - * @file MsgBuffer.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _WIN32 -using ssize_t = long long; -#endif - -namespace trantor -{ -static constexpr size_t kBufferDefaultLength{2048}; -static constexpr char CRLF[]{"\r\n"}; - -/** - * @brief This class represents a memory buffer used for sending and receiving - * data. - * - */ -class TRANTOR_EXPORT MsgBuffer -{ - public: - /** - * @brief Construct a new message buffer instance. - * - * @param len The initial size of the buffer. - */ - MsgBuffer(size_t len = kBufferDefaultLength); - - /** - * @brief Get the beginning of the buffer. - * - * @return const char* - */ - const char *peek() const - { - return begin() + head_; - } - - /** - * @brief Get the end of the buffer where new data can be written. - * - * @return const char* - */ - const char *beginWrite() const - { - return begin() + tail_; - } - char *beginWrite() - { - return begin() + tail_; - } - - /** - * @brief Get a byte value from the buffer. - * - * @return uint8_t - */ - uint8_t peekInt8() const - { - assert(readableBytes() >= 1); - return *(static_cast((void *)peek())); - } - - /** - * @brief Get a unsigned short value from the buffer. - * - * @return uint16_t - */ - uint16_t peekInt16() const; - - /** - * @brief Get a unsigned int value from the buffer. - * - * @return uint32_t - */ - uint32_t peekInt32() const; - - /** - * @brief Get a unsigned int64 value from the buffer. - * - * @return uint64_t - */ - uint64_t peekInt64() const; - - /** - * @brief Get and remove some bytes from the buffer. - * - * @param len - * @return std::string - */ - std::string read(size_t len); - - /** - * @brief Get the remove a byte value from the buffer. - * - * @return uint8_t - */ - uint8_t readInt8(); - - /** - * @brief Get and remove a unsigned short value from the buffer. - * - * @return uint16_t - */ - uint16_t readInt16(); - - /** - * @brief Get and remove a unsigned int value from the buffer. - * - * @return uint32_t - */ - uint32_t readInt32(); - - /** - * @brief Get and remove a unsigned int64 value from the buffer. - * - * @return uint64_t - */ - uint64_t readInt64(); - - /** - * @brief swap the buffer with another. - * - * @param buf - */ - void swap(MsgBuffer &buf) noexcept; - - /** - * @brief Return the size of the data in the buffer. - * - * @return size_t - */ - size_t readableBytes() const - { - return tail_ - head_; - } - - /** - * @brief Return the size of the empty part in the buffer - * - * @return size_t - */ - size_t writableBytes() const - { - return buffer_.size() - tail_; - } - - /** - * @brief Append new data to the buffer. - * - */ - void append(const MsgBuffer &buf); - template - void append(const char (&buf)[N]) - { - assert(strnlen(buf, N) == N - 1); - append(buf, N - 1); - } - void append(const char *buf, size_t len); - void append(const std::string &buf) - { - append(buf.c_str(), buf.length()); - } - - /** - * @brief Append a byte value to the end of the buffer. - * - * @param b - */ - void appendInt8(const uint8_t b) - { - append(static_cast((void *)&b), 1); - } - - /** - * @brief Append a unsigned short value to the end of the buffer. - * - * @param s - */ - void appendInt16(const uint16_t s); - - /** - * @brief Append a unsigned int value to the end of the buffer. - * - * @param i - */ - void appendInt32(const uint32_t i); - - /** - * @brief Appaend a unsigned int64 value to the end of the buffer. - * - * @param l - */ - void appendInt64(const uint64_t l); - - /** - * @brief Put new data to the beginning of the buffer. - * - * @param buf - * @param len - */ - void addInFront(const char *buf, size_t len); - - /** - * @brief Put a byte value to the beginning of the buffer. - * - * @param b - */ - void addInFrontInt8(const uint8_t b) - { - addInFront(static_cast((void *)&b), 1); - } - - /** - * @brief Put a unsigned short value to the beginning of the buffer. - * - * @param s - */ - void addInFrontInt16(const uint16_t s); - - /** - * @brief Put a unsigned int value to the beginning of the buffer. - * - * @param i - */ - void addInFrontInt32(const uint32_t i); - - /** - * @brief Put a unsigned int64 value to the beginning of the buffer. - * - * @param l - */ - void addInFrontInt64(const uint64_t l); - - /** - * @brief Remove all data in the buffer. - * - */ - void retrieveAll(); - - /** - * @brief Remove some bytes in the buffer. - * - * @param len - */ - void retrieve(size_t len); - - /** - * @brief Read data from a file descriptor and put it into the buffer.˝ - * - * @param fd The file descriptor. It is usually a socket. - * @param retErrno The error code when reading. - * @return ssize_t The number of bytes read from the file descriptor. -1 is - * returned when an error occurs. - */ - ssize_t readFd(int fd, int *retErrno); - - /** - * @brief Remove the data before a certain position from the buffer. - * - * @param end The position. - */ - void retrieveUntil(const char *end) - { - assert(peek() <= end); - assert(end <= beginWrite()); - retrieve(end - peek()); - } - - /** - * @brief Find the position of the buffer where the CRLF is found. - * - * @return const char* - */ - const char *findCRLF() const - { - const char *crlf = std::search(peek(), beginWrite(), CRLF, CRLF + 2); - return crlf == beginWrite() ? NULL : crlf; - } - - /** - * @brief Make sure the buffer has enough spaces to write data. - * - * @param len - */ - void ensureWritableBytes(size_t len); - - /** - * @brief Move the write pointer forward when the new data has been written - * to the buffer. - * - * @param len - */ - void hasWritten(size_t len) - { - assert(len <= writableBytes()); - tail_ += len; - } - - /** - * @brief Move the write pointer backward to remove data in the end of the - * buffer. - * - * @param offset - */ - void unwrite(size_t offset) - { - assert(readableBytes() >= offset); - tail_ -= offset; - } - - /** - * @brief Access a byte in the buffer. - * - * @param offset - * @return const char& - */ - const char &operator[](size_t offset) const - { - assert(readableBytes() >= offset); - return peek()[offset]; - } - char &operator[](size_t offset) - { - assert(readableBytes() >= offset); - return begin()[head_ + offset]; - } - - private: - size_t head_; - size_t initCap_; - std::vector buffer_; - size_t tail_; - const char *begin() const - { - return &buffer_[0]; - } - char *begin() - { - return &buffer_[0]; - } -}; - -inline void swap(MsgBuffer &one, MsgBuffer &two) noexcept -{ - one.swap(two); -} -} // namespace trantor - -namespace std -{ -template <> -inline void swap(trantor::MsgBuffer &one, trantor::MsgBuffer &two) noexcept -{ - one.swap(two); -} -} // namespace std diff --git a/modules/trantor/trantor/utils/NonCopyable.h b/modules/trantor/trantor/utils/NonCopyable.h deleted file mode 100644 index 5c0af62..0000000 --- a/modules/trantor/trantor/utils/NonCopyable.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * - * @file NonCopyable.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include - -namespace trantor -{ -/** - * @brief This class represents a non-copyable object. - * - */ -class TRANTOR_EXPORT NonCopyable -{ - protected: - NonCopyable() - { - } - ~NonCopyable() - { - } - NonCopyable(const NonCopyable &) = delete; - NonCopyable &operator=(const NonCopyable &) = delete; - // some uncopyable classes maybe support move constructor.... - NonCopyable(NonCopyable &&) noexcept(true) = default; - NonCopyable &operator=(NonCopyable &&) noexcept(true) = default; -}; - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/ObjectPool.h b/modules/trantor/trantor/utils/ObjectPool.h deleted file mode 100644 index 145a355..0000000 --- a/modules/trantor/trantor/utils/ObjectPool.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * - * @file ObjectPool.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace trantor -{ -/** - * @brief This class template represents a object pool. - * - * @tparam T - */ -template -class ObjectPool : public NonCopyable, - public std::enable_shared_from_this> -{ - public: - std::shared_ptr getObject() - { - static_assert(!std::is_pointer::value, - "The parameter type of the ObjectPool template can't be " - "pointer type"); - T *p{nullptr}; - { - std::lock_guard lock(mtx_); - if (!objs_.empty()) - { - p = objs_.back(); - objs_.pop_back(); - } - } - - if (p == nullptr) - { - p = new T; - } - - assert(p); - std::weak_ptr> weakPtr = this->shared_from_this(); - auto obj = std::shared_ptr(p, [weakPtr](T *ptr) { - auto self = weakPtr.lock(); - if (self) - { - std::lock_guard lock(self->mtx_); - self->objs_.push_back(ptr); - } - else - { - delete ptr; - } - }); - return obj; - } - - private: - std::vector objs_; - std::mutex mtx_; -}; -} // namespace trantor \ No newline at end of file diff --git a/modules/trantor/trantor/utils/SerialTaskQueue.cc b/modules/trantor/trantor/utils/SerialTaskQueue.cc deleted file mode 100644 index 4b989cc..0000000 --- a/modules/trantor/trantor/utils/SerialTaskQueue.cc +++ /dev/null @@ -1,56 +0,0 @@ -/** - * - * SerialTaskQueue.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include -#ifdef __linux__ -#include -#endif -namespace trantor -{ -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 &task) -{ - loopThread_.getLoop()->runInLoop(task); -} -void SerialTaskQueue::runTaskInQueue(std::function &&task) -{ - loopThread_.getLoop()->runInLoop(std::move(task)); -} - -void SerialTaskQueue::waitAllTasksFinished() -{ - syncTaskInQueue([]() { - - }); -} - -} // namespace trantor diff --git a/modules/trantor/trantor/utils/SerialTaskQueue.h b/modules/trantor/trantor/utils/SerialTaskQueue.h deleted file mode 100644 index 04742bb..0000000 --- a/modules/trantor/trantor/utils/SerialTaskQueue.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * - * SerialTaskQueue.h - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include "TaskQueue.h" -#include -#include -#include -#include -#include -#include -namespace trantor -{ -/** - * @brief This class represents a task queue in which all tasks are executed one - * by one. - * - */ -class TRANTOR_EXPORT SerialTaskQueue : public TaskQueue -{ - public: - /** - * @brief Run a task in the queue. - * - * @param task - */ - virtual void runTaskInQueue(const std::function &task); - virtual void runTaskInQueue(std::function &&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}; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/utils/TaskQueue.h b/modules/trantor/trantor/utils/TaskQueue.h deleted file mode 100644 index fb656d5..0000000 --- a/modules/trantor/trantor/utils/TaskQueue.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * - * @file TaskQueue.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include "NonCopyable.h" -#include -#include -#include -namespace trantor -{ -/** - * @brief This class is a pure virtual class that can be implemented as a - * SerialTaskQueue or a ConcurrentTaskQueue. - * - */ -class TaskQueue : public NonCopyable -{ - public: - virtual void runTaskInQueue(const std::function &task) = 0; - virtual void runTaskInQueue(std::function &&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 &task) - { - std::promise prom; - std::future fut = prom.get_future(); - runTaskInQueue([&]() { - task(); - prom.set_value(1); - }); - fut.get(); - }; - virtual ~TaskQueue() - { - } -}; -} // namespace trantor diff --git a/modules/trantor/trantor/utils/TimingWheel.cc b/modules/trantor/trantor/utils/TimingWheel.cc deleted file mode 100644 index 3ee3ec7..0000000 --- a/modules/trantor/trantor/utils/TimingWheel.cc +++ /dev/null @@ -1,126 +0,0 @@ -/** - * - * TimingWheel.cc - * An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include - -using namespace trantor; - -TimingWheel::TimingWheel(trantor::EventLoop *loop, - size_t maxTimeout, - float ticksInterval, - size_t bucketsNumPerWheel) - : loop_(loop), - ticksInterval_(ticksInterval), - bucketsNumPerWheel_(bucketsNumPerWheel) -{ - assert(maxTimeout > 1); - assert(ticksInterval > 0); - assert(bucketsNumPerWheel_ > 1); - size_t maxTickNum = static_cast(maxTimeout / ticksInterval); - auto ticksNum = bucketsNumPerWheel; - wheelsNum_ = 1; - while (maxTickNum > ticksNum) - { - ++wheelsNum_; - ticksNum *= bucketsNumPerWheel_; - } - wheels_.resize(wheelsNum_); - for (size_t i = 0; i < wheelsNum_; ++i) - { - wheels_[i].resize(bucketsNumPerWheel_); - } - timerId_ = loop_->runEvery(ticksInterval_, [this]() { - ++ticksCounter_; - size_t t = ticksCounter_; - size_t pow = 1; - for (size_t i = 0; i < wheelsNum_; ++i) - { - if ((t % pow) == 0) - { - EntryBucket tmp; - { - // use tmp val to make this critical area as short as - // possible. - wheels_[i].front().swap(tmp); - wheels_[i].pop_front(); - wheels_[i].push_back(EntryBucket()); - } - } - pow = pow * bucketsNumPerWheel_; - } - }); -} - -TimingWheel::~TimingWheel() -{ - loop_->assertInLoopThread(); - loop_->invalidateTimer(timerId_); - for (auto iter = wheels_.rbegin(); iter != wheels_.rend(); ++iter) - { - iter->clear(); - } - LOG_TRACE << "TimingWheel destruct!"; -} - -void TimingWheel::insertEntry(size_t delay, EntryPtr entryPtr) -{ - if (delay <= 0) - return; - if (!entryPtr) - return; - if (loop_->isInLoopThread()) - { - insertEntryInloop(delay, entryPtr); - } - else - { - loop_->runInLoop( - [this, delay, entryPtr]() { insertEntryInloop(delay, entryPtr); }); - } -} - -void TimingWheel::insertEntryInloop(size_t delay, EntryPtr entryPtr) -{ - loop_->assertInLoopThread(); - - delay = static_cast(delay / ticksInterval_ + 1); - size_t t = ticksCounter_; - for (size_t i = 0; i < wheelsNum_; ++i) - { - if (delay <= bucketsNumPerWheel_) - { - wheels_[i][delay - 1].insert(entryPtr); - break; - } - if (i < (wheelsNum_ - 1)) - { - entryPtr = std::make_shared( - [this, delay, i, t, entryPtr]() { - if (delay > 0) - { - wheels_[i][(delay + (t % bucketsNumPerWheel_) - 1) % - bucketsNumPerWheel_] - .insert(entryPtr); - } - }); - } - else - { - // delay is too long to put entry at valid position in wheels; - wheels_[i][bucketsNumPerWheel_ - 1].insert(entryPtr); - } - delay = (delay + (t % bucketsNumPerWheel_) - 1) / bucketsNumPerWheel_; - t = t / bucketsNumPerWheel_; - } -} \ No newline at end of file diff --git a/modules/trantor/trantor/utils/TimingWheel.h b/modules/trantor/trantor/utils/TimingWheel.h deleted file mode 100644 index 55f7fe0..0000000 --- a/modules/trantor/trantor/utils/TimingWheel.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * - * @file TimingWheel.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TIMING_BUCKET_NUM_PER_WHEEL 100 -#define TIMING_TICK_INTERVAL 1.0 - -namespace trantor -{ -using EntryPtr = std::shared_ptr; - -using EntryBucket = std::unordered_set; -using BucketQueue = std::deque; - -/** - * @brief This class implements a timer strategy with high performance and low - * accuracy. This is usually used internally. - * - */ -class TRANTOR_EXPORT TimingWheel -{ - public: - class CallbackEntry - { - public: - CallbackEntry(std::function cb) : cb_(std::move(cb)) - { - } - ~CallbackEntry() - { - cb_(); - } - - private: - std::function cb_; - }; - - /** - * @brief Construct a new timing wheel instance. - * - * @param loop The event loop in which the timing wheel runs. - * @param maxTimeout The maximum timeout of the timing wheel. - * @param ticksInterval The internal timer tick interval. It affects the - * accuracy of the timing wheel. - * @param bucketsNumPerWheel The number of buckets per wheel. - * @note The max delay of the timing wheel is about - * ticksInterval*(bucketsNumPerWheel^wheelsNum) seconds. - * @example Four wheels with 200 buckets per wheel means the timing wheel - * can work with a timeout up to 200^4 seconds, about 50 years; - */ - TimingWheel(trantor::EventLoop *loop, - size_t maxTimeout, - float ticksInterval = TIMING_TICK_INTERVAL, - size_t bucketsNumPerWheel = TIMING_BUCKET_NUM_PER_WHEEL); - - void insertEntry(size_t delay, EntryPtr entryPtr); - - void insertEntryInloop(size_t delay, EntryPtr entryPtr); - - EventLoop *getLoop() - { - return loop_; - } - - ~TimingWheel(); - - private: - std::vector wheels_; - - std::atomic ticksCounter_{0}; - - trantor::TimerId timerId_; - trantor::EventLoop *loop_; - - float ticksInterval_; - size_t wheelsNum_; - size_t bucketsNumPerWheel_; -}; -} // namespace trantor diff --git a/modules/trantor/trantor/utils/WindowsSupport.cc b/modules/trantor/trantor/utils/WindowsSupport.cc deleted file mode 100644 index 78d6810..0000000 --- a/modules/trantor/trantor/utils/WindowsSupport.cc +++ /dev/null @@ -1,55 +0,0 @@ -/** - * - * WindowsSupport.cc - * An Tao - * - * Implementation of Windows support functions. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#include -#include - -// from polipo -int win32_read_socket(int fd, void *buf, int n) -{ - int rc = recv(fd, reinterpret_cast(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; -} diff --git a/modules/trantor/trantor/utils/WindowsSupport.h b/modules/trantor/trantor/utils/WindowsSupport.h deleted file mode 100644 index 9081df8..0000000 --- a/modules/trantor/trantor/utils/WindowsSupport.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * - * @file WindowsSupport.h - * @author An Tao - * - * Public header file in trantor lib. - * - * Copyright 2018, An Tao. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the License file. - * - * - */ - -#pragma once - -#include -#include - -struct iovec -{ - void *iov_base; /* Starting address */ - int iov_len; /* Number of bytes */ -}; - -TRANTOR_EXPORT int readv(int fd, const struct iovec *vector, int count);