Added ChatServer and soePlatform

This commit is contained in:
Anonymous
2014-01-17 03:40:51 -07:00
parent 26b88b4533
commit 4fae2dfe0f
183 changed files with 64549 additions and 0 deletions
@@ -0,0 +1,44 @@
#ifndef BASE_LINUX_ARCHIVE_H
#define BASE_LINUX_ARCHIVE_H
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
#ifdef PACK_BIG_ENDIAN
inline double byteSwap(double value) { byteReverse(&value); return value; }
inline float byteSwap(float value) { byteReverse(&value); return value; }
inline uint64 byteSwap(uint64 value) { byteReverse(&value); return value; }
inline int64 byteSwap(int64 value) { byteReverse(&value); return value; }
inline uint32 byteSwap(uint32 value) { byteReverse(&value); return value; }
inline int32 byteSwap(int32 value) { byteReverse(&value); return value; }
inline uint16 byteSwap(uint16 value) { byteReverse(&value); return value; }
inline int16 byteSwap(int16 value) { byteReverse(&value); return value; }
#else
inline double byteSwap(double value) { return value; }
inline float byteSwap(float value) { return value; }
inline uint64 byteSwap(uint64 value) { return value; }
inline int64 byteSwap(int64 value) { return value; }
inline uint32 byteSwap(uint32 value) { return value; }
inline int32 byteSwap(int32 value) { return value; }
inline uint16 byteSwap(uint16 value) { return value; }
inline int16 byteSwap(int16 value) { return value; }
#endif
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif
@@ -0,0 +1,110 @@
#include "../BlockAllocator.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
BlockAllocator::BlockAllocator()
{
for(unsigned i = 0; i < 31; i++)
{
m_blocks[i] = NULL;
}
}
BlockAllocator::~BlockAllocator()
{
// free all allocated memory blocks
for(unsigned i = 0; i < 31; i++)
{
while(m_blocks[i] != NULL)
{
unsigned *tmp = m_blocks[i];
m_blocks[i] = (unsigned *)*m_blocks[i];
free(tmp);
}
}
}
// Allocate a block that is the next power of two greater than the # of bytes passed.
// 33 bytes yields a 64 byte block of memory and so forth.
void *BlockAllocator::getBlock(unsigned bytes)
{
unsigned accum = 16, bits = 16;
unsigned *handle = NULL;
// Perform a binary search looking for the highest bit.
while(bits != 0)
{
// If bytes is less than the bit we're testing for, subtract half
// from the bit value and repeat
if(bytes < (unsigned)(1 << accum))
{
bits /= 2;
accum -= bits;
}
// If bytes is greater than the bit we're testing for, add half
// from the but value and repeat
else if(bytes > (unsigned)(1 << accum))
{
bits /= 2;
accum += bits;
}
// Got lucky and hit the value dead on
else
{
break;
}
}
// At this point accum contains the most significant bit index, increment
accum++;
if(accum < 2)
{
accum = 2;
}
// Note that when memory is actually allocated, 8 extra bytes will be allocated.at the front
// The first integer is the address of the next block of memory when the block is in the allocator
// The second integer is the bit length of the block
// Memory is allocated on 4 byte boundaries to sidestep byte alignment problems
// Check if the allocator already has a block of that size
if(m_blocks[accum] == 0)
{
// remove the pre allocated block from the linked list
handle = (unsigned *)calloc(((1 << accum) / 4) + 2, sizeof(unsigned));
handle[1] = accum;
handle[0] = 0;
}
else
{
// Allocate a new block
handle = m_blocks[accum];
m_blocks[accum] = (unsigned *)handle[0];
handle[0] = 0;
}
// return a pointer that skips over the header used for the allocator's purposes
return(handle + 2);
}
void BlockAllocator::returnBlock(unsigned *handle)
{
// C++ allows for safe deletion of a NULL pointer
if(handle)
{
// Update the allocator linked list, insert this entry at the head
*(handle - 2) = (unsigned)m_blocks[*(handle - 1)];
// Add this entry to the proper linked list node
m_blocks[*(handle - 1)] = (handle - 2);
}
}
};
#ifdef EXTERNAL_DISTRO
};
#endif
@@ -0,0 +1,103 @@
////////////////////////////////////////
// Event.cpp
//
// Purpose:
// 1. Implementation of the CEvent class.
//
// Revisions:
// 07/10/2001 Created
//
#if defined(_REENTRANT)
#include "Event.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
CEvent::CEvent() :
mMutex(),
mCond(),
mThreadCount(0)
{
pthread_mutex_init(&mMutex, NULL);
pthread_cond_init(&mCond, NULL);
}
CEvent::~CEvent()
{
pthread_cond_destroy(&mCond);
pthread_mutex_destroy(&mMutex);
}
bool CEvent::Signal()
{
pthread_mutex_lock(&mMutex);
if (mThreadCount == 0)
mThreadCount = SIGNALED;
pthread_cond_signal(&mCond);
pthread_mutex_unlock(&mMutex);
return true;
}
int32 CEvent::Wait(uint32 timeout)
{
int result;
pthread_mutex_lock(&mMutex);
if (mThreadCount == SIGNALED)
{
mThreadCount = 0;
pthread_mutex_unlock(&mMutex);
return eWAIT_SIGNAL;
}
if (!timeout)
{
mThreadCount++;
result = pthread_cond_wait(&mCond, &mMutex);
mThreadCount--;
pthread_mutex_unlock(&mMutex);
}
else
{
struct timeval now;
struct timespec abs_timeout;
gettimeofday(&now, NULL);
abs_timeout.tv_sec = now.tv_sec + timeout/1000;
abs_timeout.tv_nsec = now.tv_usec * 1000 + (timeout%1000)*1000000;
abs_timeout.tv_sec += abs_timeout.tv_nsec / 1000000000;
abs_timeout.tv_nsec %= 1000000000;
mThreadCount++;
result = pthread_cond_timedwait(&mCond, &mMutex, &abs_timeout);
mThreadCount--;
pthread_mutex_unlock(&mMutex);
}
if (result == 0 || result == EINTR)
return eWAIT_SIGNAL;
else if (result == ETIMEDOUT)
return eWAIT_TIMEOUT;
else
return eWAIT_ERROR;
}
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // #if defined(_REENTRANT)
@@ -0,0 +1,74 @@
////////////////////////////////////////
// Event.h
//
// Purpose:
// 1. Declair the CEvent class that encapsulates the functionality of a
// single-locking semaphore.
//
// Revisions:
// 07/10/2001 Created
//
#ifndef BASE_LINUX_EVENT_H
#define BASE_LINUX_EVENT_H
#if !defined(_REENTRANT)
# pragma message( "Excluding Base::CEvent - requires multi-threaded compile. (_REENTRANT)" )
#else
#include <pthread.h>
#include "Platform.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
////////////////////////////////////////
// Class:
// CEvent
//
// Purpose:
// Encapsulates the functionality of a singal-locking semaphore.
// This class is valuable for thread syncronization when a thead's
// execution needs to be dependent upon another thread.
//
// Public Methods:
// Signal() : Signals a thread that has called Wait() so that it can
// continue execution. This function returns true if the waiting
// thread was signalled successfully, otherwise false is returned.
// Wait() : Halts the calling thread's execution indefinately until
// a Singal() call is made by an external thread. If the thread is
// successfully signalled, the function returns eWAIT_SIGNAL. If
// timeout period expires without a signal, eWAIT_TIMEOUT is returned.
// If the function fails, eWAIT_ERROR is returned.
//
class CEvent
{
public:
CEvent();
virtual ~CEvent();
bool Signal();
int32 Wait(uint32 timeout = 0);
public:
enum { eWAIT_ERROR, eWAIT_SIGNAL, eWAIT_TIMEOUT };
enum { SIGNALED = -1 };
private:
pthread_mutex_t mMutex;
pthread_cond_t mCond;
int mThreadCount;
};
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // #if defined(_MT)
#endif // BASE_LINUX_EVENT_H
@@ -0,0 +1,40 @@
////////////////////////////////////////
// Mutex.cpp
//
// Purpose:
// 1. Implementation of the CMutex class.
//
// Revisions:
// 07/10/2001 Created
//
#if defined(_REENTRANT)
#include "Mutex.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
CMutex::CMutex()
{
mInitialized = (pthread_mutex_init(&mMutex, 0) == 0);
}
CMutex::~CMutex()
{
if (mInitialized)
pthread_mutex_destroy(&mMutex);
}
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // #if defined(_REENTRANT)
@@ -0,0 +1,79 @@
////////////////////////////////////////
// Mutex.h
//
// Purpose:
// 1. Declair the CMutex class that encapsulates the functionality of a
// mutually-exclusive device.
//
// Revisions:
// 07/10/2001 Created
//
#ifndef BASE_LINUX_MUTEX_H
#define BASE_LINUX_MUTEX_H
#if !defined(_REENTRANT)
# pragma message( "Excluding Base::CMutex - requires multi-threaded compile. (_REENTRANT)" )
#else
#include "Platform.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
////////////////////////////////////////
// Class:
// CMutex
//
// Purpose:
// Encapsulates the functionality of a mutually-exclusive device.
// This class is valuable for protecting against race conditions
// within threaded applications. The CMutex class can be used to
// only allow a single thread to run within a specified code
// segment at a time.
//
// Public Methods:
// Lock() : Locks the mutex. If the mutex is already locked, the
// operating system will block the calling thread until another
// thread has unlocked the mutex.
// Unlock() : Unlocks the mutex.
//
class CMutex
{
public:
CMutex();
~CMutex();
void Lock();
void Unlock();
private:
pthread_mutex_t mMutex;
bool mInitialized;
};
inline void CMutex::Lock(void)
{
if (mInitialized)
pthread_mutex_lock(&mMutex);
}
inline void CMutex::Unlock(void)
{
if (mInitialized)
pthread_mutex_unlock(&mMutex);
}
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // #if defined(_MT)
#endif // BASE_LINUX_MUTEX_H
@@ -0,0 +1,55 @@
////////////////////////////////////////
// Platform.cpp
//
// Purpose:
// 1. Implementation of the global functionality declaired in Platform.h.
//
// Revisions:
// 07/10/2001 Created
//
#include <ctype.h>
#include "Platform.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
// Implementation of microsoft strlwr extension
// This non-ANSI function is not supported under UNIX
void strlwr(char * s)
{
while (*s)
{
*s = tolower(*s);
s++;
}
}
// Implementation of microsoft strlwr extension
// This non-ANSI function is not supported under UNIX
void strupr(char * s)
{
while (*s)
{
*s = toupper(*s);
s++;
}
}
CTimer::CTimer() :
mTimer(0)
{
}
}
#ifdef EXTERNAL_DISTRO
};
#endif
@@ -0,0 +1,112 @@
////////////////////////////////////////
// Platform.h
//
// Purpose:
// 1. Include relevent system headers that are platform specific.
// 2. Declair global platform specific functionality.
// 3. Include primative type definitions
//
// Global Functions:
// getTimer() : Return the current high resolution clock count.
// getTimerFrequency() : Return the frequency of the high resolution clock.
// sleep() : Voluntarily relinquish timeslice of the calling thread for a
// specified number of milliseconds.
// strlwr() : Alters the contents of a string, making it all lower-case.
//
// Revisions:
// 07/10/2001 Created
//
#ifndef BASE_LINUX_PLATFORM_H
#define BASE_LINUX_PLATFORM_H
#include <errno.h>
#include <assert.h>
#include <sys/errno.h>
#include <pthread.h>
#include <resolv.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include "Types.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
uint64 getTimer(void);
uint64 getTimerFrequency(void);
void sleep(uint32 ms);
inline uint64 getTimer(void)
{
uint64 t;
struct timeval tv;
gettimeofday(&tv, 0);
t = tv.tv_sec;
t = t * 1000000;
t += tv.tv_usec;
return t;
}
inline uint64 getTimerFrequency(void)
{
uint64 f = 1000000;
return f;
}
inline void sleep(uint32 ms)
{
usleep(static_cast<unsigned long>(ms * 1000));
}
void strlwr(char * s);
void strupr(char * s);
class CTimer
{
public:
CTimer();
void Set(uint32 seconds);
void Signal();
bool Expired();
private:
uint32 mTimer;
};
inline void CTimer::Set(uint32 interval)
{
mTimer = (uint32)time(0) + interval;
}
inline void CTimer::Signal()
{
mTimer = 0;
}
inline bool CTimer::Expired()
{
return (mTimer <= (uint32)time(0));
}
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // BASE_LINUX_PLATFORM_H
@@ -0,0 +1,299 @@
////////////////////////////////////////
// Thread.cpp
//
// Purpose:
// 1. Implementation of the CThread class.
//
// Revisions:
// 07/10/2001 Created
//
#if defined(_REENTRANT)
#include <pthread.h>
#include <time.h>
#include "Thread.h"
using namespace std;
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
void *threadProc(void *threadPtr)
{
CThread &thread = *((CThread*)threadPtr);
thread.mThreadActive = true;
thread.ThreadProc();
thread.mThreadActive = false;
return 0;
}
CThread::CThread()
{
mThreadID = 0;
mThreadActive = false;
mThreadContinue = false;
}
CThread::~CThread()
{
StopThread();
}
void CThread::StartThread()
{
mThreadContinue = true;
if (pthread_create(&mThreadID,0,threadProc,this) == 0)
pthread_detach(mThreadID);
while (!IsThreadActive())
Base::sleep(1);
}
int32 CThread::StopThread(int timeout)
{
timeout += time(0);
mThreadContinue = false;
while (mThreadActive && time(0)<timeout)
sleep(1);
if (mThreadActive)
{
mThreadActive = false;
return eSTOP_TIMEOUT;
}
return eSTOP_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////
CThreadPool::CMember::CMember(CThreadPool * parent) :
mParent(parent),
mFunction(NULL),
mArgument(NULL),
mSemaphore()
{
StartThread();
}
CThreadPool::CMember::~CMember()
{
}
void CThreadPool::CMember::Destroy()
{
mThreadContinue = false;
mSemaphore.Signal();
}
bool CThreadPool::CMember::Execute(void( *function )( void * ), void * arg)
{
if (mFunction)
return false;
mArgument = arg;
mFunction = function;
mSemaphore.Signal();
return true;
}
void CThreadPool::CMember::ThreadProc()
{
mParent->OnStartup(this);
while (mThreadContinue)
{
mParent->OnIdle(this);
mSemaphore.Wait(mParent->GetTimeOut()*1000);
if (mFunction)
{
mFunction(mArgument);
mArgument = NULL;
mFunction = NULL;
}
else if (mParent->OnDestory(this))
mThreadContinue = false;
}
}
////////////////////////////////////////////////////////////////////////////////
CThreadPool::CThreadPool(uint32 maxThreads, uint32 minThreads, uint32 timeout) :
mMutex(),
mIdleMember(),
mBusyMember(),
mNullMember(),
mThreadCount(0),
mMaxThreads(maxThreads),
mMinThreads(minThreads),
mTimeOut(timeout)
{
if (mMaxThreads == 0) mMaxThreads = 1;
if (mMinThreads == 0) mMinThreads = 1;
if (mMinThreads > mMaxThreads) mMinThreads = mMaxThreads;
for (uint32 i=0; i<mMinThreads; i++)
new CMember(this);
}
CThreadPool::~CThreadPool()
{
set<CMember *>::iterator setIterator;
////////////////////////////////////////
// (1) Destory all busy member threads
mMutex.Lock();
setIterator = mBusyMember.begin();
while (setIterator != mBusyMember.end())
(*setIterator++)->Destroy();
mMutex.Unlock();
////////////////////////////////////////
// (2) Destory all idle member threads
while (mThreadCount)
{
mMutex.Lock();
setIterator = mIdleMember.begin();
while (setIterator != mIdleMember.end())
(*setIterator++)->Destroy();
mMutex.Unlock();
sleep(1);
}
////////////////////////////////////////
// (3) Delete the null member threads
mMutex.Lock();
while (!mNullMember.empty())
{
delete mNullMember.front();
mNullMember.pop_front();
}
mMutex.Unlock();
}
bool CThreadPool::Execute(void( *function )( void * ), void * arg, uint32 poolGrowthSize )
{
mMutex.Lock();
////////////////////////////////////////
// (1) If no idle members, return false to indicate that no threads
// were available. If the thread count is below the max, create
// a new thread.
if (mIdleMember.empty())
{
if (mThreadCount < mMaxThreads)
{
if (!poolGrowthSize)
poolGrowthSize = mMinThreads;
if ((mThreadCount + poolGrowthSize) > mMaxThreads)
poolGrowthSize = mMaxThreads - mThreadCount;
for (uint32 i(0); i < poolGrowthSize; i++)
new CMember(this);
mMutex.Unlock();
time_t idleTimeout = time(0) + 5;
while(mIdleMember.empty())
{
if (time(0) >= idleTimeout)
{
return false;
}
Base::sleep(10);
}
mMutex.Lock();
}
else
{
mMutex.Unlock();
return false;
}
}
////////////////////////////////////////
// (2) Delete any null member threads.
while (!mNullMember.empty())
{
delete mNullMember.front();
mNullMember.pop_front();
}
////////////////////////////////////////
// (3) Move the first idle thread to the busy set and signal the
// thread to execute the specified function.
CMember * member = *(mIdleMember.begin());
mIdleMember.erase(member);
mBusyMember.insert(member);
member->Execute(function,arg);
mMutex.Unlock();
return true;
}
uint32 CThreadPool::GetTimeOut()
{
return mTimeOut;
}
void CThreadPool::OnStartup(CMember * member)
{
mMutex.Lock();
mThreadCount++;
mIdleMember.insert(member);
mMutex.Unlock();
}
void CThreadPool::OnIdle(CMember * member)
{
mMutex.Lock();
mBusyMember.erase(member);
mIdleMember.insert(member);
mMutex.Unlock();
}
bool CThreadPool::OnDestory(CMember * member)
{
set<CMember *>::iterator setIterator;
mMutex.Lock();
bool result = (setIterator = mIdleMember.find(member)) != mIdleMember.end();
if (result)
{
mNullMember.push_back(member);
mIdleMember.erase(setIterator);
mThreadCount--;
}
mMutex.Unlock();
return result;
}
////////////////////////////////////////////////////////////////////////////////
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // #if defined(_REENTRANT)
@@ -0,0 +1,146 @@
////////////////////////////////////////
// Thread.h
//
// Purpose:
// 1. Declair the CThread class that encapsulates threading functionality.
// This abstract base class in intended to be used to encapsulate
// individual tasks that require threading in derived classes.
//
// Revisions:
// 07/10/2001 Created
//
#ifndef BASE_LINUX_THREAD_H
#define BASE_LINUX_THREAD_H
#if !defined(_REENTRANT)
# pragma message( "Excluding Base::CThread - requires multi-threaded compile. (_REENTRANT)" )
#else
#pragma warning( disable : 4786)
#include <list>
#include <set>
#include "Platform.h"
#include "Mutex.h"
#include "Event.h"
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
////////////////////////////////////////
// Class:
// CThread
//
// Purpose:
// Encapsulates threading functionality. Creating classes derived
// from CThread provides an easy way to encapsulate tasks that require
// their own thread.
//
// Public Methods:
// StartThread() : Creates the low-level thread handle and begins executing
// the CThread::ThreadProc() function within the new thread.
// StopThread() : Signals the ThreadProc() function to stop executing using
// the mThreadContinue member variable, and waits for the ThreadProc()
// function to exit. By default, the function will block for a maximum
// of 5 seconds before exiting without the thread halting.
// IsThreadActive() : Returns true if the physical thread is still executing
// within the ThreadProc() function, otherwise it returns false.
// ThreadProc() : Pure-virtual function that will be executed when the StartThread()
// function is called. Derived classes must implement this function. The
// mThreadContinue member variable should be used internal the the ThreadProc()
// function to indicate whether it should continue executing or exit.
// Protected Attributes:
// mThreadContinue : Boolean value indicating to the ThreadProc() function
// whether to continue executing or to exit. If mThreadContinue is true,
// ThreadProc() should continue, otherwise ThreadProc() should exit. It
// left up to the derived class to implement a ThreadProc() function that
// uses the mThreadContinue member.
//
//
class CThread
{
friend void * threadProc(void *);
public:
enum { eSTOP_SUCCESS, eSTOP_TIMEOUT };
public:
CThread();
virtual ~CThread();
void StartThread();
int32 StopThread(int timeout=5);
bool IsThreadActive() { return mThreadActive; }
protected:
virtual void ThreadProc() {}
protected:
bool mThreadContinue;
private:
pthread_t mThreadID;
bool mThreadActive;
};
class CThreadPool
{
private:
class CMember : public CThread
{
public:
CMember(CThreadPool * parent);
virtual ~CMember();
bool Execute(void( *function )( void * ), void * arg);
void Destroy();
protected:
virtual void ThreadProc();
private:
CThreadPool * mParent;
void( * mFunction )( void * );
void * mArgument;
CEvent mSemaphore;
};
friend class CMember;
public:
CThreadPool(uint32 maxThreads, uint32 minThreads=1, uint32 timeout=15*60);
virtual ~CThreadPool();
virtual bool Execute(void( *function )( void * ), void * arg, uint32 poolGrowthSize = 0);
private:
uint32 GetTimeOut();
void OnStartup(CMember * member);
void OnIdle(CMember * member);
bool OnDestory(CMember * member);
private:
CMutex mMutex;
std::set<CMember *> mIdleMember;
std::set<CMember *> mBusyMember;
std::list<CMember *> mNullMember;
uint32 mThreadCount;
uint32 mMaxThreads;
uint32 mMinThreads;
uint32 mTimeOut;
};
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // #if defined(_REENTRANT)
#endif // BASE_LINUX_THREAD_H
@@ -0,0 +1,42 @@
////////////////////////////////////////
// Types.h
//
// Purpose:
// 1. Define integer types that are unambiguous with respect to size
//
// Revisions:
// 07/10/2001 Created
//
#ifndef BASE_LINUX_TYPES_H
#define BASE_LINUX_TYPES_H
#include <sys/bitypes.h>
#ifdef EXTERNAL_DISTRO
namespace NAMESPACE
{
#endif
namespace Base
{
#define INT32_MAX 0x7FFFFFFF
#define INT32_MIN 0x80000000
#define UINT32_MAX 0xFFFFFFFF
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
}
#ifdef EXTERNAL_DISTRO
};
#endif
#endif // BASE_LINUX_TYPES_H