init
This commit is contained in:
BIN
sdk/system/.DS_Store
vendored
Normal file
BIN
sdk/system/.DS_Store
vendored
Normal file
Binary file not shown.
62
sdk/system/CustomSocket.cpp
Normal file
62
sdk/system/CustomSocket.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "SocketConfig.h"
|
||||
|
||||
using namespace wylib::inet::socket;
|
||||
|
||||
CCustomSocket::CCustomSocket()
|
||||
{
|
||||
m_nSocket = INVALID_SOCKET;
|
||||
m_LocalAddr.sin_family = AF_INET;
|
||||
m_LocalAddr.sin_addr.s_addr = 0;
|
||||
m_LocalAddr.sin_port = 0;
|
||||
m_RemoteAddr = m_LocalAddr;
|
||||
m_boBlock = true;
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
}
|
||||
|
||||
CCustomSocket::~CCustomSocket()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
VOID CCustomSocket::OnConnected()
|
||||
{
|
||||
}
|
||||
|
||||
VOID CCustomSocket::OnDisconnected()
|
||||
{
|
||||
}
|
||||
|
||||
VOID CCustomSocket::OnError(INT errorCode)
|
||||
{
|
||||
}
|
||||
|
||||
VOID CCustomSocket::Connected()
|
||||
{
|
||||
OnConnected();
|
||||
}
|
||||
|
||||
VOID CCustomSocket::Disconnected()
|
||||
{
|
||||
OnDisconnected();
|
||||
}
|
||||
|
||||
VOID CCustomSocket::SocketError(INT errorCode)
|
||||
{
|
||||
OnError(errorCode);
|
||||
close();
|
||||
}
|
||||
|
||||
VOID CCustomSocket::setSocket(const SOCKET socket)
|
||||
{
|
||||
m_nSocket = socket;
|
||||
|
||||
//设置了套接字后变更为制定的阻塞模式
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boBlock = !m_boBlock;
|
||||
setBlockMode( !m_boBlock );
|
||||
}
|
||||
else m_boConnected = false;
|
||||
}
|
||||
112
sdk/system/CustomSocket.h
Normal file
112
sdk/system/CustomSocket.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef _CUSTOM_SOCKET_H_
|
||||
#define _CUSTOM_SOCKET_H_
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* wyLib库 2008 - 2010
|
||||
*
|
||||
* $ 通用套接字处理类 $
|
||||
*
|
||||
* - 主要功能 -
|
||||
*
|
||||
* 基本的套接字封装类,支持阻塞和非阻塞模式。
|
||||
*
|
||||
*****************************************************************/
|
||||
#include "_osdef.h"
|
||||
#include "SocketConfig.h"
|
||||
|
||||
namespace wylib
|
||||
{
|
||||
namespace inet
|
||||
{
|
||||
namespace socket
|
||||
{
|
||||
/* 基本TCP套接字类
|
||||
|
||||
*/
|
||||
class CCustomSocket
|
||||
{
|
||||
protected:
|
||||
SOCKET m_nSocket; //套接字
|
||||
SOCKADDR_IN m_LocalAddr; //绑定的本地地址
|
||||
SOCKADDR_IN m_RemoteAddr; //远程地址
|
||||
bool m_boBlock; //是否非阻塞模式
|
||||
bool m_boConnected; //是否已建立连接
|
||||
bool m_boConnecting; //是否正在连接
|
||||
protected:
|
||||
//提供向最外层逻辑通知连接建立的事件
|
||||
virtual VOID OnConnected();
|
||||
//提供向最外层逻辑通知连接断开的事件
|
||||
virtual VOID OnDisconnected();
|
||||
//提供向最外层逻辑通知连接发生错误的事件
|
||||
virtual VOID OnError(int errorCode);
|
||||
protected:
|
||||
//继承类通过重载此函数处理建立连接需要进行的操作
|
||||
virtual VOID Connected();
|
||||
//继承类通过重载此函数处理断开连接需要进行的操作
|
||||
virtual VOID Disconnected();
|
||||
//继承类通过重载此函数处理连接发生了错误的所需要进行的操作
|
||||
virtual VOID SocketError(int nErrorCode);
|
||||
public:
|
||||
CCustomSocket();
|
||||
virtual ~CCustomSocket();
|
||||
|
||||
//获得SOCKET
|
||||
inline SOCKET getSocket(){ return m_nSocket; }
|
||||
//设置SOCKET
|
||||
VOID setSocket(const SOCKET socket);
|
||||
//获取是阻塞模式。true表示阻塞,false表示非阻塞
|
||||
inline bool getBlockMode(){ return m_boBlock; }
|
||||
//设置阻塞模式。true表示阻塞,false表示非阻塞,返回值为socket错误号,0表示成功
|
||||
INT setBlockMode(const bool block);
|
||||
//判断SOCKET是否处于连接状态
|
||||
inline bool connected(){ return m_boConnected; }
|
||||
//判断SOCKET是否处于正在连接状态
|
||||
inline bool connecting(){ return m_boConnecting; }
|
||||
//断开连接并关闭套接字
|
||||
VOID close();
|
||||
//断开连接,sd表示断开的方式,分别有SD_RECEIVE、SD_SEND和SD_BOTH
|
||||
INT shutDown(const INT sd);
|
||||
//绑定指定32位的IP地址和字符串绑定到制定的地址和端口,返回值为socket错误号,0表示成功
|
||||
INT bind(const ULONG addr, const INT port);
|
||||
//通过指定IP地址字符串和端口绑定到指定的地址和端口,返回值为socket错误号,0表示成功
|
||||
INT bind(const char * addr, const INT port);
|
||||
//获取绑定的本地地址和端口的sockaddr_in结构
|
||||
inline VOID getLoaclAddr(PSOCKADDR_IN addr_in){ *addr_in = m_LocalAddr; }
|
||||
//获取远程的地址和端口的sockaddr_in结构
|
||||
inline VOID getRemoteAddr(PSOCKADDR_IN addr_in){ *addr_in = m_RemoteAddr; }
|
||||
//设置远程地址信息
|
||||
inline VOID setRemoteAddr(const PSOCKADDR_IN addr_in){ m_RemoteAddr = *addr_in; }
|
||||
//获取接收缓冲区大小,返回值为socket错误号,0表示成功。
|
||||
INT getRecvBufSize(ULONG *size);
|
||||
//设置接收缓冲区大小,返回值为socket错误号,0表示成功。
|
||||
INT setRecvBufSize(ULONG size);
|
||||
//获取发送缓冲区大小,返回值为socket错误号,0表示成功。
|
||||
INT getSendBufSize(ULONG *size);
|
||||
//设置发送缓冲区大小,返回值为socket错误号,0表示成功。
|
||||
INT setSendBufSize(ULONG size);
|
||||
//开始监听,backlog表示每次可接受的连接数量,返回值为socket错误号,0表示成功
|
||||
INT listen(const INT backlog = 5);
|
||||
//通过32位IP地址连接到制定的端口,返回值为socket错误号,0表示成功。对于非阻塞模式返回0并不表示已经建立连接
|
||||
INT connect(const ULONG addr, const INT port);
|
||||
//通过IP地址字符串连接到指定的端口,返回值为socket错误号,0表示成功。对于非阻塞模式返回0并不表示已经建立连接
|
||||
INT connect(const char * addr, const INT port);
|
||||
|
||||
INT connect(const char * addr, const INT port, int timeout);
|
||||
INT connect(const ULONG addr, const INT port, int timeout);
|
||||
|
||||
//接收新的连接,wait_msec表示最大等待毫秒数,函数返回0表示成功且socket被接收的套接字填充,返回SOCKET_ERROR-1表示等待超时,否则函数返回socket错误号
|
||||
INT accept(SOCKET * socket, unsigned long wait_msec, PSOCKADDR_IN addr);
|
||||
//创建套接字,返回值为socket错误号,0表示成功且socket的内容被填充为新建立的socket
|
||||
INT createSocket(OUT SOCKET *socket, const INT af = AF_INET, const int type = SOCK_STREAM, const int protocol = IPPROTO_TCP);
|
||||
//读取套接字内容。返回0表示连接已断开,返回SOCKET_ERROR表示发生错误,返回SOCKET_ERROR-1表示没有数据可读(仅对于非阻塞模式套接字),否则表示实际接收的字节数
|
||||
virtual INT recv(LPVOID buf, INT len, const INT flags = 0);
|
||||
//向套接字写入内容,返回0表示连接已断开,返回SOCKET_ERROR表示发生错误,返回SOCKET_ERROR-1表示send操作会发生阻塞且没有数据被发送(仅对于非阻塞模式套接字),否则返回发送的字节数。
|
||||
virtual INT send(LPVOID buf, INT len, const INT flags = 0);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
417
sdk/system/CustomSocketLinux.cpp
Normal file
417
sdk/system/CustomSocketLinux.cpp
Normal file
@@ -0,0 +1,417 @@
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
#include "SocketConfig.h"
|
||||
|
||||
#ifdef CONFIG_USE_LINUX_SOCKET
|
||||
|
||||
using namespace wylib::inet::socket;
|
||||
|
||||
INT CCustomSocket::setBlockMode(const bool block)
|
||||
{
|
||||
u_long ulock;
|
||||
|
||||
if ( block == m_boBlock )
|
||||
return 0;
|
||||
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
ulock = block ? 0 : 1;
|
||||
if ( ioctl( m_nSocket, FIONBIO, &ulock ) )
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
m_boBlock = block;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID CCustomSocket::close()
|
||||
{
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
if ( m_boConnected )
|
||||
{
|
||||
Disconnected();
|
||||
}
|
||||
shutdown(m_nSocket, SHUT_RDWR);
|
||||
::close(m_nSocket);
|
||||
m_nSocket = INVALID_SOCKET;
|
||||
}
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
m_boBlock = true;
|
||||
}
|
||||
|
||||
INT CCustomSocket::shutDown(const INT sd)
|
||||
{
|
||||
int nErr = 0;
|
||||
|
||||
if ( m_boConnected && m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
nErr = shutdown( m_nSocket, sd );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
Disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::bind(const ULONG addr, const INT port)
|
||||
{
|
||||
INT nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
//addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
addrin.sin_port = htons((u_short)port);
|
||||
|
||||
int tmp =1;
|
||||
setsockopt(m_nSocket,SOL_SOCKET,SO_REUSEADDR,&tmp, sizeof(tmp));
|
||||
|
||||
nErr = ::bind( m_nSocket, (const sockaddr*)&addrin, sizeof(addrin) );
|
||||
//if ( nErr == 0 )
|
||||
{
|
||||
m_LocalAddr = addrin;
|
||||
}
|
||||
|
||||
//return nErr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::bind(const char * addr, const INT port)
|
||||
{
|
||||
INT nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = inet_addr(addr);
|
||||
addrin.sin_port = htons((u_short)port);
|
||||
int tmp=1;
|
||||
setsockopt(m_nSocket,SOL_SOCKET,SO_REUSEADDR,&tmp, sizeof(tmp));
|
||||
nErr = ::bind( m_nSocket, (const sockaddr*)&addrin, sizeof(addrin) );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_LocalAddr = addrin;
|
||||
}
|
||||
|
||||
return nErr;
|
||||
/*
|
||||
struct hostent *phost;
|
||||
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = *(u_long*)phost->h_addr_list[0];
|
||||
return bind( addr.s_addr, port );
|
||||
}
|
||||
return errno;
|
||||
*/
|
||||
}
|
||||
|
||||
INT CCustomSocket::getRecvBufSize(ULONG *size)
|
||||
{
|
||||
unsigned int oplen = sizeof(*size);
|
||||
return getsockopt( m_nSocket, SOL_SOCKET, SO_RCVBUF, (char*)size, &oplen );
|
||||
}
|
||||
|
||||
INT CCustomSocket::setRecvBufSize(ULONG size)
|
||||
{
|
||||
return setsockopt(m_nSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&size, sizeof(size));
|
||||
}
|
||||
|
||||
INT CCustomSocket::getSendBufSize(ULONG *size)
|
||||
{
|
||||
unsigned int oplen = sizeof(*size);
|
||||
return getsockopt( m_nSocket, SOL_SOCKET, SO_SNDBUF, (char*)size, &oplen );
|
||||
}
|
||||
|
||||
INT CCustomSocket::setSendBufSize(ULONG size)
|
||||
{
|
||||
return setsockopt( m_nSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&size, sizeof(size) );
|
||||
}
|
||||
|
||||
INT CCustomSocket::listen(const INT backlog)
|
||||
{
|
||||
return ::listen( m_nSocket, backlog );
|
||||
}
|
||||
|
||||
int CCustomSocket::connect(const char * addr, const INT port)
|
||||
{
|
||||
struct hostent *phost = NULL;
|
||||
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr_;
|
||||
addr_.s_addr = inet_addr(addr);//*(u_long*)(phost->h_addr_list[0]);
|
||||
return connect( addr_.s_addr, port );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CCustomSocket::accept(SOCKET *socket, unsigned long wait_msec, PSOCKADDR_IN addr)
|
||||
{
|
||||
int nErr;
|
||||
fd_set set;
|
||||
timeval tv;
|
||||
unsigned int addrsize;
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET( m_nSocket, &set );
|
||||
|
||||
tv.tv_sec = long(wait_msec / 1000);
|
||||
tv.tv_usec = long( (wait_msec %1000)* 1000);
|
||||
|
||||
nErr = select( int(m_nSocket + 1), &set, NULL, NULL, &tv );
|
||||
if ( nErr < 0 )
|
||||
return nErr;
|
||||
if ( nErr > 0 )
|
||||
{
|
||||
addrsize = sizeof(*addr);
|
||||
*socket = ::accept( m_nSocket, (sockaddr*)addr, &addrsize );
|
||||
if ( *socket == INVALID_SOCKET )
|
||||
{
|
||||
return nErr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SOCKET_ERROR - 1;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const ULONG addr, const INT port)
|
||||
{
|
||||
int nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_port = htons(port);
|
||||
|
||||
nErr = ::connect( m_nSocket, (sockaddr*)&addrin, sizeof(addrin) );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
}
|
||||
else
|
||||
{
|
||||
nErr = errno;
|
||||
if ( nErr == ENOBUFS)
|
||||
{
|
||||
nErr = 0;
|
||||
m_boConnected = false;
|
||||
m_boConnecting = true;
|
||||
}
|
||||
}
|
||||
|
||||
return nErr;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const char * addr, const INT port, int timeout)
|
||||
{
|
||||
struct hostent *phost;
|
||||
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = *(u_long*)phost->h_addr_list[0];
|
||||
return connect( addr.s_addr, port, timeout);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const ULONG addr, const INT port, int timeout)
|
||||
{
|
||||
int nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
memset(&addrin, 0, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_port = htons(port);
|
||||
|
||||
// 超时需要在非阻塞下
|
||||
unsigned long mode = 1;
|
||||
ioctl(m_nSocket, FIONBIO, &mode);
|
||||
nErr = 0;
|
||||
if ( ::connect( m_nSocket, (sockaddr*)&addrin, sizeof(addrin) ) == 0 )
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 设置回阻塞
|
||||
mode = 0;
|
||||
ioctl(m_nSocket, FIONBIO, &mode);
|
||||
|
||||
// 使用select超时connet
|
||||
struct timeval tm={timeout,0};
|
||||
fd_set wset;
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(m_nSocket, &wset);
|
||||
if( ::select(m_nSocket+1, NULL, &wset, NULL, &tm) > 0)
|
||||
{
|
||||
int error=-1, len=sizeof(int);
|
||||
getsockopt(m_nSocket, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
|
||||
if(error == 0)
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行到这里说明连接不成功
|
||||
nErr = errno;
|
||||
if ( nErr == ENOBUFS)
|
||||
{
|
||||
nErr = 0;
|
||||
m_boConnected = false;
|
||||
m_boConnecting = true;
|
||||
}
|
||||
}
|
||||
return nErr;
|
||||
}
|
||||
|
||||
int CCustomSocket::createSocket(SOCKET *socket, const INT af, const int type, const int protocol)
|
||||
{
|
||||
*socket = ::socket( af, type, protocol );
|
||||
if ( *socket == INVALID_SOCKET )
|
||||
{
|
||||
return *socket;
|
||||
}
|
||||
m_nSocket = *socket ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 原来的recv的实现
|
||||
int nErr = ::recv( m_nSocket, (char*)buf, len, flags );
|
||||
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
close();
|
||||
}
|
||||
else if ( nErr < 0 )
|
||||
{
|
||||
if ( !m_boBlock )
|
||||
{
|
||||
nErr = errno;
|
||||
if ( nErr != ENOBUFS )
|
||||
{
|
||||
SocketError( nErr );
|
||||
nErr = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nErr = SOCKET_ERROR - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nErr;
|
||||
*/
|
||||
|
||||
int CCustomSocket::recv(LPVOID buf, INT size, const INT flags)
|
||||
{
|
||||
if ( !buf || size < 1) return 0;
|
||||
|
||||
int r = 0 ;
|
||||
r = ::recv(m_nSocket, buf, size, flags);
|
||||
if( r == 0 )
|
||||
{
|
||||
// 关闭连接
|
||||
close();
|
||||
return 0 ;
|
||||
}
|
||||
else if( r < 0 )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
INT CCustomSocket::send(LPVOID buf, INT len, const INT flags)
|
||||
{
|
||||
int nRet, nErr;
|
||||
char *ptr = (char*)buf;
|
||||
|
||||
nRet = 0;
|
||||
while ( len > 0 )
|
||||
{
|
||||
nErr = ::send( m_nSocket, (char*)ptr, len, flags );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
nRet = 0;
|
||||
close();
|
||||
break;
|
||||
}
|
||||
else if ( nErr < 0 )
|
||||
{
|
||||
if ( !m_boBlock )
|
||||
{
|
||||
if ( errno == EINTR ) // 因为发生中断,中断处理后可以继续发送,所以此处应选择暂时退出函数, 然后再继续调用send进行接收数据
|
||||
{
|
||||
continue ;
|
||||
}
|
||||
else if(errno == EAGAIN)
|
||||
{
|
||||
Sleep(10);
|
||||
continue ;
|
||||
}
|
||||
|
||||
}
|
||||
nRet = nErr;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRet += nErr;
|
||||
ptr += nErr;
|
||||
len -= nErr;
|
||||
}
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
#endif
|
||||
293
sdk/system/CustomSocketWin.cpp
Normal file
293
sdk/system/CustomSocketWin.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
#include "SocketConfig.h"
|
||||
|
||||
#ifdef CONFIG_USE_WIN_SOCKET
|
||||
|
||||
using namespace wylib::inet::socket;
|
||||
|
||||
int CCustomSocket::setBlockMode(const bool block)
|
||||
{
|
||||
u_long ulock;
|
||||
|
||||
if ( block == m_boBlock )
|
||||
return 0;
|
||||
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
ulock = block ? 0 : 1;
|
||||
if ( ioctlsocket( m_nSocket, FIONBIO, &ulock ) )
|
||||
{
|
||||
return WSAGetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
m_boBlock = block;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID CCustomSocket::close()
|
||||
{
|
||||
if ( m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
if ( m_boConnected )
|
||||
{
|
||||
Disconnected();
|
||||
}
|
||||
closesocket( m_nSocket );
|
||||
m_nSocket = INVALID_SOCKET;
|
||||
}
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
m_boBlock = true;
|
||||
}
|
||||
|
||||
INT CCustomSocket::shutDown(const INT sd)
|
||||
{
|
||||
INT nErr = 0;
|
||||
|
||||
if ( m_boConnected && m_nSocket != INVALID_SOCKET )
|
||||
{
|
||||
nErr = shutdown( m_nSocket, sd );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_boConnected = false;
|
||||
m_boConnecting = false;
|
||||
Disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::bind(const ULONG addr, const INT port)
|
||||
{
|
||||
INT nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
ZeroMemory(&addrin, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_port = htons(port);
|
||||
|
||||
nErr = ::bind( m_nSocket, (sockaddr*)&addrin, sizeof(addrin) );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_LocalAddr = addrin;
|
||||
}
|
||||
|
||||
return nErr ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::bind(const char * addr, const INT port)
|
||||
{
|
||||
hostent *phost;
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = *(u_long*)phost->h_addr_list[0];
|
||||
return bind( addr.s_addr, port );
|
||||
}
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
INT CCustomSocket::getRecvBufSize(ULONG *size)
|
||||
{
|
||||
int oplen = sizeof(*size);
|
||||
int nErr = getsockopt( m_nSocket, SOL_SOCKET, SO_RCVBUF, (char*)size, &oplen );
|
||||
return nErr ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::setRecvBufSize(ULONG size)
|
||||
{
|
||||
int nErr = setsockopt( m_nSocket, SOL_SOCKET, SO_RCVBUF, (char*)&size, sizeof(size) );
|
||||
return nErr ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::getSendBufSize(ULONG *size)
|
||||
{
|
||||
int oplen = sizeof(*size);
|
||||
int nErr = getsockopt( m_nSocket, SOL_SOCKET, SO_SNDBUF, (char*)size, &oplen );
|
||||
return nErr ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::setSendBufSize(ULONG size)
|
||||
{
|
||||
int nErr = setsockopt( m_nSocket, SOL_SOCKET, SO_SNDBUF, (char*)&size, sizeof(size) );
|
||||
return nErr ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::listen(const INT backlog)
|
||||
{
|
||||
int nErr;
|
||||
nErr = ::listen( m_nSocket, backlog );
|
||||
|
||||
return nErr ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
int CCustomSocket::connect(const char * addr, const INT port)
|
||||
{
|
||||
hostent *phost;
|
||||
#ifdef UNICODE
|
||||
wylib::string::CWideString ws(addr);
|
||||
wylib::string::CAnsiString *as = ws.toAStr();
|
||||
phost = gethostbyname(*as);
|
||||
delete as;
|
||||
#else
|
||||
phost = gethostbyname(addr);
|
||||
#endif
|
||||
if ( phost )
|
||||
{
|
||||
in_addr addr;
|
||||
addr.s_addr = *(u_long*)phost->h_addr_list[0];
|
||||
return connect( addr.s_addr, port );
|
||||
}
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
INT CCustomSocket::accept(SOCKET *socket, unsigned long wait_msec, PSOCKADDR_IN addr)
|
||||
{
|
||||
int nErr;
|
||||
fd_set set;
|
||||
timeval tv;
|
||||
int addrsize;
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET( m_nSocket, &set );
|
||||
|
||||
tv.tv_sec = long(wait_msec / 1000);
|
||||
tv.tv_usec = long(wait_msec * 1000);
|
||||
|
||||
nErr = select( int(m_nSocket + 1), &set, NULL, NULL, &tv );
|
||||
if ( nErr < 0 )
|
||||
return WSAGetLastError();
|
||||
if ( nErr > 0 )
|
||||
{
|
||||
addrsize = sizeof(*addr);
|
||||
*socket = ::accept( m_nSocket, (sockaddr*)addr, &addrsize );
|
||||
if ( *socket == INVALID_SOCKET )
|
||||
{
|
||||
return WSAGetLastError();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SOCKET_ERROR - 1;
|
||||
}
|
||||
|
||||
INT CCustomSocket::connect(const ULONG addr, const INT port)
|
||||
{
|
||||
int nErr;
|
||||
SOCKADDR_IN addrin;
|
||||
|
||||
ZeroMemory(&addrin, sizeof(addrin));
|
||||
addrin.sin_family = AF_INET;
|
||||
addrin.sin_addr.s_addr = addr;
|
||||
addrin.sin_port = htons(port);
|
||||
|
||||
nErr = ::connect( m_nSocket, (sockaddr*)&addrin, sizeof(addrin) );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
m_boConnected = true;
|
||||
m_boConnecting = false;
|
||||
Connected();
|
||||
}
|
||||
else
|
||||
{
|
||||
nErr = WSAGetLastError();
|
||||
if ( nErr == WSAEWOULDBLOCK )
|
||||
{
|
||||
nErr = 0;
|
||||
m_boConnected = false;
|
||||
m_boConnecting = true;
|
||||
}
|
||||
}
|
||||
|
||||
return nErr;
|
||||
}
|
||||
|
||||
INT CCustomSocket::createSocket(SOCKET *socket, const INT af, const int type, const int protocol)
|
||||
{
|
||||
*socket = ::socket( af, type, protocol );
|
||||
if ( *socket == INVALID_SOCKET )
|
||||
{
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT CCustomSocket::recv(LPVOID buf, INT len, const INT flags)
|
||||
{
|
||||
int nErr = ::recv( m_nSocket, (char*)buf, len, flags );
|
||||
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
close();
|
||||
}
|
||||
else if ( nErr < 0 )
|
||||
{
|
||||
if ( !m_boBlock )
|
||||
{
|
||||
nErr = WSAGetLastError();
|
||||
if ( nErr != WSAEWOULDBLOCK )
|
||||
{
|
||||
SocketError( nErr );
|
||||
nErr = -1;
|
||||
}
|
||||
else nErr = SOCKET_ERROR - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return nErr;
|
||||
}
|
||||
|
||||
INT CCustomSocket::send(LPVOID buf, INT len, const INT flags)
|
||||
{
|
||||
int nRet, nErr;
|
||||
char *ptr = (char*)buf;
|
||||
|
||||
nRet = 0;
|
||||
while ( len > 0 )
|
||||
{
|
||||
nErr = ::send( m_nSocket, (char*)ptr, len, flags );
|
||||
if ( nErr == 0 )
|
||||
{
|
||||
nRet = 0;
|
||||
close();
|
||||
break;
|
||||
}
|
||||
else if ( nErr < 0 )
|
||||
{
|
||||
if ( !m_boBlock )
|
||||
{
|
||||
nErr = WSAGetLastError();
|
||||
if ( nErr != WSAEWOULDBLOCK )
|
||||
{
|
||||
nRet = SOCKET_ERROR;
|
||||
SocketError( WSAGetLastError() );
|
||||
}
|
||||
else if ( nRet == 0 )
|
||||
{
|
||||
nRet = SOCKET_ERROR - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRet += nErr;
|
||||
ptr += nErr;
|
||||
len -= nErr;
|
||||
}
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
#endif
|
||||
353
sdk/system/LinuxPortable.h
Normal file
353
sdk/system/LinuxPortable.h
Normal file
@@ -0,0 +1,353 @@
|
||||
|
||||
|
||||
#ifndef _SYSTEM_LINUXPORTABLE_H
|
||||
#define _SYSTEM_LINUXPORTABLE_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
// 日期和时间
|
||||
struct port_date_time_t
|
||||
{
|
||||
int nYear;
|
||||
int nMonth;
|
||||
int nDay;
|
||||
int nHour;
|
||||
int nMinute;
|
||||
int nSecond;
|
||||
int nMilliseconds;
|
||||
int nDayOfWeek;
|
||||
};
|
||||
|
||||
// 内存使用情况
|
||||
struct port_memory_info_t
|
||||
{
|
||||
double dMemoryLoad;
|
||||
double dTotalMemory;
|
||||
double dAvailMemory;
|
||||
};
|
||||
|
||||
// 唯一标识符
|
||||
struct port_uuid_t
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
};
|
||||
|
||||
// 获得本地当前时间
|
||||
inline bool Port_GetLocalTime(port_date_time_t* dt)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
tm* pt = localtime(&tv.tv_sec);
|
||||
|
||||
dt->nYear = pt->tm_year + 1900;
|
||||
dt->nMonth = pt->tm_mon + 1;
|
||||
dt->nDay = pt->tm_mday;
|
||||
dt->nHour = pt->tm_hour;
|
||||
dt->nMinute = pt->tm_min;
|
||||
dt->nSecond = pt->tm_sec;
|
||||
dt->nMilliseconds = tv.tv_usec / 1000;
|
||||
dt->nDayOfWeek = pt->tm_wday;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获得系统计时
|
||||
// inline long long Port_GetTickCount()
|
||||
// {
|
||||
// time_t t = time(NULL);
|
||||
// struct tm tm;
|
||||
// localtime_r(&t,&tm);
|
||||
|
||||
// unsigned int timetotle = mktime(&tm);
|
||||
|
||||
|
||||
// struct timeval tv;
|
||||
|
||||
// gettimeofday(&tv, NULL);
|
||||
|
||||
// long long nDailyTime = (long long)timetotle*1000 + tv.tv_usec / 1000;
|
||||
// return nDailyTime;
|
||||
// }
|
||||
|
||||
// 获得系统计时
|
||||
inline unsigned int Port_GetTickCountOld()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
// 获得当前高精度时刻
|
||||
inline double Port_GetPerformanceTime()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return (double)tv.tv_sec + (double)tv.tv_usec * 0.000001;
|
||||
}
|
||||
|
||||
// 系统休眠
|
||||
inline void Port_Sleep(unsigned int ms)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = ms * 1000000;
|
||||
|
||||
nanosleep(&ts, NULL);
|
||||
//usleep(ms * 1000);
|
||||
}
|
||||
|
||||
// 是否非法的浮点数
|
||||
inline int Port_IsNaN(float value)
|
||||
{
|
||||
return isnan(value);
|
||||
}
|
||||
|
||||
// 创建唯一标识符
|
||||
inline const char* Port_CreateGuid(char* buffer, size_t size)
|
||||
{
|
||||
port_uuid_t id;
|
||||
|
||||
uuid_generate((unsigned char*)&id);
|
||||
|
||||
snprintf(buffer, size - 1,
|
||||
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
id.Data1, id.Data2, id.Data3,
|
||||
id.Data4[0], id.Data4[1], id.Data4[2], id.Data4[3],
|
||||
id.Data4[4], id.Data4[5], id.Data4[6], id.Data4[7]);
|
||||
|
||||
buffer[size - 1] = 0;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// 弹出信息窗口
|
||||
inline void Port_PopupMsgBox(const char* info, const char* title)
|
||||
{
|
||||
printf("(msg)%s:%s\n", title, info);
|
||||
}
|
||||
|
||||
// 弹出错误信息窗口
|
||||
inline void Port_PopupErrorMsgBox(const char* info, const char* title)
|
||||
{
|
||||
printf("(err)%s:%s\n", title, info);
|
||||
}
|
||||
|
||||
// 获得当前的进程ID
|
||||
inline unsigned int Port_GetCurrentProcessId()
|
||||
{
|
||||
return getpid();
|
||||
}
|
||||
|
||||
// 获得当前执行文件的路径
|
||||
inline bool Port_GetCurrentModuleFileName(char* buffer, size_t size)
|
||||
{
|
||||
ssize_t res = readlink("/proc/self/exe", buffer, size);
|
||||
|
||||
if ((res < 0) || (res >= size))
|
||||
{
|
||||
buffer[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer[res] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 终止进程
|
||||
inline bool Port_KillProcess(unsigned int proc_id)
|
||||
{
|
||||
return kill(proc_id, SIGKILL);
|
||||
}
|
||||
|
||||
inline char* skip_token(char* fp)
|
||||
{
|
||||
char* ptr = fp;
|
||||
|
||||
while (*ptr && (*ptr != ' '))
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
while (*ptr == ' ')
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// 获得内存使用情况
|
||||
inline bool Port_GetMemoryInfo(port_memory_info_t* pInfo)
|
||||
{
|
||||
memset(pInfo, 0, sizeof(port_memory_info_t));
|
||||
|
||||
// get system wide memory usage
|
||||
char buffer[1024];
|
||||
char* p;
|
||||
|
||||
int fd = open("/proc/meminfo" , O_RDONLY);
|
||||
int len = read(fd, buffer, sizeof (buffer) - 1);
|
||||
|
||||
close(fd);
|
||||
|
||||
buffer[len] = '\0';
|
||||
|
||||
p = buffer;
|
||||
p = skip_token(p);
|
||||
|
||||
pInfo->dTotalMemory = strtoul(p, &p, 10); // total memory
|
||||
|
||||
p = strchr(p, '\n');
|
||||
p = skip_token(p);
|
||||
|
||||
pInfo->dAvailMemory = strtoul(p, &p, 10); // free memory
|
||||
pInfo->dMemoryLoad = (1.0 - pInfo->dAvailMemory / pInfo->dTotalMemory);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获得CPU使用率
|
||||
inline double Port_GetCpuRate()
|
||||
{
|
||||
char buffer[256];
|
||||
char* p;
|
||||
|
||||
int fd = open("/proc/loadavg", O_RDONLY);
|
||||
int len = read(fd, buffer, sizeof(buffer) - 1);
|
||||
|
||||
close(fd);
|
||||
|
||||
buffer[len] = '\0';
|
||||
|
||||
double load_avg0 = strtod(buffer, &p);
|
||||
double load_avg1 = strtod(p, &p);
|
||||
double load_avg2 = strtod(p, &p);
|
||||
|
||||
return load_avg1;
|
||||
}
|
||||
|
||||
// 初始化守护进程
|
||||
inline bool Port_InitDaemon()
|
||||
{
|
||||
int pid = fork();
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
// 是父进程,结束父进程
|
||||
exit(0);
|
||||
}
|
||||
else if (pid < 0)
|
||||
{
|
||||
// fork失败,退出
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// 是第一子进程,后台继续执行
|
||||
//第一子进程成为新的会话组长和进程组长
|
||||
setsid();
|
||||
|
||||
// 并与控制终端分离
|
||||
pid = fork();
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
// 是第一子进程,结束第一子进程
|
||||
exit(0);
|
||||
}
|
||||
else if (pid < 0)
|
||||
{
|
||||
// fork失败,退出
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// 是第二子进程,继续
|
||||
// 第二子进程不再是会话组长
|
||||
|
||||
//关闭打开的文件描述符
|
||||
for (int i = 0; i < NOFILE; ++i)
|
||||
{
|
||||
close(i);
|
||||
}
|
||||
|
||||
umask(0); //重设文件创建掩模
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 启动控制台程序
|
||||
inline bool Port_Execute(const char* cmd_line)
|
||||
{
|
||||
char cmd[256];
|
||||
size_t size = strlen(cmd_line) + 1;
|
||||
|
||||
if (size > sizeof(cmd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(cmd, cmd_line, size);
|
||||
|
||||
char* argv[16] = { NULL };
|
||||
char* envp[1] = { NULL };
|
||||
|
||||
int argc = 0;
|
||||
|
||||
argv[argc++] = cmd;
|
||||
|
||||
char* p = strchr(cmd, ' ');
|
||||
|
||||
while (p)
|
||||
{
|
||||
*p = 0;
|
||||
|
||||
while (*(++p) == ' ')
|
||||
{
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
argv[argc++] = p;
|
||||
|
||||
if (argc == (sizeof(argv) / sizeof(argv[0]) - 1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int pid = fork();
|
||||
|
||||
if (0 == pid)
|
||||
{
|
||||
// 子进程
|
||||
if (execve(cmd, argv, envp) == -1)
|
||||
{
|
||||
// 启动程序失败,关闭子进程
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
return pid > 0;
|
||||
}
|
||||
|
||||
#endif // _SYSTEM_LINUXPORTABLE_H
|
||||
158
sdk/system/LinuxTimer.h
Normal file
158
sdk/system/LinuxTimer.h
Normal file
@@ -0,0 +1,158 @@
|
||||
|
||||
#ifndef __SYSTEM_LINUXTIMER_H__
|
||||
#define __SYSTEM_LINUXTIMER_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
//主要是系统的一些API的集成
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _SYSTEMTIME
|
||||
{
|
||||
unsigned short wYear;
|
||||
unsigned short wMonth;
|
||||
unsigned short wDayOfWeek;
|
||||
unsigned short wDay;
|
||||
unsigned short wHour;
|
||||
unsigned short wMinute;
|
||||
unsigned short wSecond;
|
||||
unsigned short wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
void GetLocalTime(PSYSTEMTIME pTime)
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
struct tm timenow;
|
||||
localtime_r(&now,&timenow);
|
||||
pTime->wYear = (unsigned short)timenow.tm_year + 1900;
|
||||
pTime->wMonth = (unsigned short)timenow.tm_mon +1;
|
||||
|
||||
pTime->wDayOfWeek =(unsigned short) timenow.tm_wday;
|
||||
pTime->wDay =(unsigned short)timenow.tm_mday;
|
||||
pTime->wHour = (unsigned short)timenow.tm_hour;
|
||||
pTime->wMinute= (unsigned short)timenow.tm_min;
|
||||
pTime->wSecond=(unsigned short)timenow.tm_sec;
|
||||
pTime->wMilliseconds= 0;
|
||||
}
|
||||
|
||||
void GetLocalTimeFull(PSYSTEMTIME pTime)
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
struct tm timenow;
|
||||
localtime_r(&now,&timenow);
|
||||
pTime->wYear = (unsigned short)timenow.tm_year + 1900;
|
||||
pTime->wMonth = (unsigned short)timenow.tm_mon +1;
|
||||
|
||||
pTime->wDayOfWeek =(unsigned short) timenow.tm_wday;
|
||||
pTime->wDay =(unsigned short)timenow.tm_mday;
|
||||
pTime->wHour = (unsigned short)timenow.tm_hour;
|
||||
pTime->wMinute= (unsigned short)timenow.tm_min;
|
||||
pTime->wSecond=(unsigned short)timenow.tm_sec;
|
||||
pTime->wMilliseconds= (unsigned short)timenow.tm_sec;
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL); // NULL is only legal value
|
||||
pTime->wMilliseconds = tv.tv_usec / 1000; // Get Millisecond;
|
||||
}
|
||||
|
||||
// 高精度计时器
|
||||
class CGameTimer
|
||||
{
|
||||
public:
|
||||
CGameTimer()
|
||||
{
|
||||
m_bInit = false;
|
||||
m_dLastTime = 0.0;
|
||||
}
|
||||
|
||||
~CGameTimer()
|
||||
{
|
||||
}
|
||||
|
||||
// 初始化
|
||||
void Initialize()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
m_dLastTime = ToSeconds(&tv);
|
||||
m_bInit = true;
|
||||
}
|
||||
|
||||
// 高精度计时器是否可用
|
||||
bool CanUseQPF() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 是否使用高精度计时器
|
||||
void SetUseQPF(bool flag)
|
||||
{
|
||||
}
|
||||
|
||||
// 当前时间数值
|
||||
double GetCurrentTime()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return ToSeconds(&tv);
|
||||
}
|
||||
|
||||
// 获得逝去的秒数
|
||||
double GetElapseTime(double expect = 0.0)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
double now = ToSeconds(&tv);
|
||||
double elapse = now - m_dLastTime;
|
||||
|
||||
if (elapse >= expect)
|
||||
{
|
||||
m_dLastTime = now;
|
||||
}
|
||||
|
||||
return elapse;
|
||||
}
|
||||
|
||||
// 获得逝去的毫秒数
|
||||
int GetElapseMillisec(int expect = 0)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
double now = ToSeconds(&tv);
|
||||
double elapse = now - m_dLastTime;
|
||||
|
||||
if (elapse >= expect)
|
||||
{
|
||||
m_dLastTime = now;
|
||||
}
|
||||
|
||||
return (int)(elapse * 1000.0);
|
||||
}
|
||||
|
||||
private:
|
||||
double ToSeconds(struct timeval* tv)
|
||||
{
|
||||
return (double)tv->tv_sec + (double)tv->tv_usec * 0.000001;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_bInit;
|
||||
double m_dLastTime;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
163
sdk/system/Lock.cpp
Normal file
163
sdk/system/Lock.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "_osdef.h"
|
||||
#include "Lock.h"
|
||||
|
||||
using namespace wylib::sync::lock;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
CCSLock::CCSLock()
|
||||
{
|
||||
InitializeCriticalSection( &m_CriticalSection );
|
||||
m_pFileName =NULL;
|
||||
m_nLine =0;
|
||||
}
|
||||
|
||||
CCSLock::~CCSLock()
|
||||
{
|
||||
DeleteCriticalSection( &m_CriticalSection );
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#define recursive_mutex_flag PTHREAD_MUTEX_RECURSIVE_NP
|
||||
|
||||
//bool CCSLock::attr_initalized = false;
|
||||
//pthread_mutexattr_t CCSLock::attr;
|
||||
|
||||
CCSLock::CCSLock()
|
||||
{
|
||||
/*
|
||||
if(!attr_initalized)
|
||||
{
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, recursive_mutex_flag);
|
||||
attr_initalized = true;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&mutex, &attr);
|
||||
*/
|
||||
pthread_mutex_init(&mutex,NULL);
|
||||
|
||||
}
|
||||
|
||||
CCSLock::~CCSLock() { pthread_mutex_destroy(&mutex); }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void CCSLock::_Lock( char *sFile,int nLine)
|
||||
{
|
||||
#ifndef WIN32
|
||||
pthread_mutex_lock(&mutex);
|
||||
#else
|
||||
EnterCriticalSection(&m_CriticalSection);
|
||||
#endif
|
||||
m_pFileName =sFile;
|
||||
m_nLine= nLine;
|
||||
}
|
||||
|
||||
BOOL CCSLock::TryLock()
|
||||
{
|
||||
#ifndef WIN32
|
||||
return (pthread_mutex_trylock(&mutex) == 0);
|
||||
#else
|
||||
return TryEnterCriticalSection(&m_CriticalSection);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CCSLock::_Unlock( char *sFile,int nLine)
|
||||
{
|
||||
#ifndef WIN32
|
||||
pthread_mutex_unlock(&mutex);
|
||||
#else
|
||||
LeaveCriticalSection(&m_CriticalSection);
|
||||
#endif
|
||||
m_pFileName =0;
|
||||
m_nLine= 0;
|
||||
}
|
||||
|
||||
|
||||
//#ifdef WIN32
|
||||
CAtomLock::CAtomLock()
|
||||
{
|
||||
m_uLockFlag = Unlocked;
|
||||
m_dwLockThread = 0;
|
||||
m_dwLockCount = 0;
|
||||
}
|
||||
|
||||
CAtomLock::~CAtomLock()
|
||||
{
|
||||
}
|
||||
|
||||
void CAtomLock::_Lock( char *sFile,int nLine)
|
||||
{
|
||||
#ifdef WIN32
|
||||
DWORD dwThreadId = GetCurrentThreadId();
|
||||
#else
|
||||
DWORD dwThreadId = pthread_self();
|
||||
#endif
|
||||
|
||||
if ( dwThreadId == m_dwLockThread )
|
||||
{
|
||||
m_dwLockCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
while ( Unlocked != InterlockedCompareExchange( &m_uLockFlag, Locked, Unlocked ) )
|
||||
{
|
||||
OnLockWait();
|
||||
}
|
||||
m_dwLockThread = dwThreadId;
|
||||
m_dwLockCount++;
|
||||
}
|
||||
m_pFileName =sFile;
|
||||
m_nLine= nLine;
|
||||
}
|
||||
|
||||
BOOL CAtomLock::TryLock()
|
||||
{
|
||||
#ifdef WIN32
|
||||
DWORD dwThreadId = GetCurrentThreadId();
|
||||
#else
|
||||
DWORD dwThreadId = pthread_self();
|
||||
#endif
|
||||
|
||||
if ( dwThreadId == m_dwLockThread )
|
||||
{
|
||||
m_dwLockCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ( Unlocked != InterlockedCompareExchange( &m_uLockFlag, Locked, Unlocked ) )
|
||||
return false;
|
||||
m_dwLockThread = dwThreadId;
|
||||
m_dwLockCount++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAtomLock::_Unlock( char *sFile,int nLine)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if ( GetCurrentThreadId() == m_dwLockThread )
|
||||
#else
|
||||
if ( pthread_self() == m_dwLockThread )
|
||||
#endif
|
||||
{
|
||||
m_dwLockCount--;
|
||||
if ( !m_dwLockCount )
|
||||
{
|
||||
m_uLockFlag = Unlocked;
|
||||
m_dwLockThread = 0;
|
||||
}
|
||||
}
|
||||
m_pFileName =0;
|
||||
m_nLine= 0;
|
||||
}
|
||||
|
||||
void CAtomLock::OnLockWait()
|
||||
{
|
||||
}
|
||||
//#endif
|
||||
116
sdk/system/Lock.h
Normal file
116
sdk/system/Lock.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef _MLOCK_H_
|
||||
#define _MLOCK_H_
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* wyLib库数互斥锁类
|
||||
*
|
||||
* 主要功能 *
|
||||
* 进程内部的互斥锁。Windows中提供临界区锁(CCSLock)和原子锁(
|
||||
* CAtomLock)两种互斥实现方式。另外提供一个可在函数内部安全
|
||||
* 使用的CSafeLock类。
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
namespace wylib
|
||||
{
|
||||
namespace sync
|
||||
{
|
||||
namespace lock
|
||||
{
|
||||
/* 基础锁类
|
||||
抽象类
|
||||
*/
|
||||
class CBaseLock
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void _Lock( char * sFile, int nLine) = 0;
|
||||
virtual BOOL TryLock() = 0;
|
||||
virtual void _Unlock( char * sFile, int nLine) = 0;
|
||||
|
||||
|
||||
//为了定位死锁问题,增加了锁定者的位置
|
||||
#define Lock() _Lock( (char *)__FILE__, __LINE__)
|
||||
#define Unlock() _Unlock( (char *)__FILE__, __LINE__)
|
||||
|
||||
protected:
|
||||
char * m_pFileName; //锁定者的文件名
|
||||
int m_nLine; //锁定者的行数
|
||||
};
|
||||
|
||||
class CCSLock
|
||||
: public CBaseLock
|
||||
{
|
||||
public:
|
||||
typedef CBaseLock Inherited;
|
||||
private:
|
||||
#ifdef WIN32
|
||||
CRITICAL_SECTION m_CriticalSection;
|
||||
#else
|
||||
//static bool attr_initalized;
|
||||
//static pthread_mutexattr_t attr;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
|
||||
#endif
|
||||
public:
|
||||
CCSLock();
|
||||
virtual ~CCSLock();
|
||||
|
||||
void _Lock( char * sFile, int nLine);
|
||||
|
||||
void _Unlock( char * sFile, int nLine);
|
||||
|
||||
BOOL TryLock();
|
||||
|
||||
|
||||
};
|
||||
//#ifdef WIN32
|
||||
class CAtomLock
|
||||
: public CBaseLock
|
||||
{
|
||||
public:
|
||||
typedef CBaseLock Inherited;
|
||||
enum AtomLockState
|
||||
{
|
||||
Unlocked = 0,
|
||||
Locked = 1,
|
||||
};
|
||||
private:
|
||||
LONG volatile m_uLockFlag;
|
||||
DWORD volatile m_dwLockThread;
|
||||
DWORD volatile m_dwLockCount;
|
||||
public:
|
||||
CAtomLock();
|
||||
virtual ~CAtomLock();
|
||||
void _Lock( char * sFile, int nLine);
|
||||
BOOL TryLock();
|
||||
void _Unlock( char * sFile, int nLine);
|
||||
virtual void OnLockWait();
|
||||
};
|
||||
//#else
|
||||
// #define CAtomLock CCSLock
|
||||
//#endif
|
||||
class CSafeLock
|
||||
{
|
||||
private:
|
||||
CBaseLock *m_pLock;
|
||||
public:
|
||||
inline CSafeLock(CBaseLock *pLock)
|
||||
{
|
||||
m_pLock = pLock;
|
||||
pLock->Lock();
|
||||
}
|
||||
inline ~CSafeLock()
|
||||
{
|
||||
m_pLock->Unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
165
sdk/system/PathThreadLocale.cpp
Normal file
165
sdk/system/PathThreadLocale.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <tchar.h>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include <Tick.h>
|
||||
#include "ShareUtil.h"
|
||||
|
||||
/**
|
||||
* 跳转指令结构
|
||||
*************************/
|
||||
#pragma pack(push, 1)
|
||||
struct JMPInstruct32
|
||||
{
|
||||
unsigned char code;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
struct JMPInstruct64
|
||||
{
|
||||
unsigned short code;
|
||||
unsigned int loAddrCST;
|
||||
unsigned __int64 offset;
|
||||
};
|
||||
|
||||
union JMPInstruct
|
||||
{
|
||||
JMPInstruct32 c32;
|
||||
JMPInstruct64 c64;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
union JMPInstruct CodeSource;
|
||||
static char sCP[128];
|
||||
|
||||
static HANDLE WINAPI _CreateThread_Path_(
|
||||
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
__in SIZE_T dwStackSize,
|
||||
__in LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
__in_opt __deref __drv_aliasesMem LPVOID lpParameter,
|
||||
__in DWORD dwCreationFlags,
|
||||
__out_opt LPDWORD lpThreadId
|
||||
);
|
||||
|
||||
|
||||
//计算跳转偏移地址
|
||||
#define CalcJmpOffset32(s, d) ((SIZE_T)(d) - ((SIZE_T)(s) + 5))
|
||||
#define CalcJmpOffset64(s, d) ((SIZE_T)(d))
|
||||
|
||||
static int PathCreateThreadCode(const JMPInstruct* pCode)
|
||||
{
|
||||
JMPInstruct* fn = (JMPInstruct*)&CreateThread;
|
||||
DWORD dwOldProtect;
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
if ( VirtualQuery(fn, &mbi, sizeof(mbi)) != sizeof(mbi) )
|
||||
return GetLastError();
|
||||
|
||||
//修改_output_l函数的内存保护模式,增加可读写保护
|
||||
if ( !VirtualProtect(fn, sizeof(*fn), PAGE_EXECUTE_READWRITE, &dwOldProtect) )
|
||||
return GetLastError();
|
||||
|
||||
//改写跳转代码
|
||||
if (sizeof(void*) == 8)
|
||||
fn->c64 = pCode->c64;
|
||||
else if (sizeof(void*) == 4)
|
||||
fn->c32 = pCode->c32;
|
||||
|
||||
//还原_output_l函数的内存保护模式
|
||||
if ( !VirtualProtect(fn, sizeof(*fn), dwOldProtect, &dwOldProtect) )
|
||||
return GetLastError();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//设置代码跳转补丁
|
||||
static int PathCreateThread()
|
||||
{
|
||||
JMPInstruct pc;
|
||||
if (sizeof(void*) == 8)
|
||||
{
|
||||
//JMP [OFFSET]
|
||||
pc.c64.code = 0x25FF;
|
||||
pc.c64.loAddrCST = 0;//固定为0
|
||||
pc.c64.offset = CalcJmpOffset64(&CreateThread, &_CreateThread_Path_);
|
||||
}
|
||||
else if (sizeof(void*) == 4)
|
||||
{
|
||||
pc.c32.code = 0xE9;
|
||||
pc.c32.offset = (UINT)CalcJmpOffset32(&CreateThread, &_CreateThread_Path_);
|
||||
}
|
||||
return PathCreateThreadCode(&pc);
|
||||
}
|
||||
|
||||
//解除代码跳转补丁
|
||||
static int UnPathCreateThread()
|
||||
{
|
||||
return PathCreateThreadCode(&CodeSource);
|
||||
}
|
||||
|
||||
int InstallThreadLocalePath(const char *lc)
|
||||
{
|
||||
//保存原始代码字节
|
||||
if (!CodeSource.c32.code) CodeSource = *((JMPInstruct*)&CreateThread);
|
||||
//保存设定的数据
|
||||
_asncpytA(sCP, lc);
|
||||
//设置跳转
|
||||
return PathCreateThread();
|
||||
}
|
||||
|
||||
static void SetupThreadLocale()
|
||||
{
|
||||
//参见:http://msdn.microsoft.com/zh-cn/library/ms235302(VS.80).aspx
|
||||
//★★★setlocal是针对线程的!
|
||||
//设置locale为C,设置mbcp为_MB_CP_SBCS,以便支持libc中文字处理相关的函数支持UTF-8
|
||||
setlocale(LC_ALL, sCP);
|
||||
}
|
||||
|
||||
|
||||
struct PTD
|
||||
{
|
||||
LPTHREAD_START_ROUTINE routine;
|
||||
LPVOID param;
|
||||
};
|
||||
|
||||
static INT_PTR WINAPI _Path_ThreadLocale_Rountine(PTD *pd)
|
||||
{
|
||||
SetupThreadLocale();
|
||||
PTD td = *pd;
|
||||
|
||||
INT_PTR result = td.routine(td.param);
|
||||
//free(pd);
|
||||
return result;
|
||||
}
|
||||
|
||||
static HANDLE WINAPI _CreateThread_Path_(
|
||||
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
__in SIZE_T dwStackSize,
|
||||
__in LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
__in_opt __deref __drv_aliasesMem LPVOID lpParameter,
|
||||
__in DWORD dwCreationFlags,
|
||||
__out_opt LPDWORD lpThreadId
|
||||
)
|
||||
{
|
||||
UnPathCreateThread();
|
||||
|
||||
PTD *p = (PTD*)malloc(sizeof(*p));
|
||||
p->routine = lpStartAddress;
|
||||
p->param = lpParameter;
|
||||
|
||||
HANDLE result = CreateThread(lpThreadAttributes, dwStackSize,
|
||||
(LPTHREAD_START_ROUTINE)_Path_ThreadLocale_Rountine,
|
||||
p, dwCreationFlags, lpThreadId);
|
||||
|
||||
PathCreateThread();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
15
sdk/system/PathThreadLocale.h
Normal file
15
sdk/system/PathThreadLocale.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
/************************************************************************
|
||||
|
||||
线程locale自动设置的功能库
|
||||
|
||||
由于libc中的setlocale的设定是仅影响当前线程的,但每次创建线程均手动设置比较麻烦,且
|
||||
无法再更底层的库中进行通用化管理,因此提供一套代码补丁,按需在工程中进行设置。
|
||||
|
||||
通过向CreateThread函数打代码补丁从而实现对创建线程函数的Hook,并在创建线程后立刻为
|
||||
线程设置locale以及mbcp。
|
||||
|
||||
************************************************************************/
|
||||
|
||||
int InstallThreadLocalePath(const char *lc);
|
||||
48
sdk/system/SocketConfig.h
Normal file
48
sdk/system/SocketConfig.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef _SOCKET_CONFIG_H_
|
||||
#define _SOCKET_CONFIG_H_
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
# ifdef WIN32
|
||||
# define socklen_t int
|
||||
# include <winsock.h>
|
||||
# else
|
||||
# define SOCKET int
|
||||
# define SD_BOTH SHUT_RDWR
|
||||
# define INVALID_SOCKET -1
|
||||
# define WSAGetLastError() errno
|
||||
# define WSAEWOULDBLOCK EWOULDBLOCK
|
||||
# define closesocket close
|
||||
# define OUT
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
# ifndef SOCKET_ERROR
|
||||
# define SOCKET_ERROR (-1)
|
||||
# endif
|
||||
|
||||
typedef struct sockaddr_in SOCKADDR_IN;
|
||||
typedef struct sockaddr_in *PSOCKADDR_IN;
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
# include <unistd.h>
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "_memchk.h"
|
||||
#include "TypeDef.h"
|
||||
#include "CustomSocket.h"
|
||||
#include "wyString.h"
|
||||
|
||||
#endif //_SOCKET_CONFIG_H_
|
||||
64
sdk/system/SysApi.cpp
Normal file
64
sdk/system/SysApi.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
#include "SysApi.h"
|
||||
//#include <sys/time.h>
|
||||
// #include <string>
|
||||
// #include <vector>
|
||||
// #include <signal.h>
|
||||
//#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
void Sleep(unsigned int nSec)
|
||||
{
|
||||
struct timeval delay;
|
||||
if(nSec > 1000)
|
||||
{
|
||||
delay.tv_sec=nSec /1000;
|
||||
delay.tv_usec = (nSec % 1000) * 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay.tv_sec=0;
|
||||
delay.tv_usec = nSec *1000;
|
||||
}
|
||||
select(0,0,0,0,&delay);
|
||||
}
|
||||
|
||||
int _kbhit(void)
|
||||
{
|
||||
struct termios oldt, newt;
|
||||
int ch;
|
||||
int oldf;
|
||||
tcgetattr(STDIN_FILENO, &oldt);
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
|
||||
ch = getchar();
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
fcntl(STDIN_FILENO, F_SETFL, oldf);
|
||||
if(ch != EOF)
|
||||
{
|
||||
ungetc(ch, stdin);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int _kbhit2 (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set rdfs;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&rdfs);
|
||||
FD_SET (STDIN_FILENO, &rdfs);
|
||||
|
||||
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
|
||||
return FD_ISSET(STDIN_FILENO, &rdfs);
|
||||
|
||||
}
|
||||
103
sdk/system/SysApi.h
Normal file
103
sdk/system/SysApi.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef _WYL_OS___SYSAPI_H_
|
||||
#define _WYL_OS___SYSAPI_H_
|
||||
//主要是系统的一些API的集成
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#else
|
||||
|
||||
//Sleep For WIndows
|
||||
// void Sleep(unsigned int nSec);
|
||||
|
||||
// int _kbhit(void);
|
||||
|
||||
void Sleep(unsigned int nSec);
|
||||
// {
|
||||
// struct timeval delay;
|
||||
// if(nSec > 1000)
|
||||
// {
|
||||
// delay.tv_sec=nSec /1000;
|
||||
// delay.tv_usec = (nSec % 1000) * 1000;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// delay.tv_sec=0;
|
||||
// delay.tv_usec = nSec *1000;
|
||||
// }
|
||||
// select(0,0,0,0,&delay);
|
||||
// }
|
||||
|
||||
int _kbhit(void);
|
||||
// {
|
||||
// struct termios oldt, newt;
|
||||
// int ch;
|
||||
// int oldf;
|
||||
// tcgetattr(STDIN_FILENO, &oldt);
|
||||
// newt = oldt;
|
||||
// newt.c_lflag &= ~(ICANON | ECHO);
|
||||
// tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
// oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
// fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
|
||||
// ch = getchar();
|
||||
// tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
// fcntl(STDIN_FILENO, F_SETFL, oldf);
|
||||
// if(ch != EOF)
|
||||
// {
|
||||
// ungetc(ch, stdin);
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int _kbhit(void)
|
||||
// {
|
||||
// struct termios oldt, newt;
|
||||
// int ch;
|
||||
// int oldf;
|
||||
// tcgetattr(STDIN_FILENO, &oldt);
|
||||
// newt = oldt;
|
||||
// newt.c_lflag &= ~(ICANON | ECHO);
|
||||
// tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
// oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
// fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
|
||||
// ch = getchar();
|
||||
// tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
// fcntl(STDIN_FILENO, F_SETFL, oldf);
|
||||
// if(ch != EOF)
|
||||
// {
|
||||
// ungetc(ch, stdin);
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
int _kbhit2 (void);
|
||||
// {
|
||||
// struct timeval tv;
|
||||
// fd_set rdfs;
|
||||
|
||||
// tv.tv_sec = 0;
|
||||
// tv.tv_usec = 0;
|
||||
|
||||
// FD_ZERO(&rdfs);
|
||||
// FD_SET (STDIN_FILENO, &rdfs);
|
||||
|
||||
// select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
|
||||
// return FD_ISSET(STDIN_FILENO, &rdfs);
|
||||
|
||||
// }
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
355
sdk/system/Thread.cpp
Normal file
355
sdk/system/Thread.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
#include "_osdef.h"
|
||||
#include "Thread.h"
|
||||
#include "stdio.h"
|
||||
using namespace wylib::thread;
|
||||
|
||||
|
||||
|
||||
|
||||
CBaseThread::CBaseThread(char *sThreadName,THREAD_CALLBACK callFun,void * pData)
|
||||
{
|
||||
m_hThread = 0;
|
||||
m_dwThreadId = 0;
|
||||
m_boWorking =0; //没有启动
|
||||
m_boHasStoped =0; //是否已经停止完成了
|
||||
//m_boTerminated = false;
|
||||
|
||||
m_callFun =callFun;
|
||||
m_pCallBackData =pData;
|
||||
|
||||
if(sThreadName !=NULL)
|
||||
{
|
||||
strncpy(m_threadName,sThreadName,sizeof(m_threadName));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_threadName[0]=0;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
m_hWorkThreadEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); //等待线程启动事件发生
|
||||
#else
|
||||
m_boSuspend = false;
|
||||
pthread_mutex_init(&m_Mutex, NULL);
|
||||
pthread_cond_init(&m_Cond, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
CBaseThread::~CBaseThread()
|
||||
{
|
||||
StopWorkThread();
|
||||
|
||||
#ifndef WIN32
|
||||
pthread_mutex_destroy(&m_Mutex);
|
||||
pthread_cond_destroy(&m_Cond);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
THREAD_HANDLE CBaseThread::CreateThreadHandle(const DWORD dwFlags)
|
||||
{
|
||||
#ifdef WIN32
|
||||
m_hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ThreadRoutine, this, dwFlags, &m_dwThreadId);
|
||||
#else
|
||||
pthread_create(&m_hThread, NULL, ThreadRoutine, (void*)this);
|
||||
//suspend();
|
||||
m_dwThreadId = m_hThread;
|
||||
printf("[thread%s-%u]create\n\r",m_threadName,(unsigned int)m_dwThreadId);
|
||||
#endif
|
||||
return m_hThread;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
unsigned int CALLBACK CBaseThread::ThreadRoutine(void *lpThread)
|
||||
{
|
||||
if(lpThread ==NULL) return 0 ;
|
||||
|
||||
CBaseThread *pThread = (CBaseThread *)lpThread;
|
||||
|
||||
//唤醒线程
|
||||
if(pThread->m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
||||
SetEvent(pThread->m_hWorkThreadEvent);
|
||||
}
|
||||
|
||||
InterlockedCompareExchange(&pThread->m_boWorking, TRUE, FALSE );
|
||||
pThread->OnThreadStarted();
|
||||
|
||||
//如果不传参数进来,则使用本身的继承的方式
|
||||
if(pThread->m_callFun ==NULL)
|
||||
{
|
||||
|
||||
while(pThread->m_boWorking)
|
||||
{
|
||||
pThread->OnRountine();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(pThread->m_boWorking )
|
||||
{
|
||||
pThread->m_callFun(pThread->m_pCallBackData); //调用
|
||||
}
|
||||
}
|
||||
|
||||
if(pThread)
|
||||
{
|
||||
pThread->OnTerminated();
|
||||
|
||||
SetEvent(pThread->m_hWorkThreadEvent); //让等待的人退出
|
||||
InterlockedCompareExchange(&pThread->m_boHasStoped, TRUE, FALSE ); //表示已经停止了
|
||||
}
|
||||
|
||||
|
||||
ExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void * CBaseThread::ThreadRoutine(void * lpThread)
|
||||
{
|
||||
if(lpThread ==NULL) return 0;
|
||||
CBaseThread *pThread = (CBaseThread *)lpThread;
|
||||
char * sName = pThread->m_threadName;
|
||||
unsigned int nThreadId = pThread->m_dwThreadId;
|
||||
|
||||
printf("[thread %s-%u] ThreadRoutine\n\r",sName,nThreadId);
|
||||
|
||||
//唤醒母线程
|
||||
pthread_mutex_t * pMutex = &( pThread->m_Mutex);
|
||||
pthread_cond_t * pCond = &( pThread->m_Cond);
|
||||
|
||||
pthread_mutex_lock(pMutex);
|
||||
pthread_cond_signal(pCond);
|
||||
pthread_mutex_unlock(pMutex);
|
||||
|
||||
InterlockedCompareExchange(&pThread->m_boWorking, TRUE, FALSE );
|
||||
pThread->OnThreadStarted();
|
||||
if(pThread->m_callFun ==NULL)
|
||||
{
|
||||
while(pThread->m_boWorking)
|
||||
{
|
||||
pThread->OnRountine();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(pThread->m_boWorking)
|
||||
{
|
||||
pThread->m_callFun(pThread->m_pCallBackData); //调用
|
||||
}
|
||||
}
|
||||
pThread->OnTerminated();
|
||||
|
||||
pMutex = &( pThread->m_Mutex);
|
||||
pCond = &( pThread->m_Cond);
|
||||
|
||||
pthread_mutex_lock(pMutex);
|
||||
pthread_cond_signal(pCond);
|
||||
pthread_mutex_unlock(pMutex);
|
||||
InterlockedCompareExchange(&pThread->m_boHasStoped, TRUE, FALSE ); //表示已经停止了
|
||||
|
||||
printf("[thread %s-%u]exit\n\r",sName,nThreadId);
|
||||
//InterlockedCompareExchange(&pThread->m_boWorking, FALSE, TRUE );
|
||||
|
||||
pthread_exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void CBaseThread::OnRountine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CBaseThread::OnSuspend(int nSuspendCount)
|
||||
{
|
||||
}
|
||||
|
||||
void CBaseThread::OnResume(int nSuspendCount)
|
||||
{
|
||||
}
|
||||
|
||||
void CBaseThread::OnTerminated()
|
||||
{
|
||||
}
|
||||
|
||||
int CBaseThread::suspend()
|
||||
{
|
||||
|
||||
int dwSuspended;
|
||||
#ifdef WIN32
|
||||
dwSuspended = SuspendThread( m_hThread );
|
||||
#else
|
||||
if(m_boSuspend ) return -1;
|
||||
pthread_mutex_lock(&m_Mutex);
|
||||
m_boSuspend =true;
|
||||
dwSuspended = pthread_cond_wait(&m_Cond, &m_Mutex);
|
||||
pthread_mutex_unlock(&m_Mutex);
|
||||
|
||||
#endif
|
||||
if ( dwSuspended != -1 )
|
||||
{
|
||||
OnSuspend(dwSuspended + 1);
|
||||
return dwSuspended + 1;
|
||||
}
|
||||
return dwSuspended;
|
||||
}
|
||||
|
||||
int CBaseThread::resume()
|
||||
{
|
||||
printf("[thread %s-%u]resume\n\r",m_threadName,(unsigned int)m_dwThreadId);
|
||||
int dwSuspended;
|
||||
#ifdef WIN32
|
||||
dwSuspended = ResumeThread( m_hThread );
|
||||
#else
|
||||
|
||||
pthread_mutex_lock(&m_Mutex);
|
||||
m_boSuspend =false;
|
||||
dwSuspended = pthread_cond_signal(&m_Cond);
|
||||
pthread_mutex_unlock(&m_Mutex);
|
||||
|
||||
printf("[thread %s-%u]resume end\n\r",m_threadName,(unsigned int)m_dwThreadId);
|
||||
|
||||
#endif
|
||||
if ( dwSuspended != -1 )
|
||||
{
|
||||
OnResume(dwSuspended - 1);
|
||||
return dwSuspended - 1;
|
||||
}
|
||||
return dwSuspended;
|
||||
}
|
||||
|
||||
int CBaseThread::getPriority()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return GetThreadPriority( m_hThread );
|
||||
#else
|
||||
return getpriority(PRIO_PROCESS, m_dwThreadId);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CBaseThread::setPriority(int nPriority)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return SetThreadPriority( m_hThread, nPriority ) != 0;
|
||||
#else
|
||||
return setpriority(PRIO_PROCESS, m_dwThreadId, nPriority);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CBaseThread::waitFor(DWORD dwWaitLong, bool boWaitAlertAble)
|
||||
{
|
||||
if(FALSE== InterlockedCompareExchange(&m_boHasStoped, FALSE, FALSE) ) //如果引擎已经启动得话
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
return WaitForSingleObjectEx( m_hWorkThreadEvent, dwWaitLong, boWaitAlertAble );
|
||||
#else
|
||||
return pthread_join(m_hThread, NULL); //等待一个线程的结束
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CBaseThread::terminate()
|
||||
{
|
||||
InterlockedCompareExchange(&m_boWorking, FALSE, TRUE); //
|
||||
|
||||
}
|
||||
|
||||
// 开始工作,创建工作线程发送数据
|
||||
void CBaseThread::StartWorkThread()
|
||||
{
|
||||
if( m_hThread !=0 )return;
|
||||
|
||||
if( CreateThreadHandle( 0 ) <=0 ) //创建线程失败
|
||||
{
|
||||
printf("Create thread %s Fail",m_threadName);
|
||||
return;
|
||||
}
|
||||
printf("Start thread id=%d\n",(int)m_hThread);
|
||||
|
||||
//如果线程还没有启动完成,需要等待一段时间
|
||||
if(FALSE== InterlockedCompareExchange(&m_boWorking, FALSE, FALSE) ) //如果引擎已经启动得话
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
if(m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if( WAIT_TIMEOUT == WaitForSingleObject(m_hWorkThreadEvent, 300000) ) //等待工作线程启动,等待5秒,如果没启动工作线程的话
|
||||
{
|
||||
printf("Create thread time out");
|
||||
}
|
||||
ResetEvent(m_hWorkThreadEvent);
|
||||
}
|
||||
#else
|
||||
struct timespec nowTimer;
|
||||
nowTimer.tv_sec = time(NULL) +5;
|
||||
nowTimer.tv_nsec=0;
|
||||
pthread_mutex_lock(&m_Mutex);
|
||||
//dwSuspended = pthread_cond_wait(&m_Cond, &m_Mutex);
|
||||
//这里不使用长等待,使用限时的等待,避免线程启动失败,把母线程卡死的现象
|
||||
int ret= pthread_cond_timedwait(&m_Cond,&m_Mutex,&nowTimer ); //等待5秒钟看效果
|
||||
if(ret == ETIMEDOUT)
|
||||
{
|
||||
printf("Create thread time out");
|
||||
}
|
||||
pthread_mutex_unlock(&m_Mutex);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
if(m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if(m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ResetEvent(m_hWorkThreadEvent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 停止工作线程发送数据
|
||||
void CBaseThread::StopWorkThread()
|
||||
{
|
||||
if(FALSE== InterlockedCompareExchange(&m_boWorking, FALSE, FALSE) )
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
terminate();
|
||||
waitFor(300000);
|
||||
printf("Stop thread id=%d",(int)m_hThread);
|
||||
if ( m_hThread )
|
||||
{
|
||||
#ifdef WIN32
|
||||
if(m_hThread != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle( m_hThread );
|
||||
}
|
||||
#else
|
||||
//pthread_mutex_destroy(&m_Mutex);
|
||||
//pthread_cond_destroy(&m_Cond);
|
||||
#endif
|
||||
m_hThread = 0;
|
||||
m_boWorking =FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
162
sdk/system/Thread.h
Normal file
162
sdk/system/Thread.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#ifndef _WYL_THREAD_H_
|
||||
#define _WYL_THREAD_H_
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* wyLib库 2008 - 2010
|
||||
*
|
||||
* $ 线程基础类 $
|
||||
*
|
||||
* - 主要功能 -
|
||||
*
|
||||
* 实现线程的基本封装操作。支持暂停、恢复线程,等待线程以及设
|
||||
* 置线程优先级等基本操作。
|
||||
* 2013-10-22 修改:
|
||||
1、母线程启动子线程的时候,自身休眠,需要等子线程启动完毕以后,唤醒母线程;
|
||||
2、在关闭线程的时候,子线程完全退出以后,唤醒母线程,将外边的线程调用全部整合到一起;
|
||||
*****************************************************************/
|
||||
|
||||
#include "_osdef.h"
|
||||
namespace wylib
|
||||
{
|
||||
namespace thread
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
#define THREAD_HANDLE HANDLE
|
||||
#else
|
||||
#define THREAD_HANDLE pthread_t
|
||||
typedef void*( *thread_proc)(void*);
|
||||
#endif
|
||||
|
||||
/* 线程基础类
|
||||
|
||||
*/
|
||||
|
||||
class CBaseThread
|
||||
{
|
||||
|
||||
//线程的回调函数,在linux和windows下的实现
|
||||
typedef void (*THREAD_CALLBACK)( void*) ;
|
||||
|
||||
private:
|
||||
THREAD_HANDLE m_hThread; //自身的线程句柄
|
||||
|
||||
volatile long m_boWorking; //是否已经启动了,如果没有启动,需要
|
||||
|
||||
volatile long m_boHasStoped; //是否已经停止了
|
||||
|
||||
#ifndef WIN32
|
||||
pthread_cond_t m_Cond;
|
||||
pthread_mutex_t m_Mutex;
|
||||
volatile bool m_boSuspend;
|
||||
#else
|
||||
volatile HANDLE m_hWorkThreadEvent ; //用于线程同步的事件
|
||||
#endif
|
||||
|
||||
|
||||
DWORD m_dwThreadId; //线程ID
|
||||
char m_threadName[64]; //线程的名字
|
||||
THREAD_CALLBACK m_callFun; //调用函数
|
||||
void * m_pCallBackData; //回调参数
|
||||
|
||||
private:
|
||||
|
||||
THREAD_HANDLE CreateThreadHandle(const DWORD dwFlags);
|
||||
|
||||
|
||||
//启动线程的时候调用
|
||||
//static void OnStartThread(void *lpThread);
|
||||
|
||||
#ifdef WIN32
|
||||
static unsigned int CALLBACK ThreadRoutine(void *lpThread);
|
||||
#else
|
||||
static void* ThreadRoutine(void * lpThread);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
//terminated函数用于判断现成是否被设置了终止标记
|
||||
inline bool terminated(){ return m_boWorking ? false:true; }
|
||||
|
||||
|
||||
//线程启动了
|
||||
virtual void OnThreadStarted(){}
|
||||
|
||||
|
||||
//实时调用,每次调用
|
||||
virtual void OnRountine() ;
|
||||
|
||||
//线程被终止后的通知函数,nSuspendCount参数表示线程被终止的次数
|
||||
virtual void OnSuspend(int nSuspendCount);
|
||||
|
||||
//线程被恢复后的通知函数,nSuspendCount参数表示线程还需恢复多少次后才能恢复执行,为0表示线程已恢复执行
|
||||
virtual void OnResume(int nSuspendCount);
|
||||
|
||||
//线程例程终止后的通知函数
|
||||
virtual void OnTerminated();
|
||||
public:
|
||||
|
||||
|
||||
/*
|
||||
* Comments: 线程类的构造函数,支持2种方式构造线程,一个是继承本类,一种是传调用函数和参数进来,在构造函数中,不会启动线程,需要显示调用StartWorkThread
|
||||
* Parameter: char * sThreadName:线程的名字,用于调试
|
||||
* Parameter: THREAD_CALLBACK callFun:回调函数,如果不使用,就使用OnRountine调用,否则使用 callFun(pData)
|
||||
* Parameter: void * pData:如果callFun不为空的时候,是用户自己设置的调用函数,这个时候,运行附加一个参数pData
|
||||
* @Return :
|
||||
*/
|
||||
CBaseThread(char *sThreadName ="Thread",THREAD_CALLBACK callFun=NULL,void * pData =NULL );
|
||||
|
||||
|
||||
~CBaseThread();
|
||||
|
||||
//线程正式开始工作
|
||||
void StartWorkThread();
|
||||
|
||||
//停止工作
|
||||
void StopWorkThread();
|
||||
|
||||
|
||||
//获取线程句柄
|
||||
inline THREAD_HANDLE getHandle(){ return m_hThread; }
|
||||
|
||||
//获取线程ID
|
||||
inline DWORD getThreadId(){ return m_dwThreadId; }
|
||||
|
||||
//获取线程的名字
|
||||
inline char *GetThreadName() {return m_threadName;}
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
// 启动时候是否需要挂起。因为linux没有此线程api,只能手动挂起,兼容wylib的window特性
|
||||
inline bool isSuspend(){return m_boSuspend;}
|
||||
#endif
|
||||
//暂停线程的执行,返回值表示线程到本次暂停操作后为止总计被暂停的次数。若返回-1则表示暂停线程失败。
|
||||
int suspend();
|
||||
|
||||
//恢复线程的执行,返回值表示线程到本次恢复操作后,线程仍需恢复多少次才能恢复执行。
|
||||
//若返回-1则表示恢复线程失败,返回0表示线程已经完全恢复执行。
|
||||
int resume();
|
||||
|
||||
//获取线程优先级,失败会返回THREAD_PRIORITY_ERROR_RETURN,否则返回值表示线程优先级
|
||||
int getPriority();
|
||||
|
||||
//设置线程优先级,成功则返回true
|
||||
bool setPriority(int nPriority);
|
||||
|
||||
//等待线程执行完毕,dwWaitLong参数表示等待的最大毫秒数,INFINITE表示无限等待。
|
||||
//注意,调用此函数的线程在此线程执行完毕后会一直处于阻塞状态
|
||||
//参数boWaitAlertAble表示调用线程在阻塞期间是否允许进入警告状态(仅对于windows有效)
|
||||
#ifdef WIN32
|
||||
int waitFor(DWORD dwWaitLong = INFINITE, bool boWaitAlertAble = true);
|
||||
#else
|
||||
int waitFor(DWORD dwWaitLong = 0, bool boWaitAlertAble = true);
|
||||
#endif
|
||||
|
||||
//标记线程的终止标记
|
||||
void terminate();
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user