mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-14 04:57:21 +01:00
292 lines
5.8 KiB
C++
292 lines
5.8 KiB
C++
/**
|
|
*
|
|
* @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 "core/log/logger.h"
|
|
#include <assert.h>
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
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 Channel {
|
|
protected:
|
|
Channel(const Channel &) = delete;
|
|
Channel &operator=(const Channel &) = delete;
|
|
// some uncopyable classes maybe support move constructor....
|
|
Channel(Channel &&) noexcept(true) = default;
|
|
Channel &operator=(Channel &&) noexcept(true) = default;
|
|
|
|
public:
|
|
using EventCallback = std::function<void()>;
|
|
/**
|
|
* @brief Construct a new Channel instance.
|
|
*
|
|
* @param loop The event loop in which the channel works.
|
|
* @param fd The socket fd.
|
|
*/
|
|
Channel(EventLoop *loop, int fd);
|
|
|
|
/**
|
|
* @brief Set the read callback.
|
|
*
|
|
* @param cb The callback is called when read event occurs on the socket.
|
|
* @note One should call the enableReading() method to ensure that the
|
|
* callback would be called when some data is received on the socket.
|
|
*/
|
|
void setReadCallback(const EventCallback &cb) {
|
|
readCallback_ = cb;
|
|
};
|
|
void setReadCallback(EventCallback &&cb) {
|
|
readCallback_ = std::move(cb);
|
|
}
|
|
|
|
/**
|
|
* @brief Set the write callback.
|
|
*
|
|
* @param cb The callback is called when write event occurs on the socket.
|
|
* @note One should call the enableWriting() method to ensure that the
|
|
* callback would be called when the socket can be written.
|
|
*/
|
|
void setWriteCallback(const EventCallback &cb) {
|
|
writeCallback_ = cb;
|
|
};
|
|
void setWriteCallback(EventCallback &&cb) {
|
|
writeCallback_ = std::move(cb);
|
|
}
|
|
|
|
/**
|
|
* @brief Set the close callback.
|
|
*
|
|
* @param cb The callback is called when the socket is closed.
|
|
*/
|
|
void setCloseCallback(const EventCallback &cb) {
|
|
closeCallback_ = cb;
|
|
}
|
|
void setCloseCallback(EventCallback &&cb) {
|
|
closeCallback_ = std::move(cb);
|
|
}
|
|
|
|
/**
|
|
* @brief Set the error callback.
|
|
*
|
|
* @param cb The callback is called when an error occurs on the socket.
|
|
*/
|
|
void setErrorCallback(const EventCallback &cb) {
|
|
errorCallback_ = cb;
|
|
}
|
|
void setErrorCallback(EventCallback &&cb) {
|
|
errorCallback_ = std::move(cb);
|
|
}
|
|
|
|
/**
|
|
* @brief Set the event callback.
|
|
*
|
|
* @param cb The callback is called when any event occurs on the socket.
|
|
* @note If the event callback is set to the channel, any other callback
|
|
* wouldn't be called again.
|
|
*/
|
|
void setEventCallback(const EventCallback &cb) {
|
|
eventCallback_ = cb;
|
|
}
|
|
void setEventCallback(EventCallback &&cb) {
|
|
eventCallback_ = std::move(cb);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the fd of the socket.
|
|
*
|
|
* @return int
|
|
*/
|
|
int fd() const {
|
|
return fd_;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the events enabled on the socket.
|
|
*
|
|
* @return int
|
|
*/
|
|
int events() const {
|
|
return events_;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the events that occurred on the socket.
|
|
*
|
|
* @return int
|
|
*/
|
|
int revents() const {
|
|
return revents_;
|
|
}
|
|
|
|
/**
|
|
* @brief Check whether there is no event enabled on the socket.
|
|
*
|
|
* @return true
|
|
* @return false
|
|
*/
|
|
bool isNoneEvent() const {
|
|
return events_ == kNoneEvent;
|
|
};
|
|
|
|
/**
|
|
* @brief Disable all events on the socket.
|
|
*
|
|
*/
|
|
void disableAll() {
|
|
events_ = kNoneEvent;
|
|
update();
|
|
}
|
|
|
|
/**
|
|
* @brief Remove the socket from the poller in the event loop.
|
|
*
|
|
*/
|
|
void remove();
|
|
|
|
/**
|
|
* @brief Return the event loop.
|
|
*
|
|
* @return EventLoop*
|
|
*/
|
|
EventLoop *ownerLoop() {
|
|
return loop_;
|
|
};
|
|
|
|
/**
|
|
* @brief Enable the read event on the socket.
|
|
*
|
|
*/
|
|
void enableReading() {
|
|
events_ |= kReadEvent;
|
|
update();
|
|
}
|
|
|
|
/**
|
|
* @brief Disable the read event on the socket.
|
|
*
|
|
*/
|
|
void disableReading() {
|
|
events_ &= ~kReadEvent;
|
|
update();
|
|
}
|
|
|
|
/**
|
|
* @brief Enable the write event on the socket.
|
|
*
|
|
*/
|
|
void enableWriting() {
|
|
events_ |= kWriteEvent;
|
|
update();
|
|
}
|
|
|
|
/**
|
|
* @brief Disable the write event on the socket.
|
|
*
|
|
*/
|
|
void disableWriting() {
|
|
events_ &= ~kWriteEvent;
|
|
update();
|
|
}
|
|
|
|
/**
|
|
* @brief Check whether the write event is enabled on the socket.
|
|
*
|
|
* @return true
|
|
* @return false
|
|
*/
|
|
bool isWriting() const {
|
|
return events_ & kWriteEvent;
|
|
}
|
|
|
|
/**
|
|
* @brief Check whether the read event is enabled on the socket.
|
|
*
|
|
* @return true
|
|
* @return false
|
|
*/
|
|
bool isReading() const {
|
|
return events_ & kReadEvent;
|
|
}
|
|
|
|
/**
|
|
* @brief Set and update the events enabled.
|
|
*
|
|
* @param events
|
|
*/
|
|
void updateEvents(int events) {
|
|
events_ = events;
|
|
update();
|
|
}
|
|
|
|
/**
|
|
* @brief This method is used to ensure that the callback owner is valid
|
|
* when a callback is called.
|
|
*
|
|
* @param obj The callback owner. Usually, the owner is also the owner of
|
|
* the channel.
|
|
* @note The 'obj' is kept in a weak_ptr object, so this method does not
|
|
* cause a circular reference problem.
|
|
*/
|
|
void tie(const std::shared_ptr<void> &obj) {
|
|
tie_ = obj;
|
|
tied_ = true;
|
|
}
|
|
|
|
static const int kNoneEvent;
|
|
static const int kReadEvent;
|
|
static const int kWriteEvent;
|
|
|
|
private:
|
|
friend class EventLoop;
|
|
friend class EpollPoller;
|
|
friend class KQueue;
|
|
void update();
|
|
void handleEvent();
|
|
void handleEventSafely();
|
|
int setRevents(int revt) {
|
|
// LOG_TRACE<<"revents="<<revt;
|
|
revents_ = revt;
|
|
return revt;
|
|
};
|
|
int index() {
|
|
return index_;
|
|
};
|
|
void setIndex(int index) {
|
|
index_ = index;
|
|
};
|
|
EventLoop *loop_;
|
|
const int fd_;
|
|
int events_;
|
|
int revents_;
|
|
int index_;
|
|
bool addedToLoop_{ false };
|
|
EventCallback readCallback_;
|
|
EventCallback writeCallback_;
|
|
EventCallback errorCallback_;
|
|
EventCallback closeCallback_;
|
|
EventCallback eventCallback_;
|
|
std::weak_ptr<void> tie_;
|
|
bool tied_;
|
|
};
|
|
} // namespace trantor
|