mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-24 01:42:22 +08:00
添加win测试程序
This commit is contained in:
246
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/Socket.h
Executable file
246
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/Socket.h
Executable file
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// Socket.h
|
||||
// xzl
|
||||
//
|
||||
// Created by xzl on 16/4/13.
|
||||
//
|
||||
|
||||
#ifndef Socket_h
|
||||
#define Socket_h
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include "Util/util.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Poller/Timer.h"
|
||||
#include "Network/sockutil.h"
|
||||
#include "Thread/spin_mutex.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
using namespace ZL::Poller;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Network {
|
||||
|
||||
#if defined(MSG_NOSIGNAL)
|
||||
#define FLAG_NOSIGNAL MSG_NOSIGNAL
|
||||
#else
|
||||
#define FLAG_NOSIGNAL 0
|
||||
#endif //MSG_NOSIGNAL
|
||||
|
||||
#if defined(MSG_MORE)
|
||||
#define FLAG_MORE MSG_MORE
|
||||
#else
|
||||
#define FLAG_MORE 0
|
||||
#endif //MSG_MORE
|
||||
|
||||
#if defined(MSG_DONTWAIT)
|
||||
#define FLAG_DONTWAIT MSG_DONTWAIT
|
||||
#else
|
||||
#define FLAG_DONTWAIT 0
|
||||
#endif //MSG_DONTWAIT
|
||||
|
||||
#define TCP_DEFAULE_FLAGS (FLAG_NOSIGNAL | FLAG_DONTWAIT)
|
||||
#define UDP_DEFAULE_FLAGS (FLAG_NOSIGNAL | FLAG_DONTWAIT)
|
||||
|
||||
#define MAX_SEND_PKT (256)
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#import "TargetConditionals.h"
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
#define OS_IPHONE
|
||||
#elif TARGET_OS_IPHONE
|
||||
#define OS_IPHONE
|
||||
#endif
|
||||
#endif //__APPLE__
|
||||
|
||||
typedef enum {
|
||||
Err_success = 0, //成功
|
||||
Err_eof, //eof
|
||||
Err_timeout, //超时
|
||||
Err_refused,
|
||||
Err_dns,
|
||||
Err_other,
|
||||
} ErrCode;
|
||||
|
||||
class SockException: public std::exception {
|
||||
public:
|
||||
SockException(ErrCode _errCode = Err_success, const string &_errMsg = "") {
|
||||
errMsg = _errMsg;
|
||||
errCode = _errCode;
|
||||
}
|
||||
void reset(ErrCode _errCode, const string &_errMsg) {
|
||||
errMsg = _errMsg;
|
||||
errCode = _errCode;
|
||||
}
|
||||
virtual const char* what() const noexcept {
|
||||
return errMsg.c_str();
|
||||
}
|
||||
|
||||
ErrCode getErrCode() const {
|
||||
return errCode;
|
||||
}
|
||||
operator bool() const{
|
||||
return errCode != Err_success;
|
||||
}
|
||||
private:
|
||||
string errMsg;
|
||||
ErrCode errCode;
|
||||
};
|
||||
class SockFD
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<SockFD> Ptr;
|
||||
SockFD(int sock){
|
||||
_sock = sock;
|
||||
}
|
||||
virtual ~SockFD(){
|
||||
::shutdown(_sock, SHUT_RDWR);
|
||||
#if defined (OS_IPHONE)
|
||||
unsetSocketOfIOS(_sock);
|
||||
#endif //OS_IPHONE
|
||||
int fd = _sock;
|
||||
EventPoller::Instance().delEvent(fd,[fd](bool){
|
||||
close(fd);
|
||||
});
|
||||
}
|
||||
void setConnected(){
|
||||
#if defined (OS_IPHONE)
|
||||
setSocketOfIOS(_sock);
|
||||
#endif //OS_IPHONE
|
||||
}
|
||||
int rawFd() const{
|
||||
return _sock;
|
||||
}
|
||||
private:
|
||||
int _sock;
|
||||
|
||||
#if defined (OS_IPHONE)
|
||||
void *readStream=NULL;
|
||||
void *writeStream=NULL;
|
||||
bool setSocketOfIOS(int socket);
|
||||
void unsetSocketOfIOS(int socket);
|
||||
#endif //OS_IPHONE
|
||||
};
|
||||
|
||||
class Socket: public std::enable_shared_from_this<Socket> {
|
||||
public:
|
||||
class Buffer {
|
||||
public:
|
||||
typedef std::shared_ptr<Buffer> Ptr;
|
||||
Buffer(uint32_t size) {
|
||||
_size = size;
|
||||
_data = new char[size];
|
||||
}
|
||||
virtual ~Buffer() {
|
||||
delete[] _data;
|
||||
}
|
||||
const char *data() const {
|
||||
return _data;
|
||||
}
|
||||
uint32_t size() const {
|
||||
return _size;
|
||||
}
|
||||
private:
|
||||
friend class Socket;
|
||||
char *_data;
|
||||
uint32_t _size;
|
||||
};
|
||||
typedef std::shared_ptr<Socket> Ptr;
|
||||
typedef function<void(const Buffer::Ptr &buf, struct sockaddr *addr)> onReadCB;
|
||||
typedef function<void(const SockException &err)> onErrCB;
|
||||
typedef function<void(Socket::Ptr &sock)> onAcceptCB;
|
||||
typedef function<bool()> onFlush;
|
||||
|
||||
Socket();
|
||||
virtual ~Socket();
|
||||
int rawFD() const{
|
||||
SockFD::Ptr sock;
|
||||
{
|
||||
lock_guard<spin_mutex> lck(_mtx_sockFd);
|
||||
sock = _sockFd;
|
||||
}
|
||||
if(!sock){
|
||||
return -1;
|
||||
}
|
||||
return sock->rawFd();
|
||||
}
|
||||
void connect(const string &url, uint16_t port, onErrCB &&connectCB, int timeoutSec = 5);
|
||||
bool listen(const uint16_t port, const char *localIp = "0.0.0.0", int backLog = 1024);
|
||||
bool bindUdpSock(const uint16_t port, const char *localIp = "0.0.0.0");
|
||||
|
||||
void setOnRead(const onReadCB &cb);
|
||||
void setOnErr(const onErrCB &cb);
|
||||
void setOnAccept(const onAcceptCB &cb);
|
||||
void setOnFlush(const onFlush &cb);
|
||||
|
||||
int send(const char *buf, int size = 0,int flags = TCP_DEFAULE_FLAGS);
|
||||
int send(const string &buf,int flags = TCP_DEFAULE_FLAGS);
|
||||
int sendTo(const char *buf, int size, struct sockaddr *peerAddr,int flags = UDP_DEFAULE_FLAGS);
|
||||
int sendTo(const string &buf, struct sockaddr *peerAddr,int flags = UDP_DEFAULE_FLAGS);
|
||||
bool emitErr(const SockException &err);
|
||||
void enableRecv(bool enabled);
|
||||
|
||||
string get_local_ip();
|
||||
uint16_t get_local_port();
|
||||
string get_peer_ip();
|
||||
uint16_t get_peer_port();
|
||||
|
||||
void setSendPktSize(uint32_t iPktSize){
|
||||
_iMaxSendPktSize = iPktSize;
|
||||
}
|
||||
private:
|
||||
mutable spin_mutex _mtx_sockFd;
|
||||
SockFD::Ptr _sockFd;
|
||||
//send buffer
|
||||
recursive_mutex _mtx_sendBuf;
|
||||
deque<string> _sendPktBuf;
|
||||
deque<struct sockaddr> _udpSendPeer;
|
||||
/////////////////////
|
||||
std::shared_ptr<Timer> _conTimer;
|
||||
struct sockaddr _peerAddr;
|
||||
spin_mutex _mtx_read;
|
||||
spin_mutex _mtx_err;
|
||||
spin_mutex _mtx_accept;
|
||||
spin_mutex _mtx_flush;
|
||||
onReadCB _readCB;
|
||||
onErrCB _errCB;
|
||||
onAcceptCB _acceptCB;
|
||||
onFlush _flushCB;
|
||||
Ticker _flushTicker;
|
||||
int _lastSendFlags = TCP_DEFAULE_FLAGS;
|
||||
uint32_t _iMaxSendPktSize = MAX_SEND_PKT;
|
||||
atomic_bool _enableRecv;
|
||||
|
||||
void closeSock();
|
||||
bool setPeerSock(int fd, struct sockaddr *addr);
|
||||
bool attachEvent(const SockFD::Ptr &pSock,bool isUdp = false);
|
||||
|
||||
int onAccept(const SockFD::Ptr &pSock,int event);
|
||||
int onRead(const SockFD::Ptr &pSock,bool mayEof=true);
|
||||
void onError(const SockFD::Ptr &pSock);
|
||||
int realSend(const string &buf, struct sockaddr *peerAddr,int flags);
|
||||
int onWrite(const SockFD::Ptr &pSock, bool bMainThread,int flags,bool isUdp);
|
||||
void onConnected(const SockFD::Ptr &pSock, const onErrCB &connectCB);
|
||||
void onFlushed(const SockFD::Ptr &pSock);
|
||||
|
||||
void startWriteEvent(const SockFD::Ptr &pSock);
|
||||
void stopWriteEvent(const SockFD::Ptr &pSock);
|
||||
bool sendTimeout(bool isUdp);
|
||||
SockFD::Ptr makeSock(int sock){
|
||||
return std::make_shared<SockFD>(sock);
|
||||
}
|
||||
static SockException getSockErr(const SockFD::Ptr &pSock,bool tryErrno=true);
|
||||
|
||||
};
|
||||
|
||||
} // namespace Network
|
||||
} // namespace ZL
|
||||
|
||||
#endif /* Socket_h */
|
||||
106
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpClient.h
Executable file
106
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpClient.h
Executable file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* TcpClient.h
|
||||
*
|
||||
* Created on: 2017年2月13日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef SRC_NETWORK_TCPCLIENT_H_
|
||||
#define SRC_NETWORK_TCPCLIENT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "Socket.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Thread/WorkThreadPool.h"
|
||||
#include "Thread/spin_mutex.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Network {
|
||||
|
||||
class TcpClient : public std::enable_shared_from_this<TcpClient> {
|
||||
public:
|
||||
typedef std::shared_ptr<TcpClient> Ptr;
|
||||
TcpClient();
|
||||
virtual ~TcpClient();
|
||||
protected:
|
||||
void startConnect(const string &strUrl, uint16_t iPort, int iTimeOutSec = 3);
|
||||
void shutdown();
|
||||
virtual int send(const string &str);
|
||||
virtual int send(const char *str, int len);
|
||||
bool alive() {
|
||||
lock_guard<spin_mutex> lck(m_mutex);
|
||||
return m_pSock.operator bool();
|
||||
}
|
||||
string get_local_ip() {
|
||||
decltype(m_pSock) sockTmp;
|
||||
{
|
||||
lock_guard<spin_mutex> lck(m_mutex);
|
||||
sockTmp = m_pSock;
|
||||
}
|
||||
if(!sockTmp){
|
||||
return "";
|
||||
}
|
||||
return sockTmp->get_local_ip();
|
||||
}
|
||||
uint16_t get_local_port() {
|
||||
decltype(m_pSock) sockTmp;
|
||||
{
|
||||
lock_guard<spin_mutex> lck(m_mutex);
|
||||
sockTmp = m_pSock;
|
||||
}
|
||||
if(!sockTmp){
|
||||
return 0;
|
||||
}
|
||||
return sockTmp->get_local_port();
|
||||
}
|
||||
string get_peer_ip() {
|
||||
decltype(m_pSock) sockTmp;
|
||||
{
|
||||
lock_guard<spin_mutex> lck(m_mutex);
|
||||
sockTmp = m_pSock;
|
||||
}
|
||||
if(!sockTmp){
|
||||
return "";
|
||||
}
|
||||
return sockTmp->get_peer_ip();
|
||||
}
|
||||
uint16_t get_peer_port() {
|
||||
decltype(m_pSock) sockTmp;
|
||||
{
|
||||
lock_guard<spin_mutex> lck(m_mutex);
|
||||
sockTmp = m_pSock;
|
||||
}
|
||||
if(!sockTmp){
|
||||
return 0;
|
||||
}
|
||||
return sockTmp->get_peer_port();
|
||||
}
|
||||
|
||||
uint64_t elapsedTime();
|
||||
|
||||
//链接成功后,客户端将绑定一个后台线程,并且onConnect/onRecv/onSend/onErr事件将在该后台线程触发
|
||||
virtual void onConnect(const SockException &ex) {}
|
||||
virtual void onRecv(const Socket::Buffer::Ptr &pBuf) {}
|
||||
virtual void onSend() {}
|
||||
virtual void onErr(const SockException &ex) {}
|
||||
Socket::Ptr m_pSock;
|
||||
private:
|
||||
Ticker m_ticker;
|
||||
spin_mutex m_mutex;
|
||||
|
||||
void onSockConnect(const SockException &ex);
|
||||
void onSockRecv(const Socket::Buffer::Ptr &pBuf);
|
||||
void onSockSend();
|
||||
void onSockErr(const SockException &ex);
|
||||
|
||||
};
|
||||
|
||||
} /* namespace Network */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SRC_NETWORK_TCPCLIENT_H_ */
|
||||
64
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpLimitedSession.h
Executable file
64
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpLimitedSession.h
Executable file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Session.h
|
||||
*
|
||||
* Created on: 2015年10月27日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef SERVER_LIMITEDSESSION_H_
|
||||
#define SERVER_LIMITEDSESSION_H_
|
||||
#include <memory>
|
||||
#include "Util/logger.h"
|
||||
#include "TcpSession.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
|
||||
namespace ZL {
|
||||
namespace Network {
|
||||
|
||||
template<int MaxCount>
|
||||
class TcpLimitedSession: public TcpSession {
|
||||
public:
|
||||
TcpLimitedSession(const std::shared_ptr<ThreadPool> &_th, const Socket::Ptr &_sock) :
|
||||
TcpSession(_th,_sock) {
|
||||
lock_guard<recursive_mutex> lck(stackMutex());
|
||||
static uint64_t maxSeq(0);
|
||||
sessionSeq = maxSeq++;
|
||||
auto &stack = getStack();
|
||||
stack.emplace(this);
|
||||
|
||||
if(stack.size() > MaxCount){
|
||||
auto it = stack.begin();
|
||||
(*it)->safeShutdown();
|
||||
stack.erase(it);
|
||||
WarnL << "超过TCP个数限制:" << MaxCount;
|
||||
}
|
||||
}
|
||||
virtual ~TcpLimitedSession() {
|
||||
lock_guard<recursive_mutex> lck(stackMutex());
|
||||
getStack().erase(this);
|
||||
}
|
||||
private:
|
||||
uint64_t sessionSeq; //会话栈顺序
|
||||
struct Comparer {
|
||||
bool operator()(TcpLimitedSession *x, TcpLimitedSession *y) const {
|
||||
return x->sessionSeq < y->sessionSeq;
|
||||
}
|
||||
};
|
||||
static recursive_mutex &stackMutex(){
|
||||
static recursive_mutex mtx;
|
||||
return mtx;
|
||||
}
|
||||
//RTSP会话栈,先创建的在前面
|
||||
static set<TcpLimitedSession *, Comparer> &getStack(){
|
||||
static set<TcpLimitedSession *, Comparer> stack;
|
||||
return stack;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace Session */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SERVER_LIMITEDSESSION_H_ */
|
||||
134
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpServer.h
Executable file
134
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpServer.h
Executable file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* TcpServer.h
|
||||
*
|
||||
* Created on: 2016年8月9日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef TCPSERVER_TCPSERVER_H_
|
||||
#define TCPSERVER_TCPSERVER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include "Socket.h"
|
||||
#include "Util/util.h"
|
||||
#include "Util/uv_errno.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Poller/Timer.h"
|
||||
#include "Thread/semaphore.h"
|
||||
#include "Thread/WorkThreadPool.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
using namespace ZL::Poller;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Network {
|
||||
|
||||
template<typename Session>
|
||||
class TcpServer {
|
||||
public:
|
||||
typedef std::shared_ptr<TcpServer> Ptr;
|
||||
TcpServer() {
|
||||
socket.reset(new Socket());
|
||||
sessionMap.reset(new typename decltype(sessionMap)::element_type);
|
||||
}
|
||||
|
||||
~TcpServer() {
|
||||
TraceL << "start clean...";
|
||||
timer.reset();
|
||||
socket.reset();
|
||||
|
||||
typename decltype(sessionMap)::element_type copyMap;
|
||||
sessionMap->swap(copyMap);
|
||||
for (auto it = copyMap.begin(); it != copyMap.end(); ++it) {
|
||||
auto session = it->second;
|
||||
it->second->async_first( [session]() {
|
||||
session->onError(SockException(Err_other,"Tcp server shutdown!"));
|
||||
});
|
||||
}
|
||||
TraceL << "clean completed!";
|
||||
}
|
||||
void start(uint16_t port, const std::string& host = "0.0.0.0", uint32_t backlog = 1024) {
|
||||
bool success = socket->listen(port, host.c_str(), backlog);
|
||||
if (!success) {
|
||||
string err = (StrPrinter << "listen on " << host << ":" << port << "] failed:" << get_uv_errmsg(true)).operator <<(endl);
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
socket->setOnAccept( bind(&TcpServer::onAcceptConnection, this, placeholders::_1));
|
||||
timer.reset(new Timer(2, [this]()->bool {
|
||||
this->onManagerSession();
|
||||
return true;
|
||||
}));
|
||||
InfoL << "TCP Server listening on " << host << ":" << port;
|
||||
}
|
||||
|
||||
private:
|
||||
Socket::Ptr socket;
|
||||
std::shared_ptr<Timer> timer;
|
||||
std::shared_ptr<std::unordered_map<Socket *, std::shared_ptr<Session> > > sessionMap;
|
||||
|
||||
void onAcceptConnection(const Socket::Ptr & sock) {
|
||||
// 接收到客户端连接请求
|
||||
auto session(std::make_shared<Session>(WorkThreadPool::Instance().getWorkThread(), sock));
|
||||
auto sockPtr(sock.get());
|
||||
auto sessionMapTmp(sessionMap);
|
||||
weak_ptr<Session> weakSession(session);
|
||||
sessionMapTmp->emplace(sockPtr, session);
|
||||
|
||||
// 会话接收数据事件
|
||||
sock->setOnRead([weakSession](const Socket::Buffer::Ptr &buf, struct sockaddr *addr){
|
||||
//获取会话强应用
|
||||
auto strongSession=weakSession.lock();
|
||||
if(!strongSession) {
|
||||
//会话对象已释放
|
||||
return;
|
||||
}
|
||||
//在会话线程中执行onRecv操作
|
||||
strongSession->async([weakSession,buf]() {
|
||||
auto strongSession=weakSession.lock();
|
||||
if(!strongSession) {
|
||||
return;
|
||||
}
|
||||
strongSession->onRecv(buf);
|
||||
});
|
||||
});
|
||||
|
||||
//会话接收到错误事件
|
||||
sock->setOnErr([weakSession,sockPtr,sessionMapTmp](const SockException &err){
|
||||
//获取会话强应用
|
||||
auto strongSession=weakSession.lock();
|
||||
//移除掉会话
|
||||
sessionMapTmp->erase(sockPtr);
|
||||
if(!strongSession) {
|
||||
//会话对象已释放
|
||||
return;
|
||||
}
|
||||
//在会话线程中执行onError操作
|
||||
strongSession->async_first([strongSession,err]() {
|
||||
strongSession->onError(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void onManagerSession() {
|
||||
//DebugL<<EventPoller::Instance().isMainThread();
|
||||
for (auto &pr : *sessionMap) {
|
||||
weak_ptr<Session> weakSession = pr.second;
|
||||
pr.second->async([weakSession]() {
|
||||
auto strongSession=weakSession.lock();
|
||||
if(!strongSession) {
|
||||
return;
|
||||
}
|
||||
strongSession->onManager();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace Network */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* TCPSERVER_TCPSERVER_H_ */
|
||||
91
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpSession.h
Executable file
91
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/TcpSession.h
Executable file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Session.h
|
||||
*
|
||||
* Created on: 2015年10月27日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef SERVER_SESSION_H_
|
||||
#define SERVER_SESSION_H_
|
||||
#include <memory>
|
||||
#include "Socket.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Thread/ThreadPool.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Network {
|
||||
|
||||
class TcpSession: public std::enable_shared_from_this<TcpSession> {
|
||||
public:
|
||||
TcpSession(const std::shared_ptr<ThreadPool> &_th, const Socket::Ptr &_sock) :
|
||||
sock(_sock), th(_th) {
|
||||
localIp = sock->get_local_ip();
|
||||
peerIp = sock->get_peer_ip();
|
||||
localPort = sock->get_local_port();
|
||||
peerPort = sock->get_peer_port();
|
||||
}
|
||||
virtual ~TcpSession() {
|
||||
}
|
||||
virtual void onRecv(const Socket::Buffer::Ptr &) =0;
|
||||
virtual void onError(const SockException &err) =0;
|
||||
virtual void onManager() =0;
|
||||
|
||||
template <typename T>
|
||||
void async(T &&task) {
|
||||
th->async(std::forward<T>(task));
|
||||
}
|
||||
template <typename T>
|
||||
void async_first(T &&task) {
|
||||
th->async_first(std::forward<T>(task));
|
||||
}
|
||||
|
||||
protected:
|
||||
const string& getLocalIp() const {
|
||||
return localIp;
|
||||
}
|
||||
const string& getPeerIp() const {
|
||||
return peerIp;
|
||||
}
|
||||
uint16_t getLocalPort() const {
|
||||
return localPort;
|
||||
}
|
||||
uint16_t getPeerPort() const {
|
||||
return peerPort;
|
||||
}
|
||||
virtual void shutdown() {
|
||||
sock->emitErr(SockException(Err_other, "self shutdown"));
|
||||
}
|
||||
void safeShutdown(){
|
||||
std::weak_ptr<TcpSession> weakSelf = shared_from_this();
|
||||
async_first([weakSelf](){
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if(strongSelf){
|
||||
strongSelf->shutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
virtual int send(const string &buf) {
|
||||
return sock->send(buf);
|
||||
}
|
||||
virtual int send(const char *buf, int size) {
|
||||
return sock->send(buf, size);
|
||||
}
|
||||
|
||||
Socket::Ptr sock;
|
||||
private:
|
||||
std::shared_ptr<ThreadPool> th;
|
||||
string localIp;
|
||||
string peerIp;
|
||||
uint16_t localPort;
|
||||
uint16_t peerPort;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace Session */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SERVER_SESSION_H_ */
|
||||
86
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/sockutil.h
Executable file
86
bin_lib/windows/ZLToolKit/include/ZLToolKit/Network/sockutil.h
Executable file
@@ -0,0 +1,86 @@
|
||||
#ifndef SOCKUTIL_H
|
||||
#define SOCKUTIL_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <WinSock2.h>
|
||||
#include <Iphlpapi.h>
|
||||
#pragma comment (lib,"WS2_32")
|
||||
#pragma comment(lib,"Iphlpapi.lib")
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#ifndef socklen_t
|
||||
#define socklen_t int
|
||||
#endif //!socklen_t
|
||||
#ifndef SHUT_RDWR
|
||||
#define SHUT_RDWR 2
|
||||
#endif //!SHUT_RDWR
|
||||
|
||||
int ioctl(int fd, long cmd, u_long *ptr);
|
||||
int close(int fd);
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
namespace ZL {
|
||||
namespace Network {
|
||||
|
||||
class SockUtil {
|
||||
public:
|
||||
static int connect(const char *host, uint16_t port, bool bAsync = true);
|
||||
static int listen(const uint16_t port, const char *localIp = "0.0.0.0",
|
||||
int backLog = 1024);
|
||||
static int bindUdpSock(const uint16_t port,
|
||||
const char *localIp = "0.0.0.0");
|
||||
static int setNoDelay(int sockFd, bool on = true);
|
||||
static int setNoSigpipe(int sock);
|
||||
static int setNoBlocked(int sock, bool noblock = true);
|
||||
static int setRecvBuf(int sock, int size = 256 * 1024);
|
||||
static int setSendBuf(int sock, int size = 256 * 1024);
|
||||
|
||||
static int setReuseable(int sockFd, bool on = true);
|
||||
static int setBroadcast(int sockFd, bool on = true);
|
||||
static int setKeepAlive(int sockFd, bool on = true);
|
||||
|
||||
//组播相关
|
||||
static int setMultiTTL(int sockFd, uint8_t ttl = 64);
|
||||
static int setMultiIF(int sockFd, const char *strLocalIp);
|
||||
static int setMultiLOOP(int sockFd, bool bAccept = false);
|
||||
static int joinMultiAddr(int sockFd, const char *strAddr, const char* strLocalIp = "0.0.0.0");
|
||||
static int leaveMultiAddr(int sockFd, const char *strAddr, const char* strLocalIp = "0.0.0.0");
|
||||
static int joinMultiAddrFilter(int sockFd, const char* strAddr, const char* strSrcIp, const char* strLocalIp = "0.0.0.0");
|
||||
static int leaveMultiAddrFilter(int sockFd, const char* strAddr, const char* strSrcIp, const char* strLocalIp = "0.0.0.0");
|
||||
|
||||
static int getSockError(int sockFd);
|
||||
static int setCloseWait(int sockFd, int second = 0);
|
||||
|
||||
static string get_local_ip(int fd);
|
||||
static string get_local_ip();
|
||||
static uint16_t get_local_port(int fd);
|
||||
static string get_peer_ip(int fd);
|
||||
static uint16_t get_peer_port(int fd);
|
||||
|
||||
static string get_ifr_name(const char *localIp);
|
||||
static string get_ifr_mask(const char *ifrName);
|
||||
static string get_ifr_brdaddr(const char *ifrName);
|
||||
static bool in_same_lan(const char *myIp, const char *dsrIp);
|
||||
};
|
||||
|
||||
} // namespace Network
|
||||
} // namespace ZL
|
||||
|
||||
#endif // !SOCKUTIL_H
|
||||
123
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/EventPoller.h
Executable file
123
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/EventPoller.h
Executable file
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// EventPoller.h
|
||||
// xzl
|
||||
//
|
||||
// Created by xzl on 16/4/12.
|
||||
//
|
||||
|
||||
#ifndef EventPoller_h
|
||||
#define EventPoller_h
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include "PipeWrap.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
#define HAS_EPOLL
|
||||
#endif //__linux__
|
||||
|
||||
namespace ZL {
|
||||
namespace Poller {
|
||||
|
||||
typedef enum {
|
||||
Event_Read = 1 << 0, //读事件
|
||||
Event_Write = 1 << 1, //写事件
|
||||
Event_Error = 1 << 2, //错误事件
|
||||
Event_LT = 1 << 3,//水平触发
|
||||
} Poll_Event;
|
||||
|
||||
typedef enum {
|
||||
Sig_Exit = 0, //关闭监听
|
||||
Sig_Async, //异步
|
||||
} Sigal_Type;
|
||||
|
||||
typedef function<void(int event)> PollEventCB;
|
||||
typedef function<void(bool success)> PollDelCB;
|
||||
typedef function<void(void)> PollAsyncCB;
|
||||
typedef PollAsyncCB PollSyncCB;
|
||||
|
||||
#ifndef HAS_EPOLL
|
||||
typedef struct {
|
||||
Poll_Event event;
|
||||
PollEventCB callBack;
|
||||
int attach;
|
||||
void operator()(int _event) const{
|
||||
callBack(_event);
|
||||
}
|
||||
void operator()() const{
|
||||
callBack(attach);
|
||||
}
|
||||
} Poll_Record;
|
||||
#endif //HAS_EPOLL
|
||||
|
||||
class EventPoller {
|
||||
public:
|
||||
EventPoller(bool enableSelfRun = false);
|
||||
virtual ~EventPoller();
|
||||
static EventPoller &Instance(bool enableSelfRun = false) {
|
||||
static EventPoller *instance(new EventPoller(enableSelfRun));
|
||||
return *instance;
|
||||
}
|
||||
static void Destory() {
|
||||
delete &EventPoller::Instance();
|
||||
}
|
||||
int addEvent(int fd, int event, PollEventCB &&eventCb);
|
||||
int delEvent(int fd, PollDelCB &&delCb = nullptr);
|
||||
int modifyEvent(int fd, int event);
|
||||
|
||||
void async(PollAsyncCB &&asyncCb);
|
||||
void sync(PollSyncCB &&syncCb);
|
||||
|
||||
void runLoop();
|
||||
void shutdown();
|
||||
bool isMainThread();
|
||||
private:
|
||||
void initPoll();
|
||||
inline int sigalPipe(uint64_t type, uint64_t i64_size = 0, uint64_t *buf = NULL);
|
||||
inline bool handlePipeEvent();
|
||||
inline Sigal_Type _handlePipeEvent(uint64_t type, uint64_t i64_size, uint64_t *buf);
|
||||
|
||||
PipeWrap _pipe;
|
||||
bool _exitLoop = false;
|
||||
thread *loopThread = nullptr;
|
||||
thread::id mainThreadId;
|
||||
mutex mtx_event_map;
|
||||
#if defined(HAS_EPOLL)
|
||||
int epoll_fd = -1;
|
||||
unordered_map<int, PollEventCB> event_map;
|
||||
#else
|
||||
unordered_map<int, Poll_Record> event_map;
|
||||
#endif //HAS_EPOLL
|
||||
string pipeBuffer;
|
||||
};
|
||||
|
||||
#define ASYNC_TRACE(...) {\
|
||||
/*TraceL;*/\
|
||||
EventPoller::Instance().async(__VA_ARGS__);\
|
||||
}
|
||||
#define SYNC_TRACE(...) {\
|
||||
/*TraceL;*/\
|
||||
EventPoller::Instance().sync(__VA_ARGS__);\
|
||||
}
|
||||
|
||||
} // namespace Poller
|
||||
} // namespace ZL
|
||||
#endif /* EventPoller_h */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
36
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/Pipe.h
Executable file
36
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/Pipe.h
Executable file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Pipe.h
|
||||
// xzl
|
||||
//
|
||||
// Created by xzl on 16/4/13.
|
||||
//
|
||||
|
||||
#ifndef Pipe_h
|
||||
#define Pipe_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <functional>
|
||||
#include "PipeWrap.h"
|
||||
#include "EventPoller.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Poller {
|
||||
|
||||
class Pipe
|
||||
{
|
||||
public:
|
||||
Pipe(function<void(int size,const char *buf)> &&onRead=nullptr);
|
||||
virtual ~Pipe();
|
||||
void send(const char *send,int size=0);
|
||||
private:
|
||||
std::shared_ptr<PipeWrap> _pipe;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poller
|
||||
} // namespace ZL
|
||||
|
||||
|
||||
#endif /* Pipe_h */
|
||||
32
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/PipeWrap.h
Executable file
32
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/PipeWrap.h
Executable file
@@ -0,0 +1,32 @@
|
||||
#ifndef PipeWarp_h
|
||||
#define PipeWarp_h
|
||||
|
||||
namespace ZL {
|
||||
namespace Poller {
|
||||
|
||||
class PipeWrap {
|
||||
public:
|
||||
PipeWrap();
|
||||
~PipeWrap();
|
||||
int write(const void *buf, int n);
|
||||
int read(void *buf, int n);
|
||||
int readFD() const {
|
||||
return _pipe_fd[0];
|
||||
}
|
||||
int writeFD() const {
|
||||
return _pipe_fd[1];
|
||||
}
|
||||
private:
|
||||
int _pipe_fd[2] = { -1,-1 };
|
||||
void clearFD();
|
||||
#if defined(_WIN32)
|
||||
int _listenerFd = -1;
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
};
|
||||
|
||||
} /* namespace Poller */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif // !PipeWarp_h
|
||||
|
||||
34
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/SelectWrap.h
Executable file
34
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/SelectWrap.h
Executable file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* WinSelect.h
|
||||
*
|
||||
* Created on: 2017年3月2日
|
||||
* Author: Jzan
|
||||
*/
|
||||
|
||||
#ifndef SRC_POLLER_SELECTWRAP_H_
|
||||
#define SRC_POLLER_SELECTWRAP_H_
|
||||
|
||||
namespace ZL {
|
||||
namespace Poller {
|
||||
|
||||
class FdSet
|
||||
{
|
||||
public:
|
||||
FdSet();
|
||||
virtual ~FdSet();
|
||||
void fdZero();
|
||||
void fdSet(int fd);
|
||||
void fdClr(int fd);
|
||||
bool isSet(int fd);
|
||||
void *ptr;
|
||||
private:
|
||||
};
|
||||
|
||||
} /* namespace Poller */
|
||||
} /* namespace ZL */
|
||||
using namespace ZL::Poller;
|
||||
int zl_select(int cnt,FdSet *read,FdSet *write,FdSet *err,struct timeval *tv);
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_POLLER_SELECTWRAP_H_ */
|
||||
32
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/Timer.h
Executable file
32
bin_lib/windows/ZLToolKit/include/ZLToolKit/Poller/Timer.h
Executable file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Timer.h
|
||||
// xzl
|
||||
//
|
||||
// Created by xzl on 16/4/13.
|
||||
//
|
||||
|
||||
#ifndef Timer_h
|
||||
#define Timer_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <functional>
|
||||
#include "EventPoller.h"
|
||||
#include "Thread/AsyncTaskThread.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Poller {
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
Timer(float second,const function<bool()> &cb);
|
||||
virtual ~Timer();
|
||||
private:
|
||||
std::shared_ptr<bool> canceled;
|
||||
};
|
||||
|
||||
} // namespace Poller
|
||||
} // namespace ZL
|
||||
#endif /* Timer_h */
|
||||
77
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/AsyncTaskThread.h
Executable file
77
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/AsyncTaskThread.h
Executable file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// AsyncTaskThread.h
|
||||
// xzl
|
||||
//
|
||||
// Created by xzl on 15/6/8.
|
||||
//
|
||||
|
||||
#ifndef AsyncTaskThread_h
|
||||
#define AsyncTaskThread_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <condition_variable>
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Util;
|
||||
|
||||
#define TASK_INTERVAL 50
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
typedef struct {
|
||||
uint64_t type;
|
||||
uint64_t timeLine;
|
||||
uint64_t tickTime;
|
||||
function<bool()> task;
|
||||
} TaskInfo;
|
||||
|
||||
|
||||
class AsyncTaskThread {
|
||||
public:
|
||||
//the timer default 30s
|
||||
AsyncTaskThread(uint64_t millisecond_sleep);
|
||||
~AsyncTaskThread();
|
||||
void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
|
||||
void CancelTask(uint64_t type);
|
||||
static AsyncTaskThread &Instance(uint32_t millisecond_sleep = TASK_INTERVAL) {
|
||||
static AsyncTaskThread *instance(new AsyncTaskThread(millisecond_sleep));
|
||||
return *instance;
|
||||
}
|
||||
static void Destory(){
|
||||
delete &AsyncTaskThread::Instance();
|
||||
}
|
||||
private:
|
||||
recursive_mutex _mtx;
|
||||
unordered_multimap<uint64_t, std::shared_ptr<TaskInfo> > taskMap;
|
||||
unordered_set<uint64_t> needCancel;
|
||||
inline uint64_t getNowTime();
|
||||
thread *taskThread;
|
||||
void DoTask();
|
||||
atomic_bool threadExit;
|
||||
condition_variable_any cond;
|
||||
uint64_t millisecond_sleep;
|
||||
};
|
||||
|
||||
class AsyncTaskHelper
|
||||
{
|
||||
public:
|
||||
AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
|
||||
AsyncTaskThread::Instance().DoTaskDelay(reinterpret_cast<uint64_t>(this),millisecond,task);
|
||||
}
|
||||
virtual ~AsyncTaskHelper(){
|
||||
AsyncTaskThread::Instance().CancelTask(reinterpret_cast<uint64_t>(this));
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* defined(AsyncTaskThread_h) */
|
||||
72
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/TaskQueue.h
Executable file
72
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/TaskQueue.h
Executable file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* TaskQueue.h
|
||||
*
|
||||
* Created on: 2013-10-11
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef TASKQUEUE_H_
|
||||
#define TASKQUEUE_H_
|
||||
|
||||
#include <deque>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
#include "spin_mutex.h"
|
||||
#include "semaphore.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
|
||||
//实现了一个基于函数对象的任务列队,该列队是线程安全的,任务列队任务数由信号量控制
|
||||
class TaskQueue {
|
||||
public:
|
||||
TaskQueue() {
|
||||
}
|
||||
//打入任务至列队
|
||||
template <typename T>
|
||||
void push_task(T &&task_func) {
|
||||
{
|
||||
lock_guard<spin_mutex> lock(my_mutex);
|
||||
my_queue.emplace_back(std::forward<T>(task_func));
|
||||
}
|
||||
sem.post();
|
||||
}
|
||||
template <typename T>
|
||||
void push_task_first(T &&task_func) {
|
||||
{
|
||||
lock_guard<spin_mutex> lock(my_mutex);
|
||||
my_queue.emplace_front(std::forward<T>(task_func));
|
||||
}
|
||||
sem.post();
|
||||
}
|
||||
//清空任务列队
|
||||
void push_exit(unsigned int n) {
|
||||
sem.post(n);
|
||||
}
|
||||
//从列队获取一个任务,由执行线程执行
|
||||
bool get_task(function<void(void)> &tsk) {
|
||||
sem.wait();
|
||||
lock_guard<spin_mutex> lock(my_mutex);
|
||||
if (my_queue.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
tsk = my_queue.front();
|
||||
my_queue.pop_front();
|
||||
return true;
|
||||
}
|
||||
uint64_t size() const{
|
||||
lock_guard<spin_mutex> lock(my_mutex);
|
||||
return my_queue.size();
|
||||
}
|
||||
private:
|
||||
deque<function<void(void)>> my_queue;
|
||||
mutable spin_mutex my_mutex;
|
||||
semaphore sem;
|
||||
};
|
||||
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
#endif /* TASKQUEUE_H_ */
|
||||
173
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/ThreadPool.h
Executable file
173
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/ThreadPool.h
Executable file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* ThreadPool.h
|
||||
*
|
||||
* Created on: 2013-10-11
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef THREADPOOL_H_
|
||||
#define THREADPOOL_H_
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include "threadgroup.h"
|
||||
#include "TaskQueue.h"
|
||||
#include "Util/util.h"
|
||||
#include "Util/logger.h"
|
||||
|
||||
using namespace ZL::Util;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
class ThreadPool {
|
||||
public:
|
||||
enum Priority {
|
||||
PRIORITY_LOWEST = 0,
|
||||
PRIORITY_LOW,
|
||||
PRIORITY_NORMAL,
|
||||
PRIORITY_HIGH,
|
||||
PRIORITY_HIGHEST
|
||||
};
|
||||
|
||||
//num:线程池线程个数
|
||||
ThreadPool(int num, Priority _priority = PRIORITY_NORMAL) :
|
||||
thread_num(num), avaible(true), priority(_priority) {
|
||||
start();
|
||||
}
|
||||
~ThreadPool() {
|
||||
wait();
|
||||
}
|
||||
|
||||
//把任务打入线程池并异步执行
|
||||
template <typename T>
|
||||
bool async(T &&task) {
|
||||
if (!avaible) {
|
||||
return false;
|
||||
}
|
||||
if (my_thread_group.is_this_thread_in()) {
|
||||
task();
|
||||
} else {
|
||||
my_queue.push_task(std::forward<T>(task));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <typename T>
|
||||
bool async_first(T &&task) {
|
||||
if (!avaible) {
|
||||
return false;
|
||||
}
|
||||
if (my_thread_group.is_this_thread_in()) {
|
||||
task();
|
||||
} else {
|
||||
my_queue.push_task_first(std::forward<T>(task));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <typename T>
|
||||
bool sync(T &&task){
|
||||
semaphore sem;
|
||||
bool flag = async([&](){
|
||||
task();
|
||||
sem.post();
|
||||
});
|
||||
if(flag){
|
||||
sem.wait();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
template <typename T>
|
||||
bool sync_first(T &&task) {
|
||||
semaphore sem;
|
||||
bool flag = async_first([&]() {
|
||||
task();
|
||||
sem.post();
|
||||
});
|
||||
if (flag) {
|
||||
sem.wait();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
//同步等待线程池执行完所有任务并退出
|
||||
void wait() {
|
||||
exit();
|
||||
my_thread_group.join_all();
|
||||
}
|
||||
uint64_t size() const{
|
||||
return my_queue.size();
|
||||
}
|
||||
static ThreadPool &Instance() {
|
||||
//单例模式
|
||||
static ThreadPool instance(thread::hardware_concurrency());
|
||||
return instance;
|
||||
}
|
||||
static bool setPriority(Priority _priority = PRIORITY_NORMAL,
|
||||
thread::native_handle_type threadId = 0) {
|
||||
// set priority
|
||||
#if defined(_WIN32)
|
||||
static int Priorities[] = { THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST };
|
||||
if (_priority != PRIORITY_NORMAL && SetThreadPriority(GetCurrentThread(), Priorities[_priority]) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
static int Min = sched_get_priority_min(SCHED_OTHER);
|
||||
if (Min == -1) {
|
||||
return false;
|
||||
}
|
||||
static int Max = sched_get_priority_max(SCHED_OTHER);
|
||||
if (Max == -1) {
|
||||
return false;
|
||||
}
|
||||
static int Priorities[] = { Min, Min + (Max - Min) / 4, Min
|
||||
+ (Max - Min) / 2, Min + (Max - Min) / 4, Max };
|
||||
|
||||
if (threadId == 0) {
|
||||
threadId = pthread_self();
|
||||
}
|
||||
struct sched_param params;
|
||||
params.sched_priority = Priorities[_priority];
|
||||
return pthread_setschedparam(threadId, SCHED_OTHER, ¶ms) == 0;
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
TaskQueue my_queue;
|
||||
thread_group my_thread_group;
|
||||
int thread_num;
|
||||
volatile bool avaible;
|
||||
Priority priority;
|
||||
//发送空任务至任务列队,通知线程主动退出
|
||||
void exit() {
|
||||
avaible = false;
|
||||
my_queue.push_exit(thread_num);
|
||||
}
|
||||
void start() {
|
||||
if (thread_num <= 0)
|
||||
return;
|
||||
for (int i = 0; i < thread_num; ++i) {
|
||||
my_thread_group.create_thread(bind(&ThreadPool::run, this));
|
||||
}
|
||||
}
|
||||
void run() {
|
||||
ThreadPool::setPriority(priority);
|
||||
function<void(void)> task;
|
||||
while (true) {
|
||||
if (my_queue.get_task(task)) {
|
||||
try {
|
||||
task();
|
||||
} catch (std::exception &ex) {
|
||||
FatalL << ex.what();
|
||||
}
|
||||
task = nullptr;
|
||||
} else {
|
||||
//空任务,退出线程
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
#endif /* THREADPOOL_H_ */
|
||||
46
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/WorkThreadPool.h
Executable file
46
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/WorkThreadPool.h
Executable file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* WorkThreadPool.h
|
||||
*
|
||||
* Created on: 2015年10月30日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef UTIL_WORKTHREADPOOL_H_
|
||||
#define UTIL_WORKTHREADPOOL_H_
|
||||
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include "ThreadPool.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
|
||||
class WorkThreadPool {
|
||||
public:
|
||||
WorkThreadPool(int threadnum = thread::hardware_concurrency());
|
||||
virtual ~WorkThreadPool();
|
||||
std::shared_ptr<ThreadPool> &getWorkThread();
|
||||
static WorkThreadPool &Instance() {
|
||||
static WorkThreadPool *intance(new WorkThreadPool());
|
||||
return *intance;
|
||||
}
|
||||
static void Destory(){
|
||||
delete &(WorkThreadPool::Instance());
|
||||
}
|
||||
private:
|
||||
int threadnum;
|
||||
atomic<int> threadPos;
|
||||
vector <std::shared_ptr<ThreadPool> > threads;
|
||||
void wait();
|
||||
};
|
||||
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* UTIL_WORKTHREADPOOL_H_ */
|
||||
71
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/rwmutex.h
Executable file
71
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/rwmutex.h
Executable file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* rwmutex.h
|
||||
*
|
||||
* Created on: 2016年1月27日
|
||||
* Author: 熊子良
|
||||
*/
|
||||
|
||||
#ifndef UTIL_RWMUTEX_H_
|
||||
#define UTIL_RWMUTEX_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
|
||||
class rw_mutex {
|
||||
public:
|
||||
rw_mutex() :
|
||||
reader_cnt(0) {
|
||||
}
|
||||
void lock(bool write_mode = true) {
|
||||
if (write_mode) {
|
||||
//write thread
|
||||
mtx_write.lock();
|
||||
} else {
|
||||
// read thread
|
||||
lock_guard<mutex> lck(mtx_reader);
|
||||
if (reader_cnt++ == 0) {
|
||||
mtx_write.lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
void unlock(bool write_mode = true) {
|
||||
if (write_mode) {
|
||||
//write thread
|
||||
mtx_write.unlock();
|
||||
} else {
|
||||
// read thread
|
||||
lock_guard<mutex> lck(mtx_reader);
|
||||
if (--reader_cnt == 0) {
|
||||
mtx_write.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~rw_mutex() {
|
||||
}
|
||||
private:
|
||||
mutex mtx_write;
|
||||
mutex mtx_reader;
|
||||
int reader_cnt;
|
||||
};
|
||||
class lock_guard_rw {
|
||||
public:
|
||||
lock_guard_rw(rw_mutex &_mtx, bool _write_mode = true) :
|
||||
mtx(_mtx), write_mode(_write_mode) {
|
||||
mtx.lock(write_mode);
|
||||
}
|
||||
virtual ~lock_guard_rw() {
|
||||
mtx.unlock(write_mode);
|
||||
}
|
||||
private:
|
||||
rw_mutex &mtx;
|
||||
bool write_mode;
|
||||
};
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* UTIL_RWMUTEX_H_ */
|
||||
78
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/semaphore.h
Executable file
78
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/semaphore.h
Executable file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* semaphore.h
|
||||
*
|
||||
* Created on: 2015年8月14日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef SEMAPHORE_H_
|
||||
#define SEMAPHORE_H_
|
||||
|
||||
/*
|
||||
* 目前发现信号量在32位的系统上有问题,
|
||||
* 休眠的线程无法被正常唤醒,先禁用之
|
||||
#if defined(__linux__)
|
||||
#include <semaphore.h>
|
||||
#define HAVE_SEM
|
||||
#endif //HAVE_SEM
|
||||
*/
|
||||
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
|
||||
class semaphore {
|
||||
public:
|
||||
explicit semaphore(unsigned int initial = 0) {
|
||||
#if defined(HAVE_SEM)
|
||||
sem_init(&sem, 0, initial);
|
||||
#else
|
||||
count_ = 0;
|
||||
#endif
|
||||
}
|
||||
~semaphore() {
|
||||
#if defined(HAVE_SEM)
|
||||
sem_destroy(&sem);
|
||||
#endif
|
||||
}
|
||||
void post(unsigned int n = 1) {
|
||||
#if defined(HAVE_SEM)
|
||||
while (n--) {
|
||||
sem_post(&sem);
|
||||
}
|
||||
#else
|
||||
unique_lock<mutex> lock(mutex_);
|
||||
count_ += n;
|
||||
while (n--) {
|
||||
condition_.notify_one();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
void wait() {
|
||||
#if defined(HAVE_SEM)
|
||||
sem_wait(&sem);
|
||||
#else
|
||||
unique_lock<mutex> lock(mutex_);
|
||||
while (count_ == 0) {
|
||||
condition_.wait(lock);
|
||||
}
|
||||
--count_;
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
#if defined(HAVE_SEM)
|
||||
sem_t sem;
|
||||
#else
|
||||
atomic_uint count_;
|
||||
mutex mutex_;
|
||||
condition_variable_any condition_;
|
||||
#endif
|
||||
};
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
#endif /* SEMAPHORE_H_ */
|
||||
41
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/spin_mutex.h
Executable file
41
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/spin_mutex.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* spinmutex.h
|
||||
*
|
||||
* Created on: 2017年3月31日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef SRC_THREAD_SPIN_MUTEX_H_
|
||||
#define SRC_THREAD_SPIN_MUTEX_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
|
||||
#ifndef __ARM_ARCH
|
||||
|
||||
class spin_mutex {
|
||||
std::atomic_flag flag = ATOMIC_FLAG_INIT;
|
||||
public:
|
||||
spin_mutex() = default;
|
||||
spin_mutex(const spin_mutex&) = delete;
|
||||
spin_mutex& operator= (const spin_mutex&) = delete;
|
||||
void lock() {
|
||||
while(flag.test_and_set(std::memory_order_acquire)) ;
|
||||
}
|
||||
void unlock() {
|
||||
flag.clear(std::memory_order_release);
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
typedef mutex spin_mutex;
|
||||
#endif //__ARM_ARCH
|
||||
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SRC_THREAD_SPIN_MUTEX_H_ */
|
||||
93
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/threadgroup.h
Executable file
93
bin_lib/windows/ZLToolKit/include/ZLToolKit/Thread/threadgroup.h
Executable file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* threadgroup.h
|
||||
*
|
||||
* Created on: 2014-6-23
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef THREADGROUP_H_
|
||||
#define THREADGROUP_H_
|
||||
|
||||
#include <set>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Thread {
|
||||
|
||||
class thread_group {
|
||||
private:
|
||||
thread_group(thread_group const&);
|
||||
thread_group& operator=(thread_group const&);
|
||||
public:
|
||||
thread_group() {
|
||||
}
|
||||
~thread_group() {
|
||||
for (auto &th : threads) {
|
||||
delete th.second;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_this_thread_in() {
|
||||
auto it = threads.find(this_thread::get_id());
|
||||
return it != threads.end();
|
||||
}
|
||||
|
||||
bool is_thread_in(thread* thrd) {
|
||||
if (thrd) {
|
||||
auto it = threads.find(thrd->get_id());
|
||||
return it != threads.end();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
thread* create_thread(F threadfunc) {
|
||||
thread *new_thread=new thread(threadfunc);
|
||||
threads[new_thread->get_id()] = new_thread;
|
||||
return new_thread;
|
||||
}
|
||||
|
||||
void add_thread(thread* thrd) {
|
||||
if (thrd) {
|
||||
if (is_thread_in(thrd)) {
|
||||
throw runtime_error(
|
||||
"thread_group: trying to add a duplicated thread");
|
||||
}
|
||||
threads[thrd->get_id()] = thrd;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_thread(thread* thrd) {
|
||||
auto it = threads.find(thrd->get_id());
|
||||
if (it != threads.end()) {
|
||||
threads.erase(it);
|
||||
}
|
||||
}
|
||||
void join_all() {
|
||||
if (is_this_thread_in()) {
|
||||
throw runtime_error("thread_group: trying joining itself");
|
||||
return;
|
||||
}
|
||||
for (auto &it : threads) {
|
||||
if (it.second->joinable()) {
|
||||
it.second->join(); //等待线程主动退出
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t size() {
|
||||
return threads.size();
|
||||
}
|
||||
private:
|
||||
unordered_map<thread::id, thread*> threads;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace Thread */
|
||||
} /* namespace ZL */
|
||||
#endif /* THREADGROUP_H_ */
|
||||
75
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/File.h
Executable file
75
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/File.h
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* File.h
|
||||
*
|
||||
* Created on: 2016年9月22日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef SRC_UTIL_FILE_H_
|
||||
#define SRC_UTIL_FILE_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <WinSock2.h>
|
||||
#pragma comment (lib,"WS2_32")
|
||||
#endif // WIN32
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 256
|
||||
#endif // !PATH_MAX
|
||||
|
||||
struct dirent{
|
||||
long d_ino; /* inode number*/
|
||||
off_t d_off; /* offset to this dirent*/
|
||||
unsigned short d_reclen; /* length of this d_name*/
|
||||
unsigned char d_type; /* the type of d_name*/
|
||||
char d_name[1]; /* file name (null-terminated)*/
|
||||
};
|
||||
typedef struct _dirdesc {
|
||||
int dd_fd; /** file descriptor associated with directory */
|
||||
long dd_loc; /** offset in current buffer */
|
||||
long dd_size; /** amount of data returned by getdirentries */
|
||||
char *dd_buf; /** data buffer */
|
||||
int dd_len; /** size of data buffer */
|
||||
long dd_seek; /** magic cookie returned by getdirentries */
|
||||
HANDLE handle;
|
||||
struct dirent *index;
|
||||
} DIR;
|
||||
# define __dirfd(dp) ((dp)->dd_fd)
|
||||
|
||||
int mkdir(const char *path, int mode);
|
||||
DIR *opendir(const char *);
|
||||
int closedir(DIR *);
|
||||
struct dirent *readdir(DIR *);
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
class File {
|
||||
public:
|
||||
// 可读普通文件
|
||||
static bool isrfile(const char *path) ;
|
||||
//新建文件,目录文件夹自动生成
|
||||
static bool createfile_path(const char *file, unsigned int mod);
|
||||
static FILE *createfile_file(const char *file,const char *mode);
|
||||
//判断是否为目录
|
||||
static bool is_dir(const char *path) ;
|
||||
//判断是否为常规文件
|
||||
static bool is_file(const char *path) ;
|
||||
//判断是否是特殊目录(. or ..)
|
||||
static bool is_special_dir(const char *path);
|
||||
//删除目录或文件
|
||||
static void delete_file(const char *path) ;
|
||||
static bool rm_empty_dir(const char *path);
|
||||
private:
|
||||
File();
|
||||
virtual ~File();
|
||||
};
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SRC_UTIL_FILE_H_ */
|
||||
74
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/MD5.h
Executable file
74
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/MD5.h
Executable file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* MD5.h
|
||||
*
|
||||
* Created on: 2016年8月23日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef SRC_UTIL_MD5_H_
|
||||
#define SRC_UTIL_MD5_H_
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
// a small class for calculating MD5 hashes of strings or byte arrays
|
||||
// it is not meant to be fast or secure
|
||||
//
|
||||
// usage: 1) feed it blocks of uchars with update()
|
||||
// 2) finalize()
|
||||
// 3) get hexdigest() string
|
||||
// or
|
||||
// MD5(std::string).hexdigest()
|
||||
//
|
||||
// assumes that char is 8 bit and int is 32 bit
|
||||
class MD5
|
||||
{
|
||||
public:
|
||||
typedef unsigned int size_type; // must be 32bit
|
||||
|
||||
MD5();
|
||||
MD5(const std::string& text);
|
||||
void update(const unsigned char *buf, size_type length);
|
||||
void update(const char *buf, size_type length);
|
||||
MD5& finalize();
|
||||
std::string hexdigest() const;
|
||||
friend std::ostream& operator<<(std::ostream&, MD5 md5);
|
||||
|
||||
private:
|
||||
void init();
|
||||
typedef uint8_t uint1; // 8bit
|
||||
typedef uint32_t uint4; // 32bit
|
||||
enum {blocksize = 64}; // VC6 won't eat a const static int here
|
||||
|
||||
void transform(const uint1 block[blocksize]);
|
||||
static void decode(uint4 output[], const uint1 input[], size_type len);
|
||||
static void encode(uint1 output[], const uint4 input[], size_type len);
|
||||
|
||||
bool finalized;
|
||||
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
|
||||
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
|
||||
uint4 state[4]; // digest so far
|
||||
uint1 digest[16]; // the result
|
||||
|
||||
// low level logic operations
|
||||
static inline uint4 F(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 rotate_left(uint4 x, int n);
|
||||
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SRC_UTIL_MD5_H_ */
|
||||
104
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/NoticeCenter.h
Executable file
104
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/NoticeCenter.h
Executable file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* NoticeCenter.h
|
||||
*
|
||||
* Created on: 2017年2月17日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef SRC_UTIL_NOTICECENTER_H_
|
||||
#define SRC_UTIL_NOTICECENTER_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include "function_traits.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
|
||||
class NoticeCenter {
|
||||
public:
|
||||
class InterruptException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
InterruptException():std::runtime_error("InterruptException"){}
|
||||
virtual ~InterruptException(){}
|
||||
};
|
||||
|
||||
virtual ~NoticeCenter(){}
|
||||
static NoticeCenter &Instance(){
|
||||
static NoticeCenter instance;
|
||||
return instance;
|
||||
}
|
||||
template<typename ...ArgsType>
|
||||
bool emitEvent(const char *strEvent,ArgsType &&...args){
|
||||
lock_guard<recursive_mutex> lck(_mtxListener);
|
||||
auto it0 = _mapListener.find(strEvent);
|
||||
if (it0 == _mapListener.end()) {
|
||||
return false;
|
||||
}
|
||||
for(auto &pr : it0->second){
|
||||
typedef function<void(ArgsType &&...)> funType;
|
||||
funType *obj = (funType *)(pr.second.get());
|
||||
try{
|
||||
(*obj)(std::forward<ArgsType>(args)...);
|
||||
}catch(InterruptException &ex){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return it0->second.size();
|
||||
}
|
||||
|
||||
|
||||
template<typename FUN>
|
||||
void addListener(void *tag, const char *strEvent, const FUN &fun) {
|
||||
typedef typename function_traits<FUN>::stl_function_type funType;
|
||||
std::shared_ptr<void> pListener(new funType(fun), [](void *ptr) {
|
||||
funType *obj = (funType *)ptr;
|
||||
delete obj;
|
||||
});
|
||||
lock_guard<recursive_mutex> lck(_mtxListener);
|
||||
_mapListener[strEvent][tag] = pListener;
|
||||
}
|
||||
|
||||
|
||||
void delListener(void *tag,const char *strEvent){
|
||||
lock_guard<recursive_mutex> lck(_mtxListener);
|
||||
auto it = _mapListener.find(strEvent);
|
||||
if(it == _mapListener.end()){
|
||||
return;
|
||||
}
|
||||
it->second.erase(tag);
|
||||
if(it->second.empty()){
|
||||
_mapListener.erase(it);
|
||||
}
|
||||
}
|
||||
void delListener(void *tag){
|
||||
lock_guard<recursive_mutex> lck(_mtxListener);
|
||||
for(auto it = _mapListener.begin();it != _mapListener.end();){
|
||||
it->second.erase(tag);
|
||||
if(it->second.empty()){
|
||||
it = _mapListener.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
NoticeCenter(){}
|
||||
recursive_mutex _mtxListener;
|
||||
unordered_map<string,unordered_map<void *,std::shared_ptr<void> > > _mapListener;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SRC_UTIL_NOTICECENTER_H_ */
|
||||
133
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/ResourcePool.h
Executable file
133
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/ResourcePool.h
Executable file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* ResourcePool.h
|
||||
*
|
||||
* Created on: 2015年10月29日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef UTIL_RECYCLEPOOL_H_
|
||||
#define UTIL_RECYCLEPOOL_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
using namespace std;
|
||||
|
||||
template<typename C, int poolSize = 10>
|
||||
class ResourcePool {
|
||||
public:
|
||||
typedef std::shared_ptr<C> ValuePtr;
|
||||
ResourcePool() {
|
||||
pool.reset(new _ResourcePool());
|
||||
}
|
||||
#if (!defined(__GNUC__)) || (__GNUC__ >= 5)
|
||||
template<typename ...ArgTypes>
|
||||
ResourcePool(ArgTypes &&...args) {
|
||||
pool.reset(new _ResourcePool(std::forward<ArgTypes>(args)...));
|
||||
}
|
||||
#endif //(!defined(__GNUC__)) || (__GNUC__ >= 5)
|
||||
void reSize(int size) {
|
||||
pool->setSize(size);
|
||||
}
|
||||
ValuePtr obtain() {
|
||||
return pool->obtain();
|
||||
}
|
||||
void quit(const ValuePtr &ptr) {
|
||||
pool->quit(ptr);
|
||||
}
|
||||
private:
|
||||
|
||||
class _ResourcePool: public enable_shared_from_this<_ResourcePool> {
|
||||
public:
|
||||
typedef std::shared_ptr<C> ValuePtr;
|
||||
_ResourcePool() {
|
||||
poolsize = poolSize;
|
||||
allotter = []()->C* {
|
||||
return new C();
|
||||
};
|
||||
}
|
||||
#if (!defined(__GNUC__)) || (__GNUC__ >= 5)
|
||||
template<typename ...ArgTypes>
|
||||
_ResourcePool(ArgTypes &&...args) {
|
||||
poolsize = poolSize;
|
||||
allotter = [args...]()->C* {
|
||||
return new C(args...);
|
||||
};
|
||||
}
|
||||
#endif //(!defined(__GNUC__)) || (__GNUC__ >= 5)
|
||||
virtual ~_ResourcePool(){
|
||||
std::lock_guard<mutex> lck(_mutex);
|
||||
for(auto &ptr : objs){
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
void setSize(int size) {
|
||||
poolsize = size;
|
||||
}
|
||||
ValuePtr obtain() {
|
||||
std::lock_guard<mutex> lck(_mutex);
|
||||
C *ptr = nullptr;
|
||||
if (objs.size() == 0) {
|
||||
ptr = allotter();
|
||||
} else {
|
||||
ptr = objs.front();
|
||||
objs.pop_front();
|
||||
}
|
||||
return ValuePtr(ptr, Deleter(this->shared_from_this()));
|
||||
}
|
||||
void quit(const ValuePtr &ptr) {
|
||||
std::lock_guard<mutex> lck(_mutex);
|
||||
quitSet.emplace(ptr.get());
|
||||
}
|
||||
private:
|
||||
class Deleter {
|
||||
public:
|
||||
Deleter(const std::shared_ptr<_ResourcePool> &pool) {
|
||||
weakPool = pool;
|
||||
}
|
||||
void operator()(C *ptr) {
|
||||
auto strongPool = weakPool.lock();
|
||||
if (strongPool) {
|
||||
strongPool->recycle(ptr);
|
||||
} else {
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
private:
|
||||
weak_ptr<_ResourcePool> weakPool;
|
||||
};
|
||||
private:
|
||||
void recycle(C *obj) {
|
||||
std::lock_guard<mutex> lck(_mutex);
|
||||
auto it = quitSet.find(obj);
|
||||
if (it != quitSet.end()) {
|
||||
delete obj;
|
||||
quitSet.erase(it);
|
||||
return;
|
||||
}
|
||||
if ((int)objs.size() >= poolsize) {
|
||||
delete obj;
|
||||
return;
|
||||
}
|
||||
objs.push_back(obj);
|
||||
}
|
||||
|
||||
deque<C*> objs;
|
||||
unordered_set<C*> quitSet;
|
||||
function<C*(void)> allotter;
|
||||
mutex _mutex;
|
||||
int poolsize;
|
||||
};
|
||||
std::shared_ptr<_ResourcePool> pool;
|
||||
};
|
||||
|
||||
} /* namespace util */
|
||||
} /* namespace im */
|
||||
|
||||
#endif /* UTIL_RECYCLEPOOL_H_ */
|
||||
244
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/RingBuffer.h
Executable file
244
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/RingBuffer.h
Executable file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* RingBuffer.h
|
||||
*
|
||||
* Created on: 2016年8月10日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef UTIL_RINGBUFFER_H_
|
||||
#define UTIL_RINGBUFFER_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <condition_variable>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
//实现了一个一写多读得环形缓冲的模板类
|
||||
template<typename T> class RingBuffer: public enable_shared_from_this<
|
||||
RingBuffer<T> > {
|
||||
public:
|
||||
typedef std::shared_ptr<RingBuffer> Ptr;
|
||||
|
||||
class RingReader {
|
||||
public:
|
||||
friend class RingBuffer;
|
||||
typedef std::shared_ptr<RingReader> Ptr;
|
||||
RingReader(const std::shared_ptr<RingBuffer> &_buffer,bool _useBuffer) {
|
||||
buffer = _buffer;
|
||||
curpos = _buffer->ringKeyPos;
|
||||
useBuffer = _useBuffer;
|
||||
}
|
||||
virtual ~RingReader() {
|
||||
auto strongBuffer = buffer.lock();
|
||||
if (strongBuffer) {
|
||||
strongBuffer->release(this);
|
||||
}
|
||||
}
|
||||
//重新定位读取器至最新的数据位置
|
||||
void reset(bool keypos = true) {
|
||||
auto strongBuffer = buffer.lock();
|
||||
if (strongBuffer) {
|
||||
if(keypos){
|
||||
curpos = strongBuffer->ringKeyPos; //定位读取器
|
||||
}else{
|
||||
curpos = strongBuffer->ringPos; //定位读取器
|
||||
}
|
||||
}
|
||||
}
|
||||
void setReadCB(const function<void(const T &)> &cb) {
|
||||
lock_guard<recursive_mutex> lck(mtxCB);
|
||||
readCB = cb;
|
||||
reset();
|
||||
}
|
||||
void setDetachCB(const function<void()> &cb) {
|
||||
lock_guard<recursive_mutex> lck(mtxCB);
|
||||
if (!cb) {
|
||||
detachCB = []() {};
|
||||
} else {
|
||||
detachCB = cb;
|
||||
}
|
||||
}
|
||||
|
||||
const T* read(){
|
||||
auto strongBuffer=buffer.lock();
|
||||
if(!strongBuffer){
|
||||
return nullptr;
|
||||
}
|
||||
return read(strongBuffer.get());
|
||||
}
|
||||
|
||||
private:
|
||||
void onRead(const T &data) {
|
||||
lock_guard<recursive_mutex> lck(mtxCB);
|
||||
if(!readCB){
|
||||
return;
|
||||
}
|
||||
|
||||
if(!useBuffer){
|
||||
readCB(data);
|
||||
}else{
|
||||
const T *pkt = nullptr;
|
||||
while((pkt = read())){
|
||||
readCB(*pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
void onDetach() const {
|
||||
lock_guard<recursive_mutex> lck(mtxCB);
|
||||
detachCB();
|
||||
}
|
||||
//读环形缓冲
|
||||
const T *read(RingBuffer *ring) {
|
||||
if (curpos == ring->ringPos) {
|
||||
return nullptr;
|
||||
}
|
||||
const T *data = &(ring->dataRing[curpos]); //返回包
|
||||
curpos = ring->next(curpos); //更新位置
|
||||
return data;
|
||||
}
|
||||
|
||||
function<void(const T &)> readCB ;
|
||||
function<void(void)> detachCB = []() {};
|
||||
weak_ptr<RingBuffer> buffer;
|
||||
mutable recursive_mutex mtxCB;
|
||||
int curpos;
|
||||
bool useBuffer;
|
||||
};
|
||||
|
||||
friend class RingReader;
|
||||
RingBuffer(int size = 0) {
|
||||
if(size <= 0){
|
||||
size = 32;
|
||||
canReSize = true;
|
||||
}
|
||||
ringSize = size;
|
||||
dataRing = new T[ringSize];
|
||||
ringPos = 0;
|
||||
ringKeyPos = 0;
|
||||
}
|
||||
virtual ~RingBuffer() {
|
||||
decltype(readerMap) mapCopy;
|
||||
{
|
||||
lock_guard<recursive_mutex> lck(mtx_reader);
|
||||
mapCopy.swap(readerMap);
|
||||
}
|
||||
for (auto &pr : mapCopy) {
|
||||
auto reader = pr.second.lock();
|
||||
if(reader){
|
||||
reader->onDetach();
|
||||
}
|
||||
}
|
||||
delete[] dataRing;
|
||||
}
|
||||
#if defined(ENABLE_RING_USEBUF)
|
||||
std::shared_ptr<RingReader> attach(bool useBuffer = true) {
|
||||
#else //ENABLE_RING_USEBUF
|
||||
std::shared_ptr<RingReader> attach(bool useBuffer = false) {
|
||||
#endif //ENABLE_RING_USEBUF
|
||||
|
||||
std::shared_ptr<RingReader> ptr(new RingReader(this->shared_from_this(),useBuffer));
|
||||
std::weak_ptr<RingReader> weakPtr = ptr;
|
||||
lock_guard<recursive_mutex> lck(mtx_reader);
|
||||
readerMap.emplace(ptr.get(),weakPtr);
|
||||
return ptr;
|
||||
}
|
||||
//写环形缓冲,非线程安全的
|
||||
void write(const T &in,bool isKey = true) {
|
||||
computeBestSize(isKey);
|
||||
dataRing[ringPos] = in;
|
||||
if (isKey) {
|
||||
ringKeyPos = ringPos; //设置读取器可以定位的点
|
||||
}
|
||||
ringPos = next(ringPos);
|
||||
decltype(readerMap) mapCopy;
|
||||
{
|
||||
lock_guard<recursive_mutex> lck(mtx_reader);
|
||||
mapCopy = readerMap;
|
||||
}
|
||||
for (auto &pr : mapCopy) {
|
||||
auto reader = pr.second.lock();
|
||||
if(reader){
|
||||
reader->onRead(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
int readerCount(){
|
||||
lock_guard<recursive_mutex> lck(mtx_reader);
|
||||
return readerMap.size();
|
||||
}
|
||||
private:
|
||||
T *dataRing;
|
||||
int ringPos;
|
||||
int ringKeyPos;
|
||||
int ringSize;
|
||||
//计算最佳环形缓存大小的参数
|
||||
int besetSize = 0;
|
||||
int totalCnt = 0;
|
||||
int lastKeyCnt = 0;
|
||||
bool canReSize = false;
|
||||
|
||||
recursive_mutex mtx_reader;
|
||||
unordered_map<void *,std::weak_ptr<RingReader> > readerMap;
|
||||
|
||||
inline int next(int pos) {
|
||||
//读取器下一位置
|
||||
if (pos > ringSize - 2) {
|
||||
return 0;
|
||||
} else {
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void release(RingReader *reader) {
|
||||
lock_guard<recursive_mutex> lck(mtx_reader);
|
||||
readerMap.erase(reader);
|
||||
}
|
||||
void computeBestSize(bool isKey){
|
||||
if(!canReSize || besetSize){
|
||||
return;
|
||||
}
|
||||
totalCnt++;
|
||||
if(!isKey){
|
||||
return;
|
||||
}
|
||||
//关键帧
|
||||
if(lastKeyCnt){
|
||||
//计算两个I帧之间的包个数
|
||||
besetSize = totalCnt - lastKeyCnt;
|
||||
reSize();
|
||||
return;
|
||||
}
|
||||
lastKeyCnt = totalCnt;
|
||||
}
|
||||
void reSize(){
|
||||
ringSize = besetSize;
|
||||
delete [] dataRing;
|
||||
dataRing = new T[ringSize];
|
||||
ringPos = 0;
|
||||
ringKeyPos = 0;
|
||||
|
||||
decltype(readerMap) mapCopy;
|
||||
{
|
||||
lock_guard<recursive_mutex> lck(mtx_reader);
|
||||
mapCopy = readerMap;
|
||||
}
|
||||
for (auto &pr : mapCopy) {
|
||||
auto reader = pr.second.lock();
|
||||
if(reader){
|
||||
reader->reset(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* UTIL_RINGBUFFER_H_ */
|
||||
112
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/SSLBox.h
Executable file
112
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/SSLBox.h
Executable file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* SSLServer.h
|
||||
*
|
||||
* Created on: 2016年1月11日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_SSLBOX_H_
|
||||
#define CRYPTO_SSLBOX_H_
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include "logger.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN64)
|
||||
|
||||
//64bit
|
||||
#if defined(_DEBUG)
|
||||
#pragma comment (lib,"libssl64MDd")
|
||||
#pragma comment (lib,"libcrypto64MDd")
|
||||
#else
|
||||
#pragma comment (lib,"libssl64MD")
|
||||
#pragma comment (lib,"libcrypto64MD")
|
||||
#endif // defined(_DEBUG)
|
||||
|
||||
#else
|
||||
|
||||
//32 bit
|
||||
#if defined(_DEBUG)
|
||||
#pragma comment (lib,"libssl32MDd")
|
||||
#pragma comment (lib,"libcrypto32MDd")
|
||||
#else
|
||||
#pragma comment (lib,"libssl32MD")
|
||||
#pragma comment (lib,"libcrypto32MD")
|
||||
#endif // defined(_DEBUG)
|
||||
|
||||
#endif //defined(_WIN64)
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
class SSL_Initor {
|
||||
public:
|
||||
friend class SSL_Box;
|
||||
static SSL_Initor &Instance() {
|
||||
static SSL_Initor obj;
|
||||
return obj;
|
||||
}
|
||||
void loadServerPem(const char *keyAndCA_pem, const char *import_pwd = "");
|
||||
void loadClientPem(const char *keyAndCA_pem, const char *import_pwd = "");
|
||||
private:
|
||||
static mutex *_mutexes;
|
||||
SSL_CTX *ssl_server;
|
||||
SSL_CTX *ssl_client;
|
||||
SSL_Initor();
|
||||
~SSL_Initor();
|
||||
void setCtx(SSL_CTX *ctx);
|
||||
void loadPem(SSL_CTX *ctx, const char *keyAndCA_pem,const char *import_pwd);
|
||||
inline std::string getLastError();
|
||||
}
|
||||
;
|
||||
class SSL_Box {
|
||||
public:
|
||||
SSL_Box(bool isServer = true, bool enable = true);
|
||||
virtual ~SSL_Box();
|
||||
|
||||
//收到密文后,调用此函数解密
|
||||
void onRecv(const char *data, uint32_t data_len);
|
||||
//需要加密明文调用此函数
|
||||
void onSend(const char *data, uint32_t data_len);
|
||||
|
||||
//设置解密后获取明文的回调
|
||||
template<typename F>
|
||||
void setOnDecData(F &&fun) {
|
||||
onDec = fun;
|
||||
}
|
||||
|
||||
//设置加密后获取密文的回调
|
||||
template<typename F>
|
||||
void setOnEncData(F &&fun) {
|
||||
onEnc = fun;
|
||||
}
|
||||
void shutdown();
|
||||
private:
|
||||
bool isServer;
|
||||
bool enable;
|
||||
bool sendHandshake;
|
||||
SSL *ssl;
|
||||
BIO *read_bio, *write_bio;
|
||||
function<void(const char *data, uint32_t len)> onDec;
|
||||
function<void(const char *data, uint32_t len)> onEnc;
|
||||
std::string _bufferOut;
|
||||
void flush();
|
||||
void flushWriteBio(char *buf, int bufsize);
|
||||
void flushReadBio(char *buf, int bufsize);
|
||||
|
||||
};
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* CRYPTO_SSLBOX_H_ */
|
||||
145
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/SqlConnection.h
Executable file
145
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/SqlConnection.h
Executable file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* SqlConnection.h
|
||||
*
|
||||
* Created on: 2015年10月29日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef SQL_SQLCONNECTION_H_
|
||||
#define SQL_SQLCONNECTION_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include "Util/logger.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <mysql.h>
|
||||
#pragma comment (lib,"libmysql")
|
||||
#else
|
||||
#include <mysql/mysql.h>
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
class SqlConnection {
|
||||
public:
|
||||
SqlConnection(const string &url, unsigned short port, const string &dbname,
|
||||
const string &user, const string &password,const string &character = "utf8mb4");
|
||||
virtual ~SqlConnection();
|
||||
|
||||
template<typename ...Args>
|
||||
int64_t query(int64_t &rowId, const char *fmt, Args && ...arg) {
|
||||
check();
|
||||
string tmp = queryString(fmt, std::forward<Args>(arg)...);
|
||||
if (mysql_query(&sql, tmp.c_str())) {
|
||||
WarnL << mysql_error(&sql) << ":" << tmp << endl;
|
||||
return -1;
|
||||
}
|
||||
rowId=mysql_insert_id(&sql);
|
||||
return mysql_affected_rows(&sql);
|
||||
}
|
||||
|
||||
int64_t query(int64_t &rowId,const char *str) {
|
||||
check();
|
||||
if (mysql_query(&sql, str)) {
|
||||
WarnL << mysql_error(&sql) << ":" << str << endl;
|
||||
return -1;
|
||||
}
|
||||
rowId=mysql_insert_id(&sql);
|
||||
return mysql_affected_rows(&sql);
|
||||
}
|
||||
template<typename ...Args>
|
||||
int64_t query(int64_t &rowId,vector<vector<string>> &ret, const char *fmt,
|
||||
Args && ...arg) {
|
||||
check();
|
||||
string tmp = queryString(fmt, std::forward<Args>(arg)...);
|
||||
if (mysql_query(&sql, tmp.c_str())) {
|
||||
WarnL << mysql_error(&sql) << ":" << tmp << endl;
|
||||
return -1;
|
||||
}
|
||||
ret.clear();
|
||||
MYSQL_RES *res = mysql_store_result(&sql);
|
||||
if (!res) {
|
||||
rowId=mysql_insert_id(&sql);
|
||||
return mysql_affected_rows(&sql);
|
||||
}
|
||||
MYSQL_ROW row;
|
||||
unsigned int column = mysql_num_fields(res);
|
||||
while ((row = mysql_fetch_row(res)) != NULL) {
|
||||
ret.emplace_back();
|
||||
auto &back = ret.back();
|
||||
for (unsigned int i = 0; i < column; i++) {
|
||||
back.emplace_back(row[i] ? row[i] : "");
|
||||
}
|
||||
}
|
||||
mysql_free_result(res);
|
||||
rowId=mysql_insert_id(&sql);
|
||||
return mysql_affected_rows(&sql);
|
||||
}
|
||||
int64_t query(int64_t &rowId,vector<vector<string>> &ret, const char *str) {
|
||||
check();
|
||||
if (mysql_query(&sql, str)) {
|
||||
WarnL << mysql_error(&sql) << ":" << str << endl;
|
||||
return -1;
|
||||
}
|
||||
ret.clear();
|
||||
MYSQL_RES *res = mysql_store_result(&sql);
|
||||
if (!res) {
|
||||
rowId=mysql_insert_id(&sql);
|
||||
return mysql_affected_rows(&sql);
|
||||
}
|
||||
MYSQL_ROW row;
|
||||
unsigned int column = mysql_num_fields(res);
|
||||
while ((row = mysql_fetch_row(res)) != NULL) {
|
||||
ret.emplace_back();
|
||||
auto &back = ret.back();
|
||||
for (unsigned int i = 0; i < column; i++) {
|
||||
back.emplace_back(row[i] ? row[i] : "" );
|
||||
}
|
||||
}
|
||||
mysql_free_result(res);
|
||||
rowId=mysql_insert_id(&sql);
|
||||
return mysql_affected_rows(&sql);
|
||||
}
|
||||
template<typename ...Args>
|
||||
static string queryString(const char *fmt, Args && ...arg) {
|
||||
char *ptr_out = NULL;
|
||||
asprintf(&ptr_out, fmt, arg...);
|
||||
string ret(ptr_out);
|
||||
if (ptr_out) {
|
||||
free(ptr_out);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static string queryString(const char *fmt) {
|
||||
return fmt;
|
||||
}
|
||||
string &escape(string &str) {
|
||||
char *out = new char[str.length() * 2 + 1];
|
||||
mysql_real_escape_string(&sql, out, str.c_str(), str.size());
|
||||
str.assign(out);
|
||||
delete [] out;
|
||||
return str;
|
||||
}
|
||||
private:
|
||||
MYSQL sql;
|
||||
inline void check() {
|
||||
if (mysql_ping(&sql) != 0) {
|
||||
throw runtime_error("MYSQL连接异常!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace util */
|
||||
} /* namespace ZL */
|
||||
#endif /* SQL_SQLCONNECTION_H_ */
|
||||
230
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/SqlPool.h
Executable file
230
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/SqlPool.h
Executable file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* SqlPool.h
|
||||
*
|
||||
* Created on: 2015年10月29日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef SQL_SQLPOOL_H_
|
||||
#define SQL_SQLPOOL_H_
|
||||
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
#include "logger.h"
|
||||
#include "SqlConnection.h"
|
||||
#include "Thread/ThreadPool.h"
|
||||
#include "Util/ResourcePool.h"
|
||||
#include "Thread/AsyncTaskThread.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
template<int poolSize = 10>
|
||||
class _SqlPool {
|
||||
public:
|
||||
typedef ResourcePool<SqlConnection, poolSize> PoolType;
|
||||
typedef vector<vector<string> > SqlRetType;
|
||||
static _SqlPool &Instance() {
|
||||
static _SqlPool *pool(new _SqlPool());
|
||||
return *pool;
|
||||
}
|
||||
static void Destory(){
|
||||
delete &Instance();
|
||||
}
|
||||
void reSize(int size) {
|
||||
if (size < 0) {
|
||||
return;
|
||||
}
|
||||
poolsize = size;
|
||||
pool->reSize(size);
|
||||
threadPool.reset(new ThreadPool(poolsize));
|
||||
}
|
||||
template<typename ...Args>
|
||||
void Init(Args && ...arg) {
|
||||
pool.reset(new PoolType(std::forward<Args>(arg)...));
|
||||
pool->obtain();
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
int64_t query(const char *fmt, Args && ...arg) {
|
||||
string sql = SqlConnection::queryString(fmt, std::forward<Args>(arg)...);
|
||||
doQuery(sql);
|
||||
return 0;
|
||||
}
|
||||
int64_t query(const string &sql) {
|
||||
doQuery(sql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
int64_t query(int64_t &rowID,vector<vector<string>> &ret, const char *fmt,
|
||||
Args && ...arg) {
|
||||
return _query(rowID,ret, fmt, std::forward<Args>(arg)...);
|
||||
}
|
||||
|
||||
int64_t query(int64_t &rowID,vector<vector<string>> &ret, const string &sql) {
|
||||
return _query(rowID,ret, sql.c_str());
|
||||
}
|
||||
static const string &escape(const string &str) {
|
||||
try {
|
||||
//捕获创建对象异常
|
||||
_SqlPool::Instance().pool->obtain()->escape(
|
||||
const_cast<string &>(str));
|
||||
} catch (exception &e) {
|
||||
WarnL << e.what() << endl;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
private:
|
||||
_SqlPool() :
|
||||
threadPool(new ThreadPool(poolSize)), asyncTaskThread(10 * 1000) {
|
||||
poolsize = poolSize;
|
||||
asyncTaskThread.DoTaskDelay(reinterpret_cast<uint64_t>(this), 30 * 1000,
|
||||
[this]() {
|
||||
flushError();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
inline void doQuery(const string &str,int tryCnt = 3) {
|
||||
auto lam = [this,str,tryCnt]() {
|
||||
int64_t rowID;
|
||||
auto cnt = tryCnt - 1;
|
||||
if(_query(rowID,str.c_str())==-2 && cnt > 0) {
|
||||
lock_guard<mutex> lk(error_query_mutex);
|
||||
sqlQuery query(str,cnt);
|
||||
error_query.push_back(query);
|
||||
}
|
||||
};
|
||||
threadPool->async(lam);
|
||||
}
|
||||
template<typename ...Args>
|
||||
inline int64_t _query(int64_t &rowID,Args &&...arg) {
|
||||
typename PoolType::ValuePtr mysql;
|
||||
try {
|
||||
//捕获执行异常
|
||||
mysql = pool->obtain();
|
||||
return mysql->query(rowID,std::forward<Args>(arg)...);
|
||||
} catch (exception &e) {
|
||||
pool->quit(mysql);
|
||||
WarnL << e.what() << endl;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
void flushError() {
|
||||
decltype(error_query) query_copy;
|
||||
error_query_mutex.lock();
|
||||
query_copy.swap(error_query);
|
||||
error_query_mutex.unlock();
|
||||
if (query_copy.size() == 0) {
|
||||
return;
|
||||
}
|
||||
for (auto &query : query_copy) {
|
||||
doQuery(query.sql_str,query.tryCnt);
|
||||
}
|
||||
}
|
||||
virtual ~_SqlPool() {
|
||||
asyncTaskThread.CancelTask(reinterpret_cast<uint64_t>(this));
|
||||
flushError();
|
||||
threadPool.reset();
|
||||
pool.reset();
|
||||
InfoL;
|
||||
}
|
||||
std::shared_ptr<ThreadPool> threadPool;
|
||||
mutex error_query_mutex;
|
||||
class sqlQuery
|
||||
{
|
||||
public:
|
||||
sqlQuery(const string &sql,int cnt):sql_str(sql),tryCnt(cnt){}
|
||||
string sql_str;
|
||||
int tryCnt = 0;
|
||||
} ;
|
||||
deque<sqlQuery> error_query;
|
||||
|
||||
std::shared_ptr<PoolType> pool;
|
||||
AsyncTaskThread asyncTaskThread;
|
||||
unsigned int poolsize;
|
||||
}
|
||||
;
|
||||
typedef _SqlPool<1> SqlPool;
|
||||
|
||||
class SqlStream {
|
||||
public:
|
||||
SqlStream(const char *_sql) :
|
||||
sql(_sql) {
|
||||
startPos = 0;
|
||||
}
|
||||
~SqlStream() {
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SqlStream& operator <<(const T& data) {
|
||||
auto pos = sql.find_first_of('?', startPos);
|
||||
if (pos == string::npos) {
|
||||
return *this;
|
||||
}
|
||||
str_tmp.str("");
|
||||
str_tmp << data;
|
||||
string str = str_tmp.str();
|
||||
startPos = pos + str.size();
|
||||
sql.replace(pos, 1, str);
|
||||
return *this;
|
||||
}
|
||||
const string& operator <<(std::ostream&(*f)(std::ostream&)) const {
|
||||
return sql;
|
||||
}
|
||||
private:
|
||||
stringstream str_tmp;
|
||||
string sql;
|
||||
string::size_type startPos;
|
||||
};
|
||||
|
||||
class SqlWriter {
|
||||
public:
|
||||
SqlWriter(const char *_sql,bool _throwAble = true) :
|
||||
sqlstream(_sql),throwAble(_throwAble) {
|
||||
}
|
||||
~SqlWriter() {
|
||||
|
||||
}
|
||||
template<typename T>
|
||||
SqlWriter& operator <<(const T& data) {
|
||||
sqlstream << data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void operator <<(std::ostream&(*f)(std::ostream&)) {
|
||||
SqlPool::Instance().query(sqlstream << endl);
|
||||
}
|
||||
int64_t operator <<(vector<vector<string>> &ret) {
|
||||
affectedRows = SqlPool::Instance().query(rowId,ret, sqlstream << endl);
|
||||
if(affectedRows < 0 && throwAble){
|
||||
throw std::runtime_error("operate database failed");
|
||||
}
|
||||
return affectedRows;
|
||||
}
|
||||
int64_t getRowID() const {
|
||||
return rowId;
|
||||
}
|
||||
|
||||
int64_t getAffectedRows() const {
|
||||
return affectedRows;
|
||||
}
|
||||
|
||||
private:
|
||||
SqlStream sqlstream;
|
||||
int64_t rowId = 0;
|
||||
int64_t affectedRows = -1;
|
||||
bool throwAble = true;
|
||||
};
|
||||
|
||||
} /* namespace mysql */
|
||||
} /* namespace im */
|
||||
|
||||
#endif /* SQL_SQLPOOL_H_ */
|
||||
116
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/TimeTicker.h
Executable file
116
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/TimeTicker.h
Executable file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* TimeTicker.h
|
||||
*
|
||||
* Created on: 2015年12月30日
|
||||
* Author: root
|
||||
*/
|
||||
|
||||
#ifndef UTIL_TIMETICKER_H_
|
||||
#define UTIL_TIMETICKER_H_
|
||||
|
||||
#include "logger.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
class Ticker {
|
||||
public:
|
||||
Ticker(int64_t _minMs = 0, const char *_where = "",
|
||||
LogInfoMaker && _stream = LogInfoMaker(LWarn, __FILE__, "", __LINE__),bool printLog=false) :
|
||||
stream(_stream) {
|
||||
if(!printLog){
|
||||
stream.clear();
|
||||
}
|
||||
begin = getNowTime();
|
||||
created = begin;
|
||||
minMs = _minMs;
|
||||
where = _where;
|
||||
}
|
||||
virtual ~Ticker() {
|
||||
int64_t tm = getNowTime() - begin;
|
||||
if (tm > minMs) {
|
||||
stream << where << " take time:" << tm << endl;
|
||||
} else {
|
||||
stream.clear();
|
||||
}
|
||||
}
|
||||
uint64_t elapsedTime() {
|
||||
stream.clear();
|
||||
return getNowTime() - begin;
|
||||
}
|
||||
uint64_t createdTime() {
|
||||
stream.clear();
|
||||
return getNowTime() - created;
|
||||
}
|
||||
void resetTime() {
|
||||
stream.clear();
|
||||
begin = getNowTime();
|
||||
}
|
||||
|
||||
private:
|
||||
inline static uint64_t getNowTime() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
uint64_t begin;
|
||||
uint64_t created;
|
||||
LogInfoMaker stream;
|
||||
const char *where;
|
||||
int64_t minMs;
|
||||
|
||||
};
|
||||
class SmoothTicker {
|
||||
public:
|
||||
SmoothTicker(uint64_t _resetMs = 10000) {
|
||||
resetMs = _resetMs;
|
||||
ticker.resetTime();
|
||||
}
|
||||
virtual ~SmoothTicker() {
|
||||
}
|
||||
uint64_t elapsedTime() {
|
||||
auto nowTime = ticker.elapsedTime();
|
||||
if (firstTime == 0) {
|
||||
firstTime = nowTime;
|
||||
lastTime = nowTime;
|
||||
pktCount = 0;
|
||||
return nowTime;
|
||||
}
|
||||
uint64_t elapseTime = (nowTime - firstTime);
|
||||
uint64_t retTime = lastTime + elapseTime / ++pktCount;
|
||||
lastTime = retTime;
|
||||
if (elapseTime > 10000) {
|
||||
firstTime = 0;
|
||||
}
|
||||
return retTime;
|
||||
}
|
||||
void resetTime(){
|
||||
firstTime = 0;
|
||||
pktCount = 0;
|
||||
lastTime = 0;
|
||||
ticker.resetTime();
|
||||
}
|
||||
private:
|
||||
uint64_t firstTime = 0;
|
||||
uint64_t pktCount = 0;
|
||||
uint64_t lastTime = 0;
|
||||
uint64_t resetMs;
|
||||
Ticker ticker;
|
||||
};
|
||||
|
||||
#if defined(_DEBUG)
|
||||
#define TimeTicker() Ticker(5,"",WarnL,true)
|
||||
#define TimeTicker1(tm) Ticker(tm,"",WarnL,true)
|
||||
#define TimeTicker2(tm,where) Ticker(tm,where,WarnL,true)
|
||||
#define TimeTicker3(tm,where,log) Ticker(tm,where,log,true)
|
||||
#else
|
||||
#define TimeTicker()
|
||||
#define TimeTicker1(tm)
|
||||
#define TimeTicker2(tm,where)
|
||||
#define TimeTicker3(tm,where,log)
|
||||
#endif
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* UTIL_TIMETICKER_H_ */
|
||||
64
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/function_traits.h
Executable file
64
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/function_traits.h
Executable file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* functiontraits.h
|
||||
*
|
||||
* Created on: 2017年3月15日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef SRC_UTIL_FUNCTION_TRAITS_H_
|
||||
#define SRC_UTIL_FUNCTION_TRAITS_H_
|
||||
|
||||
#include <tuple>
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
template<typename T>
|
||||
struct function_traits;
|
||||
|
||||
//普通函数
|
||||
template<typename Ret, typename... Args>
|
||||
struct function_traits<Ret(Args...)>
|
||||
{
|
||||
public:
|
||||
enum { arity = sizeof...(Args) };
|
||||
typedef Ret function_type(Args...);
|
||||
typedef Ret return_type;
|
||||
using stl_function_type = std::function<function_type>;
|
||||
typedef Ret(*pointer)(Args...);
|
||||
|
||||
template<size_t I>
|
||||
struct args
|
||||
{
|
||||
static_assert(I < arity, "index is out of range, index must less than sizeof Args");
|
||||
using type = typename std::tuple_element<I, std::tuple<Args...> >::type;
|
||||
};
|
||||
};
|
||||
|
||||
//函数指针
|
||||
template<typename Ret, typename... Args>
|
||||
struct function_traits<Ret(*)(Args...)> : function_traits<Ret(Args...)>{};
|
||||
|
||||
//std::function
|
||||
template <typename Ret, typename... Args>
|
||||
struct function_traits<std::function<Ret(Args...)>> : function_traits<Ret(Args...)>{};
|
||||
|
||||
//member function
|
||||
#define FUNCTION_TRAITS(...) \
|
||||
template <typename ReturnType, typename ClassType, typename... Args>\
|
||||
struct function_traits<ReturnType(ClassType::*)(Args...) __VA_ARGS__> : function_traits<ReturnType(Args...)>{}; \
|
||||
|
||||
FUNCTION_TRAITS()
|
||||
FUNCTION_TRAITS(const)
|
||||
FUNCTION_TRAITS(volatile)
|
||||
FUNCTION_TRAITS(const volatile)
|
||||
|
||||
//函数对象
|
||||
template<typename Callable>
|
||||
struct function_traits : function_traits<decltype(&Callable::operator())>{};
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* SRC_UTIL_FUNCTION_TRAITS_H_ */
|
||||
400
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/logger.h
Executable file
400
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/logger.h
Executable file
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* logger.h
|
||||
*
|
||||
* Created on: 2016年8月3日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef UTIL_LOGGER_H_
|
||||
#define UTIL_LOGGER_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <ctime>
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <time.h>
|
||||
#include <condition_variable>
|
||||
#include "Util/util.h"
|
||||
#include "Thread/semaphore.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ZL::Thread;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
enum LogLevel {
|
||||
LTrace = 0, LDebug, LInfo, LWarn, LError, LFatal,
|
||||
};
|
||||
static const char *LogLevelStr[] = { "trace", "debug", "info", "warn", "error",
|
||||
"fatal" };
|
||||
|
||||
#define CLEAR_COLOR "\033[0m"
|
||||
#define UNDERLINE "\033[4m"
|
||||
|
||||
static const char *COLOR[6][2] = { { "\033[44;37m", "\033[34m" }, {
|
||||
"\033[42;37m", "\033[32m" }, { "\033[46;37m", "\033[36m" }, {
|
||||
"\033[43;37m", "\033[33m" }, { "\033[45;37m", "\033[35m" }, {
|
||||
"\033[41;37m", "\033[31m" } };
|
||||
|
||||
class Logger;
|
||||
class LogWriter;
|
||||
class LogChannel;
|
||||
class LogInfo;
|
||||
class LogInfoMaker;
|
||||
|
||||
typedef std::shared_ptr<LogInfo> LogInfo_ptr;
|
||||
class LogChannel {
|
||||
public:
|
||||
LogChannel(const string& name, LogLevel level = LDebug,
|
||||
const char* timeFormat = "%Y-%m-%d %H:%M:%S") :
|
||||
_name(name), _level(level), _timeFormat(timeFormat) {
|
||||
}
|
||||
virtual ~LogChannel() {
|
||||
}
|
||||
virtual void write(const LogInfo_ptr & stream)=0;
|
||||
const string &name() const {
|
||||
return _name;
|
||||
}
|
||||
LogLevel level() const {
|
||||
return _level;
|
||||
}
|
||||
const string &timeFormat() const {
|
||||
return _timeFormat;
|
||||
}
|
||||
void setLevel(LogLevel level) {
|
||||
_level = level;
|
||||
}
|
||||
void setDateFormat(const char* format) {
|
||||
_timeFormat = format;
|
||||
}
|
||||
protected:
|
||||
string _name;
|
||||
LogLevel _level;
|
||||
string _timeFormat;
|
||||
};
|
||||
|
||||
class LogWriter {
|
||||
public:
|
||||
LogWriter() {
|
||||
}
|
||||
virtual ~LogWriter() {
|
||||
}
|
||||
virtual void write(const LogInfo_ptr &stream) =0;
|
||||
};
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
friend class LogWriter;
|
||||
friend class AsyncLogWriter;
|
||||
static Logger& Instance() {
|
||||
static Logger *logger(new Logger());
|
||||
return *logger;
|
||||
}
|
||||
static void Destory() {
|
||||
delete &Logger::Instance();
|
||||
}
|
||||
void add(const std::shared_ptr<LogChannel> &&channel) {
|
||||
channels[channel->name()] = channel;
|
||||
}
|
||||
void del(const string& name) {
|
||||
auto it = channels.find(name);
|
||||
if (it != channels.end()) {
|
||||
channels.erase(it);
|
||||
}
|
||||
}
|
||||
std::shared_ptr<LogChannel> get(const string& name){
|
||||
auto it = channels.find(name);
|
||||
if(it == channels.end()){
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void setWriter(const std::shared_ptr<LogWriter> &&_writer) {
|
||||
if (_writer) {
|
||||
this->writer = _writer;
|
||||
}
|
||||
}
|
||||
void write(const LogInfo_ptr &stream) {
|
||||
if (writer) {
|
||||
writer->write(stream);
|
||||
return;
|
||||
}
|
||||
for (auto &chn : channels) {
|
||||
chn.second->write(stream);
|
||||
}
|
||||
}
|
||||
void setLevel(LogLevel level) {
|
||||
for (auto &chn : channels) {
|
||||
chn.second->setLevel(level);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
Logger() {
|
||||
}
|
||||
~Logger() {
|
||||
}
|
||||
// Non-copyable and non-movable
|
||||
Logger(const Logger&); // = delete;
|
||||
Logger(Logger&&); // = delete;
|
||||
Logger& operator=(const Logger&); // = delete;
|
||||
Logger& operator=(Logger&&); // = delete;
|
||||
|
||||
map<string, std::shared_ptr<LogChannel> > channels;
|
||||
std::shared_ptr<LogWriter> writer;
|
||||
};
|
||||
|
||||
class LogInfo {
|
||||
public:
|
||||
friend class LogInfoMaker;
|
||||
void format(ostream& ost, const char *timeFormat = "%Y-%m-%d %H:%M:%S",
|
||||
bool enableColor = true) {
|
||||
static string appName = exeName();
|
||||
ost << appName << " "<< file << " " << line << "\r\n ";
|
||||
if (enableColor) {
|
||||
ost << COLOR[level][1];
|
||||
}
|
||||
if (timeFormat) {
|
||||
ost << print(toLocal(ts), timeFormat);
|
||||
}
|
||||
ost << " [" << LogLevelStr[level] << "] ";
|
||||
ost << function << " ";
|
||||
ost << message.str();
|
||||
if (enableColor) {
|
||||
ost << CLEAR_COLOR;
|
||||
}
|
||||
ost.flush();
|
||||
}
|
||||
|
||||
LogLevel getLevel() const {
|
||||
return level;
|
||||
}
|
||||
|
||||
private:
|
||||
LogInfo(LogLevel _level, const char* _file, const char* _function,
|
||||
int _line) :
|
||||
level(_level), line(_line), file(_file), function(_function), ts(
|
||||
::time(NULL)) {
|
||||
}
|
||||
std::string print(const std::tm& dt, const char* fmt) {
|
||||
/*
|
||||
#if defined(__WIN32__)
|
||||
// BOGUS hack done for VS2012: C++11 non-conformant since it SHOULD take a "const struct tm* "
|
||||
// ref. C++11 standard: ISO/IEC 14882:2011, <20> 27.7.1,
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(const_cast<std::tm*>(&dt), fmt);
|
||||
return oss.str();
|
||||
|
||||
#else // LINUX
|
||||
*/
|
||||
const size_t size = 1024;
|
||||
char buffer[size];
|
||||
auto success = std::strftime(buffer, size, fmt, &dt);
|
||||
if (0 == success)
|
||||
return string(fmt);
|
||||
return buffer;
|
||||
//#endif
|
||||
}
|
||||
|
||||
std::tm toLocal(const std::time_t& time) {
|
||||
std::tm tm_snapshot;
|
||||
|
||||
#if defined(_WIN32)
|
||||
localtime_s(&tm_snapshot, &time); // thread-safe?
|
||||
#else
|
||||
localtime_r(&time, &tm_snapshot); // POSIX
|
||||
#endif //WIN32
|
||||
return tm_snapshot;
|
||||
}
|
||||
LogLevel level;
|
||||
int line;
|
||||
string file;
|
||||
string function;
|
||||
time_t ts;
|
||||
ostringstream message;
|
||||
};
|
||||
|
||||
class LogInfoMaker {
|
||||
public:
|
||||
LogInfoMaker(LogLevel level, const char* file, const char* function,
|
||||
int line) :
|
||||
logInfo(new LogInfo(level, file, function, line)) {
|
||||
}
|
||||
LogInfoMaker(LogInfoMaker &&that) {
|
||||
this->logInfo = that.logInfo;
|
||||
that.logInfo.reset();
|
||||
}
|
||||
LogInfoMaker(const LogInfoMaker &that) {
|
||||
this->logInfo = that.logInfo;
|
||||
(const_cast<LogInfoMaker &>(that)).logInfo.reset();
|
||||
}
|
||||
~LogInfoMaker() {
|
||||
*this << endl;
|
||||
}
|
||||
template<typename T>
|
||||
LogInfoMaker& operator <<(const T& data) {
|
||||
if (!logInfo) {
|
||||
return *this;
|
||||
}
|
||||
logInfo->message << data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogInfoMaker& operator <<(const char *data) {
|
||||
if (!logInfo) {
|
||||
return *this;
|
||||
}
|
||||
if(data){
|
||||
logInfo->message << data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogInfoMaker& operator <<(ostream&(*f)(ostream&)) {
|
||||
if (!logInfo) {
|
||||
return *this;
|
||||
}
|
||||
logInfo->message << f;
|
||||
Logger::Instance().write(logInfo);
|
||||
logInfo.reset();
|
||||
return *this;
|
||||
}
|
||||
void clear() {
|
||||
logInfo.reset();
|
||||
}
|
||||
private:
|
||||
LogInfo_ptr logInfo;
|
||||
};
|
||||
|
||||
class AsyncLogWriter: public LogWriter {
|
||||
public:
|
||||
AsyncLogWriter() :
|
||||
exit_flag(false) {
|
||||
_thread.reset(new thread([this]() {this->run();}));
|
||||
|
||||
}
|
||||
virtual ~AsyncLogWriter() {
|
||||
exit_flag = true;
|
||||
sem.post();
|
||||
_thread->join();
|
||||
while (_pending.size()) {
|
||||
auto &next = _pending.front();
|
||||
realWrite(next);
|
||||
_pending.pop_front();
|
||||
}
|
||||
|
||||
}
|
||||
virtual void write(const LogInfo_ptr &stream) {
|
||||
{
|
||||
lock_guard<mutex> lock(_mutex);
|
||||
_pending.push_back(stream);
|
||||
}
|
||||
sem.post();
|
||||
}
|
||||
protected:
|
||||
void run() {
|
||||
while (!exit_flag) {
|
||||
sem.wait();
|
||||
{
|
||||
lock_guard<mutex> lock(_mutex);
|
||||
if (_pending.size()) {
|
||||
auto &next = _pending.front();
|
||||
realWrite(next);
|
||||
_pending.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void realWrite(const LogInfo_ptr &stream) {
|
||||
for (auto &chn : Logger::Instance().channels) {
|
||||
chn.second->write(stream);
|
||||
}
|
||||
}
|
||||
bool exit_flag;
|
||||
std::shared_ptr<thread> _thread;
|
||||
deque<LogInfo_ptr> _pending;
|
||||
semaphore sem;
|
||||
mutex _mutex;
|
||||
};
|
||||
|
||||
class ConsoleChannel: public LogChannel {
|
||||
public:
|
||||
ConsoleChannel(const string& name, LogLevel level = LDebug,
|
||||
const char* timeFormat = "%Y-%m-%d %H:%M:%S") :
|
||||
LogChannel(name, level, timeFormat) {
|
||||
}
|
||||
virtual ~ConsoleChannel() {
|
||||
}
|
||||
void write(const LogInfo_ptr &logInfo) {
|
||||
if (level() > logInfo->getLevel()) {
|
||||
return;
|
||||
}
|
||||
logInfo->format(std::cout, timeFormat().c_str(), true);
|
||||
}
|
||||
};
|
||||
|
||||
class FileChannel: public LogChannel {
|
||||
public:
|
||||
FileChannel(const string& name, const string& path, LogLevel level = LDebug,
|
||||
const char* timeFormat = "%Y-%m-%d %H:%M:%S") :
|
||||
LogChannel(name, level, timeFormat), _path(path) {
|
||||
}
|
||||
virtual ~FileChannel() {
|
||||
close();
|
||||
}
|
||||
virtual void write(const std::shared_ptr<LogInfo> &stream) {
|
||||
if (level() > stream->getLevel()) {
|
||||
return;
|
||||
}
|
||||
if (!_fstream.is_open()) {
|
||||
open();
|
||||
}
|
||||
stream->format(_fstream, timeFormat().c_str(), false);
|
||||
}
|
||||
void setPath(const string& path) {
|
||||
_path = path;
|
||||
open();
|
||||
}
|
||||
const string &path() const {
|
||||
return _path;
|
||||
}
|
||||
protected:
|
||||
virtual void open() {
|
||||
// Ensure a path was set
|
||||
if (_path.empty()) {
|
||||
throw runtime_error("Log file path must be set.");
|
||||
}
|
||||
// Open the file stream
|
||||
_fstream.close();
|
||||
_fstream.open(_path.c_str(), ios::out | ios::app);
|
||||
// Throw on failure
|
||||
if (!_fstream.is_open()) {
|
||||
throw runtime_error("Failed to open log file: " + _path);
|
||||
}
|
||||
}
|
||||
virtual void close() {
|
||||
_fstream.close();
|
||||
}
|
||||
ofstream _fstream;
|
||||
string _path;
|
||||
};
|
||||
|
||||
#define TraceL LogInfoMaker(LTrace, __FILE__,__FUNCTION__, __LINE__)
|
||||
#define DebugL LogInfoMaker(LDebug, __FILE__,__FUNCTION__, __LINE__)
|
||||
#define InfoL LogInfoMaker(LInfo, __FILE__,__FUNCTION__, __LINE__)
|
||||
#define WarnL LogInfoMaker(LWarn,__FILE__, __FUNCTION__, __LINE__)
|
||||
#define ErrorL LogInfoMaker(LError,__FILE__, __FUNCTION__, __LINE__)
|
||||
#define FatalL LogInfoMaker(LFatal,__FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
} /* namespace util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* UTIL_LOGGER_H_ */
|
||||
149
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/mini.h
Executable file
149
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/mini.h
Executable file
@@ -0,0 +1,149 @@
|
||||
|
||||
|
||||
#ifndef UTIL_MINI_H
|
||||
#define UTIL_MINI_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
|
||||
template<typename key, typename variant>
|
||||
class mINI_basic: public map<key, variant> {
|
||||
// Public API : existing map<> interface plus following methods
|
||||
public:
|
||||
void parse(const string &text) {
|
||||
// reset, split lines and parse
|
||||
static auto trim = []( string line ) {
|
||||
while( line.size() && ( line.back()=='\t' || line.back()==' ' ) ) line.pop_back();
|
||||
while( line.size() && ( line.front()=='\t' || line.front()==' ' ) ) line.erase(0,1);
|
||||
return line;
|
||||
};
|
||||
vector<string> lines = tokenize(text, "\r\n");
|
||||
string symbol, tag;
|
||||
for (auto &line : lines){
|
||||
// trim blanks
|
||||
line = trim(line);
|
||||
// split line into tokens and parse tokens
|
||||
if(line.empty() || line.front() == ';' || line.front() == '#'){
|
||||
continue;
|
||||
}
|
||||
if (line.size() >= 3 && line.front() == '[' && line.back() == ']') {
|
||||
tag = trim(line.substr(1, line.size() - 2));
|
||||
} else {
|
||||
auto at = line.find_first_of('=');
|
||||
symbol = trim(tag + "." + line.substr(0, at));
|
||||
(*this)[symbol] = (at == string::npos ? string() : trim(line.substr(at + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
void parseFile(const string &fileName = exePath() + ".ini") {
|
||||
ifstream in(fileName, ios::in | ios::binary | ios::ate);
|
||||
if (!in.good()) {
|
||||
stringstream ss;
|
||||
ss << "invalid ini file:" << fileName;
|
||||
throw invalid_argument(ss.str());
|
||||
}
|
||||
long size = in.tellg();
|
||||
in.seekg(0, ios::beg);
|
||||
string buf;
|
||||
buf.resize(size);
|
||||
in.read((char *) buf.data(), size);
|
||||
parse(buf);
|
||||
}
|
||||
|
||||
string dump(const string &header = "; auto-generated by mINI class {",
|
||||
const string &footer = "; } ---") const {
|
||||
string output(header + (header.empty() ? "" : "\r\n")), tag;
|
||||
for (auto &pr : *this) {
|
||||
vector<string> kv = tokenize(pr.first, ".");
|
||||
if (tag != kv[0]) {
|
||||
output += "\r\n[" + (tag = kv[0]) + "]\r\n";
|
||||
}
|
||||
output += kv[1] + "=" + pr.second + "\r\n";
|
||||
}
|
||||
return output + "\r\n" + footer + (footer.empty() ? "" : "\r\n");
|
||||
}
|
||||
|
||||
void dumpFile(const string &fileName = exePath() + ".ini") {
|
||||
ofstream out(fileName, ios::out | ios::binary | ios::trunc);
|
||||
auto dmp = dump();
|
||||
out.write(dmp.data(),dmp.size());
|
||||
}
|
||||
static mINI_basic &Instance(){
|
||||
static mINI_basic instance;
|
||||
return instance;
|
||||
}
|
||||
private:
|
||||
vector<string> tokenize(const string &self, const string &chars) const {
|
||||
vector<string> tokens(1);
|
||||
string map(256, '\0');
|
||||
for (const unsigned char &ch : chars) {
|
||||
map[ch] = '\1';
|
||||
}
|
||||
for (const unsigned char &ch : self) {
|
||||
if (!map.at(ch)) {
|
||||
tokens.back().push_back(char(ch));
|
||||
} else if (tokens.back().size()) {
|
||||
tokens.push_back(string());
|
||||
}
|
||||
}
|
||||
while (tokens.size() && tokens.back().empty()) {
|
||||
tokens.pop_back();
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
};
|
||||
|
||||
// handy variant class as key/values
|
||||
struct variant: public string {
|
||||
template<typename T>
|
||||
variant(const T &t) :
|
||||
string(to_string(t)) {
|
||||
}
|
||||
template<size_t N>
|
||||
variant(const char (&s)[N]) :
|
||||
string(s, N) {
|
||||
}
|
||||
variant(const char *cstr) :
|
||||
string(cstr) {
|
||||
}
|
||||
variant(const string &other = string()) :
|
||||
string(other) {
|
||||
}
|
||||
template<typename T>
|
||||
operator T() const {
|
||||
T t;
|
||||
stringstream ss;
|
||||
return ss << *this && ss >> t ? t : T();
|
||||
}
|
||||
template<typename T> bool operator ==(const T &t) const {
|
||||
return 0 == this->compare(variant(t));
|
||||
}
|
||||
bool operator ==(const char *t) const {
|
||||
return this->compare(t) == 0;
|
||||
}
|
||||
template<typename T>
|
||||
T as() const {
|
||||
return (T) (*this);
|
||||
}
|
||||
};
|
||||
|
||||
using mINI = mINI_basic<string, variant>;
|
||||
|
||||
} // namespace Util
|
||||
} // namespace ZL
|
||||
|
||||
#endif //UTIL_MINI_H
|
||||
|
||||
44
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/onceToken.h
Executable file
44
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/onceToken.h
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* onceToken.h
|
||||
*
|
||||
* Created on: 2016年8月10日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef UTIL_ONCETOKEN_H_
|
||||
#define UTIL_ONCETOKEN_H_
|
||||
|
||||
#include "functional"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
class onceToken {
|
||||
public:
|
||||
typedef function<void(void)> task;
|
||||
onceToken(const task &onConstructed, const task &_onDestructed) {
|
||||
if (onConstructed) {
|
||||
onConstructed();
|
||||
}
|
||||
onDestructed = _onDestructed;
|
||||
}
|
||||
virtual ~onceToken() {
|
||||
if (onDestructed) {
|
||||
onDestructed();
|
||||
}
|
||||
}
|
||||
private:
|
||||
onceToken();
|
||||
onceToken(const onceToken &);
|
||||
onceToken(onceToken &&);
|
||||
onceToken &operator =(const onceToken &);
|
||||
onceToken &operator =(onceToken &&);
|
||||
task onDestructed;
|
||||
};
|
||||
|
||||
} /* namespace Util */
|
||||
} /* namespace ZL */
|
||||
|
||||
#endif /* UTIL_ONCETOKEN_H_ */
|
||||
79
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/util.h
Executable file
79
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/util.h
Executable file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* util.h
|
||||
*
|
||||
* Created on: 2016年8月4日
|
||||
* Author: xzl
|
||||
*/
|
||||
|
||||
#ifndef UTIL_UTIL_H_
|
||||
#define UTIL_UTIL_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <WinSock2.h>
|
||||
#pragma comment (lib,"WS2_32")
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ZL {
|
||||
namespace Util {
|
||||
|
||||
class _StrPrinter {
|
||||
public:
|
||||
_StrPrinter() {
|
||||
}
|
||||
template<typename T>
|
||||
_StrPrinter& operator <<(const T& data) {
|
||||
ss << data;
|
||||
return *this;
|
||||
}
|
||||
string operator <<(std::ostream&(*f)(std::ostream&)) const {
|
||||
return ss.str();
|
||||
}
|
||||
private:
|
||||
stringstream ss;
|
||||
};
|
||||
|
||||
#define StrPrinter _StrPrinter()
|
||||
|
||||
string makeRandStr(int sz, bool printable = true);
|
||||
string hexdump(const void *buf, size_t len);
|
||||
string exePath();
|
||||
string exeDir();
|
||||
string exeName();
|
||||
void setExePath(const string &path);
|
||||
|
||||
#ifndef bzero
|
||||
#define bzero(ptr,size) memset((ptr),0,(size));
|
||||
#endif //bzero
|
||||
|
||||
#if defined(ANDROID)
|
||||
template <typename T>
|
||||
std::string to_string(T value){
|
||||
std::ostringstream os ;
|
||||
os << std::forward<T>(value);
|
||||
return os.str() ;
|
||||
}
|
||||
#endif//ANDROID
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
int gettimeofday(struct timeval *tp, void *tzp);
|
||||
int strcasecmp(const char *strA,const char *strB);
|
||||
void usleep(int micro_seconds);
|
||||
void sleep(int second);
|
||||
|
||||
#endif //WIN32
|
||||
|
||||
} // namespace Util
|
||||
} // namespace ZL
|
||||
|
||||
#endif /* UTIL_UTIL_H_ */
|
||||
522
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/uv_errno.h
Executable file
522
bin_lib/windows/ZLToolKit/include/ZLToolKit/Util/uv_errno.h
Executable file
@@ -0,0 +1,522 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UV_ERRNO_H_
|
||||
#define UV_ERRNO_H_
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define UV__EOF (-4095)
|
||||
#define UV__UNKNOWN (-4094)
|
||||
|
||||
#define UV__EAI_ADDRFAMILY (-3000)
|
||||
#define UV__EAI_AGAIN (-3001)
|
||||
#define UV__EAI_BADFLAGS (-3002)
|
||||
#define UV__EAI_CANCELED (-3003)
|
||||
#define UV__EAI_FAIL (-3004)
|
||||
#define UV__EAI_FAMILY (-3005)
|
||||
#define UV__EAI_MEMORY (-3006)
|
||||
#define UV__EAI_NODATA (-3007)
|
||||
#define UV__EAI_NONAME (-3008)
|
||||
#define UV__EAI_OVERFLOW (-3009)
|
||||
#define UV__EAI_SERVICE (-3010)
|
||||
#define UV__EAI_SOCKTYPE (-3011)
|
||||
#define UV__EAI_BADHINTS (-3013)
|
||||
#define UV__EAI_PROTOCOL (-3014)
|
||||
|
||||
/* Only map to the system errno on non-Windows platforms. It's apparently
|
||||
* a fairly common practice for Windows programmers to redefine errno codes.
|
||||
*/
|
||||
#if defined(E2BIG) && !defined(_WIN32)
|
||||
# define UV__E2BIG (-E2BIG)
|
||||
#else
|
||||
# define UV__E2BIG (-4093)
|
||||
#endif
|
||||
|
||||
#if defined(EACCES) && !defined(_WIN32)
|
||||
# define UV__EACCES (-EACCES)
|
||||
#else
|
||||
# define UV__EACCES (-4092)
|
||||
#endif
|
||||
|
||||
#if defined(EADDRINUSE) && !defined(_WIN32)
|
||||
# define UV__EADDRINUSE (-EADDRINUSE)
|
||||
#else
|
||||
# define UV__EADDRINUSE (-4091)
|
||||
#endif
|
||||
|
||||
#if defined(EADDRNOTAVAIL) && !defined(_WIN32)
|
||||
# define UV__EADDRNOTAVAIL (-EADDRNOTAVAIL)
|
||||
#else
|
||||
# define UV__EADDRNOTAVAIL (-4090)
|
||||
#endif
|
||||
|
||||
#if defined(EAFNOSUPPORT) && !defined(_WIN32)
|
||||
# define UV__EAFNOSUPPORT (-EAFNOSUPPORT)
|
||||
#else
|
||||
# define UV__EAFNOSUPPORT (-4089)
|
||||
#endif
|
||||
|
||||
#if defined(EAGAIN) && !defined(_WIN32)
|
||||
# define UV__EAGAIN (-EAGAIN)
|
||||
#else
|
||||
# define UV__EAGAIN (-4088)
|
||||
#endif
|
||||
|
||||
#if defined(EALREADY) && !defined(_WIN32)
|
||||
# define UV__EALREADY (-EALREADY)
|
||||
#else
|
||||
# define UV__EALREADY (-4084)
|
||||
#endif
|
||||
|
||||
#if defined(EBADF) && !defined(_WIN32)
|
||||
# define UV__EBADF (-EBADF)
|
||||
#else
|
||||
# define UV__EBADF (-4083)
|
||||
#endif
|
||||
|
||||
#if defined(EBUSY) && !defined(_WIN32)
|
||||
# define UV__EBUSY (-EBUSY)
|
||||
#else
|
||||
# define UV__EBUSY (-4082)
|
||||
#endif
|
||||
|
||||
#if defined(ECANCELED) && !defined(_WIN32)
|
||||
# define UV__ECANCELED (-ECANCELED)
|
||||
#else
|
||||
# define UV__ECANCELED (-4081)
|
||||
#endif
|
||||
|
||||
#if defined(ECHARSET) && !defined(_WIN32)
|
||||
# define UV__ECHARSET (-ECHARSET)
|
||||
#else
|
||||
# define UV__ECHARSET (-4080)
|
||||
#endif
|
||||
|
||||
#if defined(ECONNABORTED) && !defined(_WIN32)
|
||||
# define UV__ECONNABORTED (-ECONNABORTED)
|
||||
#else
|
||||
# define UV__ECONNABORTED (-4079)
|
||||
#endif
|
||||
|
||||
#if defined(ECONNREFUSED) && !defined(_WIN32)
|
||||
# define UV__ECONNREFUSED (-ECONNREFUSED)
|
||||
#else
|
||||
# define UV__ECONNREFUSED (-4078)
|
||||
#endif
|
||||
|
||||
#if defined(ECONNRESET) && !defined(_WIN32)
|
||||
# define UV__ECONNRESET (-ECONNRESET)
|
||||
#else
|
||||
# define UV__ECONNRESET (-4077)
|
||||
#endif
|
||||
|
||||
#if defined(EDESTADDRREQ) && !defined(_WIN32)
|
||||
# define UV__EDESTADDRREQ (-EDESTADDRREQ)
|
||||
#else
|
||||
# define UV__EDESTADDRREQ (-4076)
|
||||
#endif
|
||||
|
||||
#if defined(EEXIST) && !defined(_WIN32)
|
||||
# define UV__EEXIST (-EEXIST)
|
||||
#else
|
||||
# define UV__EEXIST (-4075)
|
||||
#endif
|
||||
|
||||
#if defined(EFAULT) && !defined(_WIN32)
|
||||
# define UV__EFAULT (-EFAULT)
|
||||
#else
|
||||
# define UV__EFAULT (-4074)
|
||||
#endif
|
||||
|
||||
#if defined(EHOSTUNREACH) && !defined(_WIN32)
|
||||
# define UV__EHOSTUNREACH (-EHOSTUNREACH)
|
||||
#else
|
||||
# define UV__EHOSTUNREACH (-4073)
|
||||
#endif
|
||||
|
||||
#if defined(EINTR) && !defined(_WIN32)
|
||||
# define UV__EINTR (-EINTR)
|
||||
#else
|
||||
# define UV__EINTR (-4072)
|
||||
#endif
|
||||
|
||||
#if defined(EINVAL) && !defined(_WIN32)
|
||||
# define UV__EINVAL (-EINVAL)
|
||||
#else
|
||||
# define UV__EINVAL (-4071)
|
||||
#endif
|
||||
|
||||
#if defined(EIO) && !defined(_WIN32)
|
||||
# define UV__EIO (-EIO)
|
||||
#else
|
||||
# define UV__EIO (-4070)
|
||||
#endif
|
||||
|
||||
#if defined(EISCONN) && !defined(_WIN32)
|
||||
# define UV__EISCONN (-EISCONN)
|
||||
#else
|
||||
# define UV__EISCONN (-4069)
|
||||
#endif
|
||||
|
||||
#if defined(EISDIR) && !defined(_WIN32)
|
||||
# define UV__EISDIR (-EISDIR)
|
||||
#else
|
||||
# define UV__EISDIR (-4068)
|
||||
#endif
|
||||
|
||||
#if defined(ELOOP) && !defined(_WIN32)
|
||||
# define UV__ELOOP (-ELOOP)
|
||||
#else
|
||||
# define UV__ELOOP (-4067)
|
||||
#endif
|
||||
|
||||
#if defined(EMFILE) && !defined(_WIN32)
|
||||
# define UV__EMFILE (-EMFILE)
|
||||
#else
|
||||
# define UV__EMFILE (-4066)
|
||||
#endif
|
||||
|
||||
#if defined(EMSGSIZE) && !defined(_WIN32)
|
||||
# define UV__EMSGSIZE (-EMSGSIZE)
|
||||
#else
|
||||
# define UV__EMSGSIZE (-4065)
|
||||
#endif
|
||||
|
||||
#if defined(ENAMETOOLONG) && !defined(_WIN32)
|
||||
# define UV__ENAMETOOLONG (-ENAMETOOLONG)
|
||||
#else
|
||||
# define UV__ENAMETOOLONG (-4064)
|
||||
#endif
|
||||
|
||||
#if defined(ENETDOWN) && !defined(_WIN32)
|
||||
# define UV__ENETDOWN (-ENETDOWN)
|
||||
#else
|
||||
# define UV__ENETDOWN (-4063)
|
||||
#endif
|
||||
|
||||
#if defined(ENETUNREACH) && !defined(_WIN32)
|
||||
# define UV__ENETUNREACH (-ENETUNREACH)
|
||||
#else
|
||||
# define UV__ENETUNREACH (-4062)
|
||||
#endif
|
||||
|
||||
#if defined(ENFILE) && !defined(_WIN32)
|
||||
# define UV__ENFILE (-ENFILE)
|
||||
#else
|
||||
# define UV__ENFILE (-4061)
|
||||
#endif
|
||||
|
||||
#if defined(ENOBUFS) && !defined(_WIN32)
|
||||
# define UV__ENOBUFS (-ENOBUFS)
|
||||
#else
|
||||
# define UV__ENOBUFS (-4060)
|
||||
#endif
|
||||
|
||||
#if defined(ENODEV) && !defined(_WIN32)
|
||||
# define UV__ENODEV (-ENODEV)
|
||||
#else
|
||||
# define UV__ENODEV (-4059)
|
||||
#endif
|
||||
|
||||
#if defined(ENOENT) && !defined(_WIN32)
|
||||
# define UV__ENOENT (-ENOENT)
|
||||
#else
|
||||
# define UV__ENOENT (-4058)
|
||||
#endif
|
||||
|
||||
#if defined(ENOMEM) && !defined(_WIN32)
|
||||
# define UV__ENOMEM (-ENOMEM)
|
||||
#else
|
||||
# define UV__ENOMEM (-4057)
|
||||
#endif
|
||||
|
||||
#if defined(ENONET) && !defined(_WIN32)
|
||||
# define UV__ENONET (-ENONET)
|
||||
#else
|
||||
# define UV__ENONET (-4056)
|
||||
#endif
|
||||
|
||||
#if defined(ENOSPC) && !defined(_WIN32)
|
||||
# define UV__ENOSPC (-ENOSPC)
|
||||
#else
|
||||
# define UV__ENOSPC (-4055)
|
||||
#endif
|
||||
|
||||
#if defined(ENOSYS) && !defined(_WIN32)
|
||||
# define UV__ENOSYS (-ENOSYS)
|
||||
#else
|
||||
# define UV__ENOSYS (-4054)
|
||||
#endif
|
||||
|
||||
#if defined(ENOTCONN) && !defined(_WIN32)
|
||||
# define UV__ENOTCONN (-ENOTCONN)
|
||||
#else
|
||||
# define UV__ENOTCONN (-4053)
|
||||
#endif
|
||||
|
||||
#if defined(ENOTDIR) && !defined(_WIN32)
|
||||
# define UV__ENOTDIR (-ENOTDIR)
|
||||
#else
|
||||
# define UV__ENOTDIR (-4052)
|
||||
#endif
|
||||
|
||||
#if defined(ENOTEMPTY) && !defined(_WIN32)
|
||||
# define UV__ENOTEMPTY (-ENOTEMPTY)
|
||||
#else
|
||||
# define UV__ENOTEMPTY (-4051)
|
||||
#endif
|
||||
|
||||
#if defined(ENOTSOCK) && !defined(_WIN32)
|
||||
# define UV__ENOTSOCK (-ENOTSOCK)
|
||||
#else
|
||||
# define UV__ENOTSOCK (-4050)
|
||||
#endif
|
||||
|
||||
#if defined(ENOTSUP) && !defined(_WIN32)
|
||||
# define UV__ENOTSUP (-ENOTSUP)
|
||||
#else
|
||||
# define UV__ENOTSUP (-4049)
|
||||
#endif
|
||||
|
||||
#if defined(EPERM) && !defined(_WIN32)
|
||||
# define UV__EPERM (-EPERM)
|
||||
#else
|
||||
# define UV__EPERM (-4048)
|
||||
#endif
|
||||
|
||||
#if defined(EPIPE) && !defined(_WIN32)
|
||||
# define UV__EPIPE (-EPIPE)
|
||||
#else
|
||||
# define UV__EPIPE (-4047)
|
||||
#endif
|
||||
|
||||
#if defined(EPROTO) && !defined(_WIN32)
|
||||
# define UV__EPROTO (-EPROTO)
|
||||
#else
|
||||
# define UV__EPROTO (-4046)
|
||||
#endif
|
||||
|
||||
#if defined(EPROTONOSUPPORT) && !defined(_WIN32)
|
||||
# define UV__EPROTONOSUPPORT (-EPROTONOSUPPORT)
|
||||
#else
|
||||
# define UV__EPROTONOSUPPORT (-4045)
|
||||
#endif
|
||||
|
||||
#if defined(EPROTOTYPE) && !defined(_WIN32)
|
||||
# define UV__EPROTOTYPE (-EPROTOTYPE)
|
||||
#else
|
||||
# define UV__EPROTOTYPE (-4044)
|
||||
#endif
|
||||
|
||||
#if defined(EROFS) && !defined(_WIN32)
|
||||
# define UV__EROFS (-EROFS)
|
||||
#else
|
||||
# define UV__EROFS (-4043)
|
||||
#endif
|
||||
|
||||
#if defined(ESHUTDOWN) && !defined(_WIN32)
|
||||
# define UV__ESHUTDOWN (-ESHUTDOWN)
|
||||
#else
|
||||
# define UV__ESHUTDOWN (-4042)
|
||||
#endif
|
||||
|
||||
#if defined(ESPIPE) && !defined(_WIN32)
|
||||
# define UV__ESPIPE (-ESPIPE)
|
||||
#else
|
||||
# define UV__ESPIPE (-4041)
|
||||
#endif
|
||||
|
||||
#if defined(ESRCH) && !defined(_WIN32)
|
||||
# define UV__ESRCH (-ESRCH)
|
||||
#else
|
||||
# define UV__ESRCH (-4040)
|
||||
#endif
|
||||
|
||||
#if defined(ETIMEDOUT) && !defined(_WIN32)
|
||||
# define UV__ETIMEDOUT (-ETIMEDOUT)
|
||||
#else
|
||||
# define UV__ETIMEDOUT (-4039)
|
||||
#endif
|
||||
|
||||
#if defined(ETXTBSY) && !defined(_WIN32)
|
||||
# define UV__ETXTBSY (-ETXTBSY)
|
||||
#else
|
||||
# define UV__ETXTBSY (-4038)
|
||||
#endif
|
||||
|
||||
#if defined(EXDEV) && !defined(_WIN32)
|
||||
# define UV__EXDEV (-EXDEV)
|
||||
#else
|
||||
# define UV__EXDEV (-4037)
|
||||
#endif
|
||||
|
||||
#if defined(EFBIG) && !defined(_WIN32)
|
||||
# define UV__EFBIG (-EFBIG)
|
||||
#else
|
||||
# define UV__EFBIG (-4036)
|
||||
#endif
|
||||
|
||||
#if defined(ENOPROTOOPT) && !defined(_WIN32)
|
||||
# define UV__ENOPROTOOPT (-ENOPROTOOPT)
|
||||
#else
|
||||
# define UV__ENOPROTOOPT (-4035)
|
||||
#endif
|
||||
|
||||
#if defined(ERANGE) && !defined(_WIN32)
|
||||
# define UV__ERANGE (-ERANGE)
|
||||
#else
|
||||
# define UV__ERANGE (-4034)
|
||||
#endif
|
||||
|
||||
#if defined(ENXIO) && !defined(_WIN32)
|
||||
# define UV__ENXIO (-ENXIO)
|
||||
#else
|
||||
# define UV__ENXIO (-4033)
|
||||
#endif
|
||||
|
||||
#if defined(EMLINK) && !defined(_WIN32)
|
||||
# define UV__EMLINK (-EMLINK)
|
||||
#else
|
||||
# define UV__EMLINK (-4032)
|
||||
#endif
|
||||
|
||||
/* EHOSTDOWN is not visible on BSD-like systems when _POSIX_C_SOURCE is
|
||||
* defined. Fortunately, its value is always 64 so it's possible albeit
|
||||
* icky to hard-code it.
|
||||
*/
|
||||
#if defined(EHOSTDOWN) && !defined(_WIN32)
|
||||
# define UV__EHOSTDOWN (-EHOSTDOWN)
|
||||
#elif defined(__APPLE__) || \
|
||||
defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel__) || \
|
||||
defined(__NetBSD__) || \
|
||||
defined(__OpenBSD__)
|
||||
# define UV__EHOSTDOWN (-64)
|
||||
#else
|
||||
# define UV__EHOSTDOWN (-4031)
|
||||
#endif
|
||||
|
||||
#if defined(EREMOTEIO) && !defined(_WIN32)
|
||||
# define UV__EREMOTEIO (-EREMOTEIO)
|
||||
#else
|
||||
# define UV__EREMOTEIO (-4030)
|
||||
#endif
|
||||
|
||||
|
||||
#define UV_ERRNO_MAP(XX) \
|
||||
XX(E2BIG, "argument list too long") \
|
||||
XX(EACCES, "permission denied") \
|
||||
XX(EADDRINUSE, "address already in use") \
|
||||
XX(EADDRNOTAVAIL, "address not available") \
|
||||
XX(EAFNOSUPPORT, "address family not supported") \
|
||||
XX(EAGAIN, "resource temporarily unavailable") \
|
||||
XX(EAI_ADDRFAMILY, "address family not supported") \
|
||||
XX(EAI_AGAIN, "temporary failure") \
|
||||
XX(EAI_BADFLAGS, "bad ai_flags value") \
|
||||
XX(EAI_BADHINTS, "invalid value for hints") \
|
||||
XX(EAI_CANCELED, "request canceled") \
|
||||
XX(EAI_FAIL, "permanent failure") \
|
||||
XX(EAI_FAMILY, "ai_family not supported") \
|
||||
XX(EAI_MEMORY, "out of memory") \
|
||||
XX(EAI_NODATA, "no address") \
|
||||
XX(EAI_NONAME, "unknown node or service") \
|
||||
XX(EAI_OVERFLOW, "argument buffer overflow") \
|
||||
XX(EAI_PROTOCOL, "resolved protocol is unknown") \
|
||||
XX(EAI_SERVICE, "service not available for socket type") \
|
||||
XX(EAI_SOCKTYPE, "socket type not supported") \
|
||||
XX(EALREADY, "connection already in progress") \
|
||||
XX(EBADF, "bad file descriptor") \
|
||||
XX(EBUSY, "resource busy or locked") \
|
||||
XX(ECANCELED, "operation canceled") \
|
||||
XX(ECHARSET, "invalid Unicode character") \
|
||||
XX(ECONNABORTED, "software caused connection abort") \
|
||||
XX(ECONNREFUSED, "connection refused") \
|
||||
XX(ECONNRESET, "connection reset by peer") \
|
||||
XX(EDESTADDRREQ, "destination address required") \
|
||||
XX(EEXIST, "file already exists") \
|
||||
XX(EFAULT, "bad address in system call argument") \
|
||||
XX(EFBIG, "file too large") \
|
||||
XX(EHOSTUNREACH, "host is unreachable") \
|
||||
XX(EINTR, "interrupted system call") \
|
||||
XX(EINVAL, "invalid argument") \
|
||||
XX(EIO, "i/o error") \
|
||||
XX(EISCONN, "socket is already connected") \
|
||||
XX(EISDIR, "illegal operation on a directory") \
|
||||
XX(ELOOP, "too many symbolic links encountered") \
|
||||
XX(EMFILE, "too many open files") \
|
||||
XX(EMSGSIZE, "message too long") \
|
||||
XX(ENAMETOOLONG, "name too long") \
|
||||
XX(ENETDOWN, "network is down") \
|
||||
XX(ENETUNREACH, "network is unreachable") \
|
||||
XX(ENFILE, "file table overflow") \
|
||||
XX(ENOBUFS, "no buffer space available") \
|
||||
XX(ENODEV, "no such device") \
|
||||
XX(ENOENT, "no such file or directory") \
|
||||
XX(ENOMEM, "not enough memory") \
|
||||
XX(ENONET, "machine is not on the network") \
|
||||
XX(ENOPROTOOPT, "protocol not available") \
|
||||
XX(ENOSPC, "no space left on device") \
|
||||
XX(ENOSYS, "function not implemented") \
|
||||
XX(ENOTCONN, "socket is not connected") \
|
||||
XX(ENOTDIR, "not a directory") \
|
||||
XX(ENOTEMPTY, "directory not empty") \
|
||||
XX(ENOTSOCK, "socket operation on non-socket") \
|
||||
XX(ENOTSUP, "operation not supported on socket") \
|
||||
XX(EPERM, "operation not permitted") \
|
||||
XX(EPIPE, "broken pipe") \
|
||||
XX(EPROTO, "protocol error") \
|
||||
XX(EPROTONOSUPPORT, "protocol not supported") \
|
||||
XX(EPROTOTYPE, "protocol wrong type for socket") \
|
||||
XX(ERANGE, "result too large") \
|
||||
XX(EROFS, "read-only file system") \
|
||||
XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \
|
||||
XX(ESPIPE, "invalid seek") \
|
||||
XX(ESRCH, "no such process") \
|
||||
XX(ETIMEDOUT, "connection timed out") \
|
||||
XX(ETXTBSY, "text file is busy") \
|
||||
XX(EXDEV, "cross-device link not permitted") \
|
||||
XX(UNKNOWN, "unknown error") \
|
||||
XX(EOF, "end of file") \
|
||||
XX(ENXIO, "no such device or address") \
|
||||
XX(EMLINK, "too many links") \
|
||||
XX(EHOSTDOWN, "host is down") \
|
||||
XX(EREMOTEIO, "remote I/O error") \
|
||||
|
||||
typedef enum {
|
||||
#define XX(code, _) UV_ ## code = UV__ ## code,
|
||||
UV_ERRNO_MAP(XX)
|
||||
#undef XX
|
||||
UV_ERRNO_MAX = UV__EOF - 1
|
||||
} uv_errno_t;
|
||||
|
||||
|
||||
const char* uv_err_name(int err);
|
||||
const char* uv_strerror(int err);
|
||||
|
||||
int uv_translate_posix_error(int err);
|
||||
int get_uv_error(bool netErr = false);
|
||||
const char* get_uv_errmsg(bool netErr = false);
|
||||
|
||||
|
||||
|
||||
#endif /* UV_ERRNO_H_ */
|
||||
Reference in New Issue
Block a user