This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

BIN
sdk/system/.DS_Store vendored Normal file

Binary file not shown.

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

View 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

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

View 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

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