Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
191
Server/RylServerProject/BaseLibrary/Thread/Lock.h
Normal file
191
Server/RylServerProject/BaseLibrary/Thread/Lock.h
Normal file
@@ -0,0 +1,191 @@
|
||||
#ifndef _CLOCK_H_
|
||||
#define _CLOCK_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// 다중 CPU환경에서는 Cache-Line에 대한 고려를 해야만 할 것.
|
||||
#define CACHE_ALIGN 32
|
||||
#define CACHE_PAD(Name, BytesSoFar) \
|
||||
BYTE Name[CACHE_ALIGN - ((BytesSoFar) % CACHE_ALIGN)]
|
||||
|
||||
|
||||
template<class DerivedLockClass>
|
||||
class CLock
|
||||
{
|
||||
public:
|
||||
class Syncronize
|
||||
{
|
||||
public:
|
||||
Syncronize(DerivedLockClass* pLockClass) : m_Lock(*pLockClass) { m_Lock.Lock(); }
|
||||
Syncronize(DerivedLockClass& LockClass) : m_Lock(LockClass) { m_Lock.Lock(); }
|
||||
~Syncronize() { m_Lock.Unlock();}
|
||||
|
||||
protected:
|
||||
DerivedLockClass& m_Lock;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// 이 Lock클래스들은 더이상 상속을 받아서는 안 된다.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DummyLock ------------------------------------------------------------------
|
||||
class CDummyLock : public CLock<CDummyLock>
|
||||
{
|
||||
public:
|
||||
void Lock() { }
|
||||
void Unlock() { }
|
||||
bool IsVaildLock() { return true; }
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SpinLock -------------------------------------------------------------------
|
||||
class CSpinLock : public CLock<CSpinLock>
|
||||
{
|
||||
public:
|
||||
CSpinLock() : m_bLocked(FALSE) { }
|
||||
~CSpinLock() { }
|
||||
void Lock() { while(TRUE == InterlockedExchange(&m_bLocked, TRUE)) { Sleep(0); } }
|
||||
void Unlock() { InterlockedExchange(&m_bLocked, FALSE); }
|
||||
|
||||
bool IsVaildLock() { return true; }
|
||||
|
||||
private:
|
||||
volatile LONG m_bLocked;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Critical Section -----------------------------------------------------------
|
||||
|
||||
class CCSLock : public CLock<CCSLock>
|
||||
{
|
||||
public:
|
||||
CCSLock() { InitializeCriticalSection(&m_CSLock); }
|
||||
~CCSLock() { DeleteCriticalSection(&m_CSLock); }
|
||||
void Lock() { EnterCriticalSection(&m_CSLock); }
|
||||
void Unlock() { LeaveCriticalSection(&m_CSLock); }
|
||||
bool IsVaildLock() { return true; }
|
||||
|
||||
private:
|
||||
CRITICAL_SECTION m_CSLock;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Mutex Lock -----------------------------------------------------------------
|
||||
|
||||
class CMutex : public CLock<CMutex>
|
||||
{
|
||||
public:
|
||||
CMutex() : m_hMutex(CreateMutex(NULL, FALSE, NULL)) { }
|
||||
~CMutex() { if(0 != m_hMutex) { CloseHandle(m_hMutex); } }
|
||||
unsigned long Lock() { return WaitForSingleObject(m_hMutex, INFINITE); }
|
||||
unsigned long Unlock() { return ReleaseMutex(m_hMutex); }
|
||||
bool IsVaildLock() { return (NULL != m_hMutex); }
|
||||
|
||||
private:
|
||||
HANDLE m_hMutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CNamedMutex : public CLock<CNamedMutex>
|
||||
{
|
||||
public:
|
||||
CNamedMutex(const TCHAR* szMutexName, BOOL bInitialOwner)
|
||||
: m_hMutex(CreateMutex(NULL, bInitialOwner, szMutexName)) { }
|
||||
~CNamedMutex() { if(0 != m_hMutex) { CloseHandle(m_hMutex); } }
|
||||
unsigned long Lock() { return WaitForSingleObject(m_hMutex, INFINITE); }
|
||||
unsigned long Unlock() { return ReleaseMutex(m_hMutex); }
|
||||
bool IsVaildLock() { return (NULL != m_hMutex); }
|
||||
|
||||
private:
|
||||
HANDLE m_hMutex;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
class CFairRWLock : private CCSLock
|
||||
{
|
||||
private:
|
||||
Semaphore access_lock; // used as a one-at-a-time release valve
|
||||
CCSLock read_barrier; // used to block/wakeup readers
|
||||
unsigned int is_write_lock; // nonzero if locked for writing
|
||||
unsigned int writer_count; // # of writers waiting for or holding the lock
|
||||
unsigned int reader_count; // # of readers holding the lock
|
||||
unsigned int readers_waiting; // # of readers waiting for the lock
|
||||
|
||||
public:
|
||||
ReadLock()
|
||||
: access_lock(1), is_write_lock(0),
|
||||
writers_waiting(0), reader_count(0), readers_waiting(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ReadLock()
|
||||
{
|
||||
Mutex::Lock();
|
||||
|
||||
// if there is at least one writer using the lock or waiting for it,
|
||||
// we need to wait for access
|
||||
if (writer_count > 0))
|
||||
{
|
||||
if (readers_waiting++ == 0) // if we're the first reader in line
|
||||
Mutex::Unlock();
|
||||
access_lock.Wait(); // get the access lock
|
||||
Mutex::Lock();
|
||||
if (readers_waiting > 1) // then if there are other readers
|
||||
read_barrier.Open(); // let them go
|
||||
}
|
||||
else
|
||||
{
|
||||
Mutex::Unlock();
|
||||
read_barrier.Wait(); // otherwise wait until someone lets us go
|
||||
Mutex::Lock();
|
||||
}
|
||||
readers_waiting--;
|
||||
}
|
||||
reader_count++;
|
||||
Mutex::Unlock();
|
||||
}
|
||||
|
||||
void WriteLock()
|
||||
{
|
||||
Mutex::Lock();
|
||||
writer_count++; // one more writer
|
||||
Mutex::Unlock();
|
||||
access_lock.Wait(); // wait until the access lock is available
|
||||
Mutex::Lock();
|
||||
is_write_lock = 1; // lock is a write lock
|
||||
read_barrier.Close(); // give readers something to wait for
|
||||
Mutex::Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
Mutex::Lock();
|
||||
if (is_write_lock)
|
||||
{ // if this is a write lock
|
||||
is_write_lock = 0; // let it go
|
||||
writer_count--; // one less writer
|
||||
access_lock.Post(); // now let someone else have a chance
|
||||
}
|
||||
else if (--reader_count == 0)
|
||||
{
|
||||
// if we're the last reader
|
||||
access_lock.Post(); // release the access lock
|
||||
}
|
||||
Mutex::Unlock();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
35
Server/RylServerProject/BaseLibrary/Thread/Thread.h
Normal file
35
Server/RylServerProject/BaseLibrary/Thread/Thread.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _CTHREAD_H_
|
||||
#define _CTHREAD_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
|
||||
CThread() : m_hThreadHandle(INVALID_HANDLE_VALUE) { }
|
||||
virtual ~CThread() { }
|
||||
|
||||
protected:
|
||||
|
||||
virtual unsigned int Run() = 0; // 실제 실행 되는 루프를 넣는다.
|
||||
virtual BOOL End() = 0; // 루프가 끝날 수 있는 루틴을 넣는다.
|
||||
|
||||
typedef unsigned int(__stdcall *LPThreadFunc)(void*);
|
||||
static inline unsigned int __stdcall ThreadFunc(void* pArg);
|
||||
|
||||
inline void SetHandle(HANDLE hHandle) { m_hThreadHandle = hHandle; }
|
||||
inline HANDLE GetHandle() { return m_hThreadHandle; }
|
||||
|
||||
HANDLE m_hThreadHandle;
|
||||
|
||||
friend class CThreadMgr;
|
||||
};
|
||||
|
||||
inline unsigned int __stdcall CThread::ThreadFunc(void* pArg)
|
||||
{
|
||||
return static_cast<CThread*>(pArg)->Run();
|
||||
}
|
||||
|
||||
#endif
|
||||
126
Server/RylServerProject/BaseLibrary/Thread/ThreadMgr.cpp
Normal file
126
Server/RylServerProject/BaseLibrary/Thread/ThreadMgr.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "stdafx.h"
|
||||
#include "Thread.h"
|
||||
#include "ThreadMgr.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "GMMemory.h"
|
||||
|
||||
// constructor and destructor
|
||||
CThreadMgr::CThreadMgr()
|
||||
: m_nThreadNum(0), m_bJoinStarted(FALSE)
|
||||
{
|
||||
std::fill_n(m_lpThreads, size_t(MAX_THREAD_NUM), reinterpret_cast<CThread*>(0));
|
||||
std::fill_n(m_hThreads, size_t(MAX_THREAD_NUM), INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
CThreadMgr::~CThreadMgr()
|
||||
{
|
||||
JoinThread();
|
||||
}
|
||||
|
||||
|
||||
bool CThreadMgr::RegisterAndRun(CThread* llpThread)
|
||||
{
|
||||
unsigned int nThreadID = 0;
|
||||
unsigned int nThreadIndex = 0;
|
||||
|
||||
if(0 == llpThread)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lock
|
||||
{
|
||||
ThreadLock::Syncronize sync(m_ThreadLock);
|
||||
|
||||
if(63 <= m_nThreadNum || TRUE == m_bJoinStarted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nThreadIndex = m_nThreadNum;
|
||||
++m_nThreadNum;
|
||||
}
|
||||
|
||||
m_lpThreads[nThreadIndex] = llpThread;
|
||||
m_hThreads[nThreadIndex] = reinterpret_cast<HANDLE>(_beginthreadex(0, 0,
|
||||
CThread::ThreadFunc, llpThread, 0, &nThreadID));
|
||||
|
||||
return (0 != m_hThreads[nThreadIndex]);
|
||||
}
|
||||
|
||||
bool CThreadMgr::JoinThread()
|
||||
{
|
||||
|
||||
{
|
||||
ThreadLock::Syncronize sync(m_ThreadLock);
|
||||
if(0 == m_nThreadNum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 조인이 시작되면, 더이상의 스레드 생성 및 등록을 금지함.
|
||||
m_bJoinStarted = TRUE;
|
||||
}
|
||||
|
||||
// 스레드 전부 종료 & 대기.
|
||||
std::for_each(&m_lpThreads[0], &m_lpThreads[m_nThreadNum], std::mem_fun(&CThread::End));
|
||||
WaitForMultipleObjects(m_nThreadNum, m_hThreads, TRUE, INFINITE);
|
||||
|
||||
CThread** lppPastEndThread = m_lpThreads + MAX_THREAD_NUM;
|
||||
HANDLE* lppPastEndHandle = m_hThreads + MAX_THREAD_NUM;
|
||||
|
||||
// 스레드 소멸.
|
||||
for(CThread** lplpThread = m_lpThreads;
|
||||
lplpThread != lppPastEndThread; ++lplpThread)
|
||||
{
|
||||
delete *lplpThread;
|
||||
}
|
||||
|
||||
// 스레드 핸들 소멸.
|
||||
for(HANDLE* lppHandle = m_hThreads;
|
||||
lppHandle != lppPastEndHandle; ++lppHandle)
|
||||
{
|
||||
CloseHandle(*lppHandle);
|
||||
}
|
||||
|
||||
{
|
||||
// 스레드 개수 및 조인 여부 리셋.
|
||||
ThreadLock::Syncronize sync(m_ThreadLock);
|
||||
m_nThreadNum = 0;
|
||||
m_bJoinStarted = FALSE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
HANDLE CThreadMgr::Run(CThread* lpThread)
|
||||
{
|
||||
unsigned int nThreadID = 0;
|
||||
HANDLE hThread = reinterpret_cast<HANDLE>(_beginthreadex(0,
|
||||
0, CThread::ThreadFunc, lpThread, 0, &nThreadID));
|
||||
|
||||
lpThread->SetHandle(hThread);
|
||||
return hThread;
|
||||
}
|
||||
|
||||
bool CThreadMgr::Stop(CThread* lpThread, unsigned long dwTimeout)
|
||||
{
|
||||
if(0 == lpThread)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE hThread = lpThread->GetHandle();
|
||||
if(INVALID_HANDLE_VALUE == hThread)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
lpThread->SetHandle(INVALID_HANDLE_VALUE);
|
||||
lpThread->End();
|
||||
WaitForSingleObject(hThread, dwTimeout);
|
||||
return (TRUE == CloseHandle(hThread));
|
||||
}
|
||||
61
Server/RylServerProject/BaseLibrary/Thread/ThreadMgr.h
Normal file
61
Server/RylServerProject/BaseLibrary/Thread/ThreadMgr.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef _CTHREADMGR_H_
|
||||
#define _CTHREADMGR_H_
|
||||
|
||||
#ifndef WINDOWS_LEAN_AND_MEAN
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "Lock.h"
|
||||
|
||||
// forward decl
|
||||
class CThread;
|
||||
|
||||
class CThreadMgr
|
||||
{
|
||||
public:
|
||||
|
||||
enum { MAX_THREAD_NUM = 63 };
|
||||
|
||||
CThreadMgr();
|
||||
virtual ~CThreadMgr();
|
||||
|
||||
bool RegisterAndRun(CThread* lpThread); // 스레드를 등록한다. 최대 63개까지 등록할 수 있다.
|
||||
bool JoinThread(); // 모든 스레드를 종료시킨다.
|
||||
|
||||
inline int GetNum()
|
||||
{
|
||||
return m_nThreadNum;
|
||||
}
|
||||
inline int GetMaxNum()
|
||||
{
|
||||
return MAX_THREAD_NUM;
|
||||
}
|
||||
|
||||
CThread* GetThread(int iPos)
|
||||
{
|
||||
return m_lpThreads[iPos];
|
||||
}
|
||||
|
||||
|
||||
// 매니저에 등록하지 않고, 그냥 실행 시킨다.
|
||||
static HANDLE Run(CThread* lpThread);
|
||||
static bool Stop(CThread* lpThread, unsigned long dwTimeout = INFINITE);
|
||||
|
||||
private:
|
||||
|
||||
typedef CCSLock ThreadLock;
|
||||
|
||||
CThread* m_lpThreads[MAX_THREAD_NUM];
|
||||
HANDLE m_hThreads[MAX_THREAD_NUM];
|
||||
|
||||
ThreadLock m_ThreadLock;
|
||||
|
||||
unsigned int m_nThreadNum;
|
||||
unsigned int m_bJoinStarted;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user