Browse Source

Merge pull request #172 from dpogue/kill_log

plStatusLog++; pnAcLog--
Adam Johnson 13 years ago
parent
commit
120dae6c2b
  1. 2
      Sources/Plasma/Apps/plClientPatcher/CMakeLists.txt
  2. 24
      Sources/Plasma/Apps/plClientPatcher/UruPlayer.cpp
  3. 1
      Sources/Plasma/Apps/plUruLauncher/CMakeLists.txt
  4. 17
      Sources/Plasma/Apps/plUruLauncher/SelfPatcher.cpp
  5. 15
      Sources/Plasma/CoreLib/hsThread.h
  6. 36
      Sources/Plasma/CoreLib/hsThread_Unix.cpp
  7. 36
      Sources/Plasma/CoreLib/hsThread_Win.cpp
  8. 3
      Sources/Plasma/CoreLib/hsUtils.h
  9. 1
      Sources/Plasma/NucleusLib/pnAsyncCore/CMakeLists.txt
  10. 168
      Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcIo.h
  11. 77
      Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.cpp
  12. 27
      Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.h
  13. 5
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt
  14. 39
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp
  15. 1010
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtFile.cpp
  16. 93
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h
  17. 10
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp
  18. 518
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp
  19. 55
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h
  20. 81
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/pnAceInt.h
  21. 173
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp
  22. 478
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp
  23. 13
      Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp
  24. 68
      Sources/Plasma/PubUtilLib/plStatusLog/plLoggable.cpp
  25. 4
      Sources/Plasma/PubUtilLib/plStatusLog/plLoggable.h
  26. 17
      Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.cpp
  27. 18
      Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h

2
Sources/Plasma/Apps/plClientPatcher/CMakeLists.txt

@ -18,7 +18,7 @@ set(plClientPatcher_SOURCES
)
add_library(plClientPatcher STATIC ${plClientPatcher_HEADERS} ${plClientPatcher_SOURCES})
target_link_libraries(plClientPatcher CoreLib plAudioCore)
target_link_libraries(plClientPatcher CoreLib plAudioCore plStatusLog)
source_group("Header Files" FILES ${plClientPatcher_HEADERS})
source_group("Source Files" FILES ${plClientPatcher_SOURCES})

24
Sources/Plasma/Apps/plClientPatcher/UruPlayer.cpp

@ -46,6 +46,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
***/
#include "Pch.h"
#include "plStatusLog/plStatusLog.h"
#pragma hdrstop
@ -215,11 +216,6 @@ static wchar_t s_clientExeName[] = L"plClient.exe";
*
***/
//============================================================================
static void LogHandler (ELogSeverity severity, const wchar_t msg[]) {
AsyncLogWriteMsg(L"UruPlayer", severity, msg);
}
//============================================================================
static void NetErrorHandler (ENetProtocol protocol, ENetError error) {
@ -247,7 +243,8 @@ static void NetErrorHandler (ENetProtocol protocol, ENetError error) {
break;
}
LogMsg(kLogError, L"NetErr: %s: %s", srv, NetErrorToString(error));
plString msg = plString::Format("NetErr: %S: %S", srv, NetErrorToString(error));
plStatusLog::AddLineS("patcher.log", msg.c_str());
// Notify GameTap something bad happened.
if (!s_patchError) {
@ -831,7 +828,9 @@ static void FileSrvIpAddressCallback (
NetCliGateKeeperDisconnect();
if (IS_NET_ERROR(result)) {
LogMsg(kLogDebug, L"FileSrvIpAddressRequest failed: %s", NetErrorToString(result));
plString msg = plString::Format("FileSrvIpAddressRequest failed: %S", NetErrorToString(result));
plStatusLog::AddLineS("patcher.log", msg.c_str());
s_patchError = true;
return;
}
@ -862,13 +861,14 @@ static void FileSrvIpAddressCallback (
void InitAsyncCore () {
if(AtomicAdd(&s_asyncCoreInitCount, 1) > 0)
return;
LogRegisterHandler(LogHandler);
AsyncCoreInitialize();
AsyncLogInitialize(L"Log", false);
wchar_t productString[256];
ProductString(productString, arrsize(productString));
LogMsg(kLogPerf, L"Patcher: %s", productString);
char* log = hsWStringToString(productString);
plStatusLog::AddLineS("patcher.log", log);
delete[] log;
}
//============================================================================
@ -880,9 +880,7 @@ void ShutdownAsyncCore () {
while (s_perf[kPerfThreadTaskCount])
AsyncSleep(10);
AsyncLogDestroy();
AsyncCoreDestroy(30 * 1000);
LogUnregisterHandler(LogHandler);
}
//============================================================================

1
Sources/Plasma/Apps/plUruLauncher/CMakeLists.txt

@ -43,6 +43,7 @@ target_link_libraries(plUruLauncher plNetClientComm)
target_link_libraries(plUruLauncher plNetGameLib)
target_link_libraries(plUruLauncher plNetMessage)
target_link_libraries(plUruLauncher plNetTransport)
target_link_libraries(plUruLauncher plStatusLog)
target_link_libraries(plUruLauncher plUnifiedTime)
target_link_libraries(plUruLauncher pnAsyncCore)
target_link_libraries(plUruLauncher pnAsyncCoreExe)

17
Sources/Plasma/Apps/plUruLauncher/SelfPatcher.cpp

@ -46,6 +46,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
***/
#include "Pch.h"
#include "plStatusLog/plStatusLog.h"
#pragma hdrstop
@ -87,7 +88,9 @@ static wchar_t s_newPatcherFile[MAX_PATH];
//============================================================================
static void NetErrorHandler (ENetProtocol protocol, ENetError error) {
LogMsg(kLogError, L"NetErr: %s", NetErrorToString(error));
plString msg = plString::Format("NetErr: %S", NetErrorToString(error));
plStatusLog::AddLineS("patcher.log", msg.c_str());
if (IS_NET_SUCCESS(s_patchResult))
s_patchResult = error;
s_downloadComplete = true;
@ -116,7 +119,9 @@ static void DownloadCallback (
break;
default:
LogMsg(kLogError, L"Error getting patcher file: %s", NetErrorToString(result));
plString msg = plString::Format("Error getting patcher file: %S", NetErrorToString(result));
plStatusLog::AddLineS("patcher.log", msg.c_str());
if (IS_NET_SUCCESS(s_patchResult))
s_patchResult = result;
break;
@ -161,7 +166,9 @@ static void ManifestCallback (
break;
default:
LogMsg(kLogError, L"Error getting patcher manifest: %s", NetErrorToString(result));
plString msg = plString::Format("Error getting patcher manifest: %S", NetErrorToString(result));
plStatusLog::AddLineS("patcher.log", msg.c_str());
if (IS_NET_SUCCESS(s_patchResult))
s_patchResult = result;
break;
@ -211,7 +218,9 @@ static void FileSrvIpAddressCallback (
NetCliGateKeeperDisconnect();
if (IS_NET_ERROR(result)) {
LogMsg(kLogDebug, L"FileSrvIpAddressRequest failed: %s", NetErrorToString(result));
plString msg = plString::Format("FileSrvIpAddressRequest failed: %S", NetErrorToString(result));
plStatusLog::AddLineS("patcher.log", msg.c_str());
s_patchResult = result;
s_downloadComplete = true;
}

15
Sources/Plasma/CoreLib/hsThread.h

@ -102,10 +102,6 @@ public:
static void* Alloc(size_t size); // does not call operator::new(), may return nil
static void Free(void* p); // does not call operator::delete()
static void ThreadYield();
#if HS_BUILD_FOR_WIN32
DWORD WinRun();
#endif
};
//////////////////////////////////////////////////////////////////////////////
@ -149,7 +145,8 @@ class hsSemaphore {
HANDLE fSemaH;
#elif HS_BUILD_FOR_UNIX
#ifdef USE_SEMA
sem_t fPSema;
sem_t* fPSema;
bool fNamed;
#else
pthread_mutex_t fPMutex;
pthread_cond_t fPCond;
@ -157,13 +154,9 @@ class hsSemaphore {
#endif
#endif
public:
#ifdef HS_BUILD_FOR_WIN32
hsSemaphore(int initialValue=0, const char *name=nil);
#else
hsSemaphore(int initialValue=0);
#endif
hsSemaphore(int initialValue=0, const char* name=nil);
~hsSemaphore();
hsBool Wait(hsMilliseconds timeToWait = kPosInfinity32);
void Signal();
};

36
Sources/Plasma/CoreLib/hsThread_Unix.cpp

@ -42,6 +42,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsThread.h"
#include "hsExceptions.h"
#include <sys/errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define NO_POSIX_CLOCK 1
@ -72,7 +74,7 @@ extern "C" {
static void* gEntryPoint(void* param)
{
pthread_mutex_lock(((hsThread*)param)->GetStartupMutex());
void* ret = (void*)((hsThread*)param)->Run();
void* ret = (void*)(uintptr_t)((hsThread*)param)->Run();
pthread_mutex_unlock(((hsThread*)param)->GetStartupMutex());
pthread_exit(ret);
return ret;
@ -266,12 +268,24 @@ void hsMutex::Unlock()
/////////////////////////////////////////////////////////////////////////////
hsSemaphore::hsSemaphore(int initialValue)
hsSemaphore::hsSemaphore(int initialValue, const char* name)
{
#ifdef USE_SEMA
int shared = 0; // 1 if sharing between processes
int status = ::sem_init(&fPSema, shared, initialValue);
hsThrowIfOSErr(status);
fPSema = nil;
if ((fNamed = (name != nil))) {
/* Named semaphore shared between processes */
fPSema = sem_open(name, O_CREAT, 0666, initialValue);
if (fPSema == SEM_FAILED)
{
hsAssert(0, "hsOSException");
throw hsOSException(errno);
}
} else {
/* Anonymous semaphore shared between threads */
int shared = 0; // 1 if sharing between processes
int status = sem_init(fPSema, shared, initialValue);
hsThrowIfOSErr(status);
}
#else
int status = ::pthread_mutex_init(&fPMutex, nil);
hsThrowIfOSErr(status);
@ -286,7 +300,12 @@ hsSemaphore::hsSemaphore(int initialValue)
hsSemaphore::~hsSemaphore()
{
#ifdef USE_SEMA
int status = ::sem_destroy(&fPSema);
int status = 0;
if (fNamed) {
status = sem_close(fPSema);
} else {
status = sem_destroy(fPSema);
}
hsThrowIfOSErr(status);
#else
int status = ::pthread_cond_destroy(&fPCond);
@ -300,8 +319,9 @@ hsSemaphore::~hsSemaphore()
hsBool hsSemaphore::Wait(hsMilliseconds timeToWait)
{
#ifdef USE_SEMA // SHOULDN'T THIS USE timeToWait??!?!? -rje
// shouldn't this use sem_timedwait? -dpogue (2012-03-04)
hsAssert( timeToWait==kPosInfinity32, "sem_t does not support wait with timeout. #undef USE_SEMA and recompile." );
int status = ::sem_wait(&fPSema);
int status = sem_wait(fPSema);
hsThrowIfOSErr(status);
return true;
#else
@ -351,7 +371,7 @@ EXIT:
void hsSemaphore::Signal()
{
#ifdef USE_SEMA
int status = ::sem_post(&fPSema);
int status = sem_post(fPSema);
hsThrowIfOSErr(status);
#else
int status = ::pthread_mutex_lock(&fPMutex);

36
Sources/Plasma/CoreLib/hsThread_Win.cpp

@ -46,16 +46,23 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsExceptions.h"
#include "hsMemory.h"
// typedef unsigned int __stdcall (*EntryPtCB)(void*);
static DWORD __stdcall gEntryPoint(void* param)
struct WinThreadParam
{
return ((hsThread*)param)->WinRun();
}
hsThread* fThread;
HANDLE fQuitSemaH; // private member of hsThread
WinThreadParam(hsThread* t, HANDLE quit)
: fThread(t), fQuitSemaH(quit)
{ }
};
static unsigned int __stdcall gEntryPointBT(void* param)
{
return ((hsThread*)param)->WinRun();
WinThreadParam* wtp = (WinThreadParam*)param;
unsigned int result = wtp->fThread->Run();
::ReleaseSemaphore(wtp->fQuitSemaH, 1, nil); // signal that we've quit
delete param;
return result;
}
hsThread::hsThread(uint32_t stackSize) : fStackSize(stackSize), fQuit(false), fThreadH(nil), fQuitSemaH(nil)
@ -74,12 +81,8 @@ void hsThread::Start()
fQuitSemaH = ::CreateSemaphore(nil, 0, kPosInfinity32, nil);
if (fQuitSemaH == nil)
throw hsOSException(-1);
#if 0
fThreadH = ::CreateThread(nil, fStackSize, gEntryPoint, this, 0, &fThreadId);
#else
fThreadH = (HANDLE)_beginthreadex(nil, fStackSize, gEntryPointBT, this, 0, (unsigned int*)&fThreadId);
#endif
WinThreadParam* wtp = new WinThreadParam(this, fQuitSemaH);
fThreadH = (HANDLE)_beginthreadex(nil, fStackSize, gEntryPointBT, wtp, 0, (unsigned int*)&fThreadId);
if (fThreadH == nil)
throw hsOSException(-1);
}
@ -100,15 +103,6 @@ void hsThread::Stop()
}
}
DWORD hsThread::WinRun()
{
DWORD result = this->Run();
::ReleaseSemaphore(fQuitSemaH, 1, nil); // signal that we've quit
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////
void* hsThread::Alloc(size_t size)

3
Sources/Plasma/CoreLib/hsUtils.h

@ -165,7 +165,8 @@ inline hsBool hsCompare(float a, float b, float delta=0.0001);
# define hsWFopen(name, mode) fopen(hsWStringToString(name), hsWStringToString(mode))
# define MAX_PATH 1024
# include <limits.h>
# define MAX_PATH PATH_MAX
#endif
// Useful floating point utilities

1
Sources/Plasma/NucleusLib/pnAsyncCore/CMakeLists.txt

@ -1,5 +1,6 @@
include_directories(../../CoreLib)
include_directories(../../NucleusLib)
include_directories(../../PubUtilLib)
set(pnAsyncCore_HEADERS
Pch.h

168
Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcIo.h

@ -64,174 +64,6 @@ typedef struct AsyncCancelIdStruct * AsyncCancelId;
const unsigned kAsyncSocketBufferSize = 1460;
enum EFileError {
kFileSuccess,
kFileErrorInvalidParameter,
kFileErrorFileNotFound,
kFileErrorPathNotFound,
kFileErrorAccessDenied,
kFileErrorSharingViolation,
kNumFileErrors
};
EFileError AsyncGetLastFileError ();
const wchar_t * FileErrorToString (EFileError error);
/****************************************************************************
*
* File notifications
*
***/
enum EAsyncNotifyFile {
kNotifyFileFlush,
kNotifyFileRead,
kNotifyFileWrite,
kNotifyFileSequence,
kNumFileNotifications
};
struct AsyncNotifyFile {
void * param;
AsyncId asyncId;
};
struct AsyncNotifyFileConnect : AsyncNotifyFile {
uint64_t fileSize;
uint64_t fileLastWriteTime;
};
struct AsyncNotifyFileFlush : AsyncNotifyFile {
EFileError error;
uint64_t truncateSize;
};
struct AsyncNotifyFileRead : AsyncNotifyFile {
uint64_t offset;
uint8_t * buffer;
unsigned bytes;
};
typedef AsyncNotifyFileRead AsyncNotifyFileWrite;
struct AsyncNotifyFileSequence : AsyncNotifyFile {
// no additional fields
};
typedef void (* FAsyncNotifyFileProc)(
AsyncFile file,
EAsyncNotifyFile code,
AsyncNotifyFile * notify,
void ** userState
);
/****************************************************************************
*
* File I/O functions
*
***/
// Desired access
const unsigned kAsyncFileReadAccess = 0x80000000;
const unsigned kAsyncFileWriteAccess = 0x40000000;
// Open mode (creation disposition)
const unsigned kAsyncFileModeCreateNew = 1;
const unsigned kAsyncFileModeCreateAlways = 2;
const unsigned kAsyncFileModeOpenExisting = 3;
const unsigned kAsyncFileModeOpenAlways = 4;
// Share mode flags
const unsigned kAsyncFileShareRead = 0x00000001;
const unsigned kAsyncFileShareWrite = 0x00000002;
AsyncFile AsyncFileOpen (
const wchar_t fullPath[],
FAsyncNotifyFileProc notifyProc,
EFileError * error,
unsigned desiredAccess,
unsigned openMode,
unsigned shareModeFlags, // optional
void * userState, // optional
uint64_t * fileSize, // optional
uint64_t * fileLastWriteTime // optional
);
// Use with AsyncFileDelete/AsyncFileFlushBuffers
const uint64_t kAsyncFileDontTruncate = (uint64_t) -1;
// This function may ONLY be called when there is no outstanding I/O against a file
// and no more I/O will be initiated against it. This function guarantees that it
// will close the system file handle before it returns to that another open against
// the same filename can succeed.
void AsyncFileClose (
AsyncFile file,
uint64_t truncateSize
);
void AsyncFileSetLastWriteTime (
AsyncFile file,
uint64_t lastWriteTime
);
uint64_t AsyncFileGetLastWriteTime (
const wchar_t fileName[]
);
// Truncation occurs atomically, any writes which occur after
// AsyncFileFlushBuffers will be queued until the truncation completes
AsyncId AsyncFileFlushBuffers (
AsyncFile file,
uint64_t truncateSize,
bool notify,
void * param
);
const unsigned kAsyncFileRwNotify = 1<<0;
const unsigned kAsyncFileRwSync = 1<<1;
AsyncId AsyncFileRead (
AsyncFile file,
uint64_t offset,
void * buffer,
unsigned bytes,
unsigned flags,
void * param
);
// Buffer must stay valid until I/O is completed
AsyncId AsyncFileWrite (
AsyncFile file,
uint64_t offset,
const void * buffer,
unsigned bytes,
unsigned flags,
void * param
);
// Inserts a "null operation" into the list of reads and writes. The callback
// will be called when all preceding operations have successfully completed.
AsyncId AsyncFileCreateSequence (
AsyncFile file,
bool notify,
void * param
);
enum EFileSeekFrom {
kFileSeekFromBegin,
kFileSeekFromCurrent,
kFileSeekFromEnd,
kNumFileSeekFroms
};
bool AsyncFileSeek (
AsyncFile file,
uint64_t distance,
EFileSeekFrom seekFrom
);
/****************************************************************************
*
* Socket connect packet

77
Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.cpp

@ -46,81 +46,15 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
***/
#include "../Pch.h"
#include "plStatusLog/plStatusLog.h"
#pragma hdrstop
/*****************************************************************************
*
* Private
*
***/
static const unsigned kMaxHandlers = 8;
static CCritSect s_critsect;
static FLogHandler s_asyncHandlers[kMaxHandlers];
/*****************************************************************************
*
* Internal functions
*
***/
//===========================================================================
static void Dispatch (ELogSeverity severity, const wchar_t msg[]) {
// Dispatch to default debug handler
char dbg[1024];
StrToAnsi(dbg, msg, arrsize(dbg));
DEBUG_MSG(dbg);
// We don't need to enter a critical section to read the handlers because they
// are atomically set and cleared
for (unsigned i = 0; i < arrsize(s_asyncHandlers); ++i) {
if (FLogHandler asyncHandler = s_asyncHandlers[i])
asyncHandler(severity, msg);
}
}
/*****************************************************************************
*
* Exports
*
***/
//===========================================================================
void LogRegisterHandler (FLogHandler callback) {
ASSERT(callback);
unsigned i;
s_critsect.Enter();
for (i = 0; i < arrsize(s_asyncHandlers); ++i) {
if (!s_asyncHandlers[i]) {
s_asyncHandlers[i] = callback;
break;
}
}
s_critsect.Leave();
#ifdef HS_DEBUGGING
if (i >= arrsize(s_asyncHandlers))
FATAL("Maximum number of log handlers exceeded.");
#endif
}
//===========================================================================
void LogUnregisterHandler (FLogHandler callback) {
s_critsect.Enter();
for (unsigned i = 0; i < arrsize(s_asyncHandlers); ++i) {
if (s_asyncHandlers[i] == callback) {
s_asyncHandlers[i] = nil;
break;
}
}
s_critsect.Leave();
}
//===========================================================================
void CDECL LogMsg (ELogSeverity severity, const char format[], ...) {
ASSERT(format);
@ -148,10 +82,7 @@ void LogMsgV (ELogSeverity severity, const char format[], va_list args) {
char msg[1024];
StrPrintfV(msg, arrsize(msg), format, args);
wchar_t uniMsg[1024];
StrToUnicode(uniMsg, msg, arrsize(uniMsg));
Dispatch(severity, uniMsg);
plStatusLog::AddLineS("OLD_ASYNC_LOG.log", msg);
}
//===========================================================================
@ -162,7 +93,9 @@ void LogMsgV (ELogSeverity severity, const wchar_t format[], va_list args) {
wchar_t msg[1024];
StrPrintfV(msg, arrsize(msg), format, args);
Dispatch(severity, msg);
char* to_log = hsWStringToString(msg);
plStatusLog::AddLineS("OLD_ASYNC_LOG.log", to_log);
delete[] to_log;
}
//============================================================================

27
Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.h

@ -81,33 +81,6 @@ void LogMsg (ELogSeverity severity, const wchar_t format[], ...);
void LogMsgV (ELogSeverity severity, const char format[], va_list args);
void LogMsgV (ELogSeverity severity, const wchar_t format[], va_list args);
void LogBreakOnErrors (bool breakOnErrors);
void AsyncLogInitialize (
const wchar_t logDirName[],
bool breakOnErrors
);
void AsyncLogDestroy ();
void AsyncLogFlush ();
void AsyncLogGetDirectory (wchar_t * dest, unsigned destChars);
// Low(er) level log API; call this from your LogHander function
// if you want to use the asynchronous log facility.
void AsyncLogWriteMsg (
const wchar_t facility[],
ELogSeverity severity,
const wchar_t msg[]
);
// FLogHandler must be capable of handling multiple threads and re-entrancy
typedef void (* FLogHandler) (ELogSeverity severity, const wchar_t msg[]);
void LogRegisterHandler (FLogHandler callback);
void LogUnregisterHandler (FLogHandler callback);
/****************************************************************************
*
* Debugging API

5
Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt

@ -4,7 +4,6 @@ include_directories(../../NucleusLib)
set(pnAsyncCoreExe_SOURCES
pnAceCore.cpp
pnAceIo.cpp
pnAceLog.cpp
pnAceThread.cpp
pnAceTimer.cpp
)
@ -23,7 +22,6 @@ set(pnAysncCoreExe_PRIVATE
set(pnAysncCoreExe_PRIVATE_NT
Private/Nt/pnAceNt.cpp
Private/Nt/pnAceNt.h
Private/Nt/pnAceNtFile.cpp
Private/Nt/pnAceNtInt.h
Private/Nt/pnAceNtSocket.cpp
Private/Nt/pnAceNtThread.cpp
@ -36,7 +34,6 @@ set(pnAsyncCoreExe_PRIVATE_UNIX
set(pnAsyncCoreExe_PRIVATE_W9X
Private/W9x/pnAceW9x.cpp
Private/W9x/pnAceW9x.h
Private/W9x/pnAceW9xFile.cpp
Private/W9x/pnAceW9xInt.h
Private/W9x/pnAceW9xSocket.cpp
Private/W9x/pnAceW9xThread.cpp
@ -61,4 +58,4 @@ source_group("Private" FILES ${pnAsyncCoreExe_PRIVATE})
source_group("Private\\Nt" FILES ${pnAysncCoreExe_PRIVATE_NT})
source_group("Private\\Unix" FILES ${pnAsyncCoreExe_PRIVATE_UNIX})
source_group("Private\\W9x" FILES ${pnAsyncCoreExe_PRIVATE_W9X})
source_group("Private\\Win32" FILES ${pnAsyncCoreExe_PRIVATE_WIN32})
source_group("Private\\Win32" FILES ${pnAsyncCoreExe_PRIVATE_WIN32})

39
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp

@ -152,28 +152,6 @@ static void INtOpDispatch (
INtSocketOpCompleteSocketWrite((NtSock *) ntObj, (NtOpSocketWrite *) op);
break;
case kOpQueuedFileRead:
case kOpQueuedFileWrite:
INtFileOpCompleteQueuedReadWrite((NtFile *) ntObj, (NtOpFileReadWrite *) op);
// operation converted into kOpFileWrite so we cannot move
// to next operation until write operation completes
return;
case kOpFileRead:
case kOpFileWrite:
ASSERT(bytes != (uint32_t) -1);
if (!INtFileOpCompleteReadWrite((NtFile *) ntObj, (NtOpFileReadWrite *) op, bytes))
return;
break;
case kOpFileFlush:
INtFileOpCompleteFileFlush((NtFile *) ntObj, (NtOpFileFlush *) op);
break;
case kOpSequence:
INtFileOpCompleteSequence((NtFile *) ntObj, (NtOpFileSequence *) op);
break;
DEFAULT_FATAL(opType);
}
@ -329,10 +307,6 @@ void INtConnCompleteOperation (NtObject * ntObj) {
DWORD err = GetLastError();
switch (ntObj->ioType) {
case kNtFile:
INtFileDelete((NtFile *) ntObj);
break;
case kNtSocket:
INtSockDelete((NtSock *) ntObj);
break;
@ -393,7 +367,6 @@ void NtInitialize () {
);
}
INtFileInitialize();
INtSocketInitialize();
}
@ -403,7 +376,6 @@ void NtInitialize () {
// shut down the program is to simply let the atexit() handler take care of it.
void NtDestroy (unsigned exitThreadWaitMs) {
// cleanup modules that post completion notifications as part of their shutdown
INtFileStartCleanup();
INtSocketStartCleanup(exitThreadWaitMs);
// cleanup worker threads
@ -434,7 +406,6 @@ void NtDestroy (unsigned exitThreadWaitMs) {
s_waitEvent = 0;
}
INtFileDestroy();
INtSocketDestroy();
}
@ -466,16 +437,6 @@ void NtGetApi (AsyncApi * api) {
api->waitForShutdown = NtWaitForShutdown;
api->sleep = NtSleep;
api->fileOpen = NtFileOpen;
api->fileClose = NtFileClose;
api->fileRead = NtFileRead;
api->fileWrite = NtFileWrite;
api->fileFlushBuffers = NtFileFlushBuffers;
api->fileSetLastWriteTime = NtFileSetLastWriteTime;
api->fileGetLastWriteTime = NtFileGetLastWriteTime;
api->fileCreateSequence = NtFileCreateSequence;
api->fileSeek = NtFileSeek;
api->socketConnect = NtSocketConnect;
api->socketConnectCancel = NtSocketConnectCancel;
api->socketDisconnect = NtSocketDisconnect;

1010
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtFile.cpp

File diff suppressed because it is too large Load Diff

93
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h

@ -142,45 +142,6 @@ bool INtConnInitialize (NtObject * ntObj);
void INtConnCompleteOperation (NtObject * ntObj);
/*****************************************************************************
*
* NtFile.cpp internal functions
*
***/
struct NtFile;
struct NtOpFileFlush;
struct NtOpFileReadWrite;
struct NtOpFileSequence;
void INtFileInitialize ();
void INtFileStartCleanup ();
void INtFileDestroy ();
void INtFileDelete (
NtFile * file
);
bool INtFileOpCompleteReadWrite (
NtFile * ioConn,
NtOpFileReadWrite * op,
unsigned bytes
);
void INtFileOpCompleteQueuedReadWrite (
NtFile * ioConn,
NtOpFileReadWrite * op
);
void INtFileOpCompleteFileFlush (
NtFile * ioConn,
NtOpFileFlush * op
);
void INtFileOpCompleteSequence (
NtFile * ioConn,
NtOpFileSequence * op
);
void INtFileStartCleanup ();
/*****************************************************************************
*
@ -228,60 +189,6 @@ void NtDestroy (unsigned exitThreadWaitMs);
void NtSignalShutdown ();
void NtWaitForShutdown ();
void NtSleep (unsigned sleepMs);
AsyncFile NtFileOpen (
const wchar_t fullPath[],
FAsyncNotifyFileProc notifyProc,
EFileError * error,
unsigned desiredAccess,
unsigned openMode,
unsigned shareModeFlags,
void * userState,
uint64_t * fileSize,
uint64_t * fileLastWriteTime
);
void NtFileClose (
AsyncFile file,
uint64_t truncateSize
);
void NtFileSetLastWriteTime (
AsyncFile file,
uint64_t lastWriteTime
);
uint64_t NtFileGetLastWriteTime (
const wchar_t fileName[]
);
AsyncId NtFileFlushBuffers (
AsyncFile file,
uint64_t truncateSize,
bool notify,
void * param
);
AsyncId NtFileRead (
AsyncFile file,
uint64_t offset,
void * buffer,
unsigned bytes,
unsigned flags,
void * param
);
AsyncId NtFileWrite (
AsyncFile file,
uint64_t offset,
const void *buffer,
unsigned bytes,
unsigned flags,
void * param
);
AsyncId NtFileCreateSequence (
AsyncFile file,
bool notify,
void * param
);
bool NtFileSeek (
AsyncFile file,
uint64_t distance,
EFileSeekFrom from
);
void NtSocketConnect (
AsyncCancelId * cancelId,
const NetAddress & netAddr,

10
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp

@ -67,16 +67,6 @@ void W9xGetApi (AsyncApi * api) {
api->waitForShutdown = W9xThreadWaitForShutdown;
api->sleep = W9xThreadSleep;
api->fileOpen = W9xFileOpen;
api->fileClose = W9xFileClose;
api->fileRead = W9xFileRead;
api->fileWrite = W9xFileWrite;
api->fileFlushBuffers = W9xFileFlushBuffers;
api->fileSetLastWriteTime = W9xFileSetLastWriteTime;
api->fileGetLastWriteTime = W9xFileGetLastWriteTime;
api->fileCreateSequence = W9xFileCreateSequence;
api->fileSeek = W9xFileSeek;
api->socketConnect = W9xSocketConnect;
api->socketConnectCancel = W9xSocketConnectCancel;
api->socketDisconnect = W9xSocketDisconnect;

518
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp

@ -1,518 +0,0 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
/*****************************************************************************
*
* $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp
*
***/
#include "../../Pch.h"
#pragma hdrstop
#include "pnAceW9xInt.h"
namespace W9x {
/****************************************************************************
*
* FileOp
*
***/
struct FileOp {
EAsyncNotifyFile code;
bool notify;
union {
AsyncNotifyFileFlush flush;
AsyncNotifyFileRead read;
AsyncNotifyFileSequence sequence;
AsyncNotifyFileWrite write;
} data;
};
/****************************************************************************
*
* CFile
*
***/
class CFile : public CThreadDispObject {
private:
CCritSect m_critSect;
HANDLE m_handle;
FAsyncNotifyFileProc m_notifyProc;
void * m_userState;
protected:
void Complete (void * op, CCritSect * critSect, AsyncId asyncId);
void Delete (void * op);
public:
CFile (
HANDLE handle,
FAsyncNotifyFileProc notifyProc,
void * userState
);
~CFile ();
void Read (
uint64_t offset,
void * buffer,
unsigned bytes
);
void SetLastWriteTime (uint64_t lastWriteTime);
void Truncate (uint64_t size);
void Write (
uint64_t offset,
const void * buffer,
unsigned bytes
);
bool Seek (uint64_t offset, EFileSeekFrom from);
};
//===========================================================================
CFile::CFile (
HANDLE handle,
FAsyncNotifyFileProc notifyProc,
void * userState
) :
m_handle(handle),
m_notifyProc(notifyProc),
m_userState(userState)
{
}
//===========================================================================
CFile::~CFile () {
CloseHandle(m_handle);
m_handle = INVALID_HANDLE_VALUE;
}
//===========================================================================
void CFile::Complete (void * op, CCritSect * critSect, AsyncId asyncId) {
FileOp * fileOp = (FileOp *)op;
// Enter our local critical section and leave the global one
m_critSect.Enter();
critSect->Leave();
// Complete the operation
switch (fileOp->code) {
case kNotifyFileFlush: {
if (fileOp->data.flush.truncateSize != kAsyncFileDontTruncate)
Truncate(fileOp->data.flush.truncateSize);
BOOL result = FlushFileBuffers(m_handle);
fileOp->data.flush.error = result ? kFileSuccess : AsyncGetLastFileError();
}
break;
case kNotifyFileRead:
Read(
fileOp->data.read.offset,
fileOp->data.read.buffer,
fileOp->data.read.bytes
);
break;
case kNotifyFileWrite:
Write(
fileOp->data.write.offset,
fileOp->data.write.buffer,
fileOp->data.write.bytes
);
break;
}
// Leave our local critical section
m_critSect.Leave();
// Dispatch a completion notification
if (fileOp->notify) {
fileOp->data.flush.asyncId = asyncId;
m_notifyProc(
(AsyncFile)this,
fileOp->code,
&fileOp->data.flush,
&m_userState
);
}
}
//===========================================================================
void CFile::Delete (void * op) {
FileOp * fileOp = (FileOp *)op;
delete fileOp;
}
//===========================================================================
void CFile::Read (
uint64_t offset,
void * buffer,
unsigned bytes
) {
// Seek to the start of the read
Seek(offset, kFileSeekFromBegin);
// Perform the read
DWORD bytesRead;
BOOL result = ReadFile(
m_handle,
buffer,
bytes,
&bytesRead,
nil // overlapped
);
// Handle errors
if (bytesRead != bytes)
memset((uint8_t *)buffer + bytesRead, 0, bytes - bytesRead);
if ( (!result && (GetLastError() != ERROR_IO_PENDING)) ||
(bytesRead != bytes) )
LogMsg(kLogFatal, "failed: ReadFile");
}
//===========================================================================
bool CFile::Seek (uint64_t offset, EFileSeekFrom from) {
COMPILER_ASSERT(kFileSeekFromBegin == FILE_BEGIN);
COMPILER_ASSERT(kFileSeekFromCurrent == FILE_CURRENT);
COMPILER_ASSERT(kFileSeekFromEnd == FILE_END);
LONG low = (LONG)(offset % 0x100000000ul);
LONG high = (LONG)(offset / 0x100000000ul);
uint32_t result = SetFilePointer(m_handle, low, &high, from);
if ((result == (uint32_t)-1) && (GetLastError() != NO_ERROR)) {
LogMsg(kLogFatal, "failed: SetFilePointer");
return false;
}
else
return true;
}
//===========================================================================
void CFile::SetLastWriteTime (uint64_t lastWriteTime) {
COMPILER_ASSERT(sizeof(lastWriteTime) == sizeof(FILETIME));
SetFileTime(m_handle, nil, nil, (const FILETIME *)&lastWriteTime);
}
//===========================================================================
void CFile::Truncate (uint64_t size) {
ASSERT(size != kAsyncFileDontTruncate);
if (Seek(size, kFileSeekFromBegin) && !SetEndOfFile(m_handle))
LogMsg(kLogFatal, "failed: SetEndOfFile");
}
//===========================================================================
void CFile::Write (
uint64_t offset,
const void * buffer,
unsigned bytes
) {
// Seek to the start of the write
Seek(offset, kFileSeekFromBegin);
// Perform the write
DWORD bytesWritten;
BOOL result = WriteFile(
m_handle,
buffer,
bytes,
&bytesWritten,
nil // overlapped
);
// Handle errors
if ( (!result && (GetLastError() != ERROR_IO_PENDING)) ||
(bytesWritten != bytes) ) {
LogMsg(kLogFatal, "failed: WriteFile");
if (!result && (GetLastError() == ERROR_DISK_FULL)) {
MessageBox(nil, "Disk full!", "Error", MB_ICONSTOP | MB_SYSTEMMODAL);
// DebugDisableLeakChecking();
ExitProcess(1);
}
}
}
/****************************************************************************
*
* Exported functions
*
***/
//===========================================================================
void W9xFileClose (
AsyncFile file,
uint64_t truncateSize
) {
// Dereference the object
CFile * object = (CFile *)file;
// If requested, truncate the file
if (truncateSize != kAsyncFileDontTruncate)
object->Truncate(truncateSize);
// Close the file object
object->Close();
}
//===========================================================================
AsyncId W9xFileCreateSequence (
AsyncFile file,
bool notify,
void * param
) {
// Dereference the object
CFile * object = (CFile *)file;
// Queue an operation
FileOp * op = new FileOp;
op->code = kNotifyFileSequence;
op->notify = notify;
op->data.flush.param = param;
return object->Queue(op);
}
//===========================================================================
AsyncId W9xFileFlushBuffers (
AsyncFile file,
uint64_t truncateSize,
bool notify,
void * param
) {
// Dereference the object
CFile * object = (CFile *)file;
// Queue an operation
FileOp * op = new FileOp;
op->code = kNotifyFileFlush;
op->notify = notify;
op->data.flush.param = param;
op->data.flush.truncateSize = truncateSize;
// op->data.flush.error filled in upon completion
return object->Queue(op);
}
//===========================================================================
AsyncFile W9xFileOpen (
const wchar_t fullPath[],
FAsyncNotifyFileProc notifyProc,
EFileError * error,
unsigned desiredAccess,
unsigned openMode,
unsigned shareModeFlags,
void * userState,
uint64_t * fileSize,
uint64_t * fileLastWriteTime
) {
HANDLE fileHandle = CreateFileW(
fullPath,
desiredAccess,
shareModeFlags,
nil, // plSecurityAttributes
openMode,
0, // attributeFlags
nil // hTemplateFile
);
*error = AsyncGetLastFileError();
if (INVALID_HANDLE_VALUE == fileHandle)
return nil;
// don't allow users to open devices like "LPT1", etc.
if (GetFileType(fileHandle) != FILE_TYPE_DISK) {
LogMsg(kLogFatal, "failed: !FILE_TYPE_DISK");
*error = kFileErrorFileNotFound;
CloseHandle(fileHandle);
return nil;
}
// Get the file size
DWORD sizeHi, sizeLo = GetFileSize(fileHandle, &sizeHi);
if ((sizeLo == (DWORD) -1) && (NO_ERROR != GetLastError())) {
*error = AsyncGetLastFileError();
LogMsg(kLogFatal, "failed: GetFileSize");
CloseHandle(fileHandle);
return nil;
}
const uint64_t size = ((uint64_t) sizeHi << (uint64_t) 32) | (uint64_t) sizeLo;
uint64_t lastWriteTime;
ASSERT(sizeof(lastWriteTime) >= sizeof(FILETIME));
GetFileTime(fileHandle, nil, nil, (FILETIME *) &lastWriteTime);
// Create a file object
CFile * object = new CFile(
fileHandle,
notifyProc,
userState
);
// return out parameters
if (fileSize)
*fileSize = size;
if (fileLastWriteTime)
*fileLastWriteTime = lastWriteTime;
return (AsyncFile)object;
}
//===========================================================================
AsyncId W9xFileRead (
AsyncFile file,
uint64_t offset,
void * buffer,
unsigned bytes,
unsigned flags,
void * param
) {
// Dereference the object
CFile * object = (CFile *)file;
// Perform synchronous operations immediately
if (flags & kAsyncFileRwSync) {
object->Read(offset, buffer, bytes);
return 0;
}
// Queue asynchronous operations
else {
FileOp * op = new FileOp;
op->code = kNotifyFileRead;
op->notify = (flags & kAsyncFileRwNotify) != 0;
op->data.read.param = param;
op->data.read.offset = offset;
op->data.read.buffer = (uint8_t *)buffer;
op->data.read.bytes = bytes;
return object->Queue(op);
}
}
//===========================================================================
void W9xFileSetLastWriteTime (
AsyncFile file,
uint64_t lastWriteTime
) {
// Dereference the object
CFile * object = (CFile *)file;
// Set the file time
object->SetLastWriteTime(lastWriteTime);
}
//===========================================================================
uint64_t W9xFileGetLastWriteTime (
const wchar_t fileName[]
) {
WIN32_FILE_ATTRIBUTE_DATA info;
bool f = GetFileAttributesExW(fileName, GetFileExInfoStandard, &info);
return f ? *((uint64_t *) &info.ftLastWriteTime) : 0;
}
//===========================================================================
AsyncId W9xFileWrite (
AsyncFile file,
uint64_t offset,
const void * buffer,
unsigned bytes,
unsigned flags,
void * param
) {
// Dereference the object
CFile * object = (CFile *)file;
// Perform synchronous operations immediately
if (flags & kAsyncFileRwSync) {
object->Write(offset, buffer, bytes);
return 0;
}
// Queue asynchronous operations
else {
FileOp * op = new FileOp;
op->code = kNotifyFileWrite;
op->notify = (flags & kAsyncFileRwNotify) != 0;
op->data.write.param = param;
op->data.write.offset = offset;
op->data.write.buffer = (uint8_t *)buffer;
op->data.write.bytes = bytes;
return object->Queue(op);
}
}
//============================================================================
bool W9xFileSeek (
AsyncFile file,
uint64_t distance,
EFileSeekFrom from
) {
CFile * object = (CFile *)file;
return object->Seek(distance, from);
}
} // namespace W9x

55
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h

@ -86,61 +86,6 @@ bool W9xThreadWaitId (
AsyncId asyncId,
unsigned timeoutMs
);
AsyncFile W9xFileOpen (
const wchar_t fullPath[],
FAsyncNotifyFileProc notifyProc,
EFileError * error,
unsigned desiredAccess,
unsigned openMode,
unsigned shareModeFlags,
void * userState,
uint64_t * fileSize,
uint64_t * fileLastWriteTime
);
void W9xFileClose (
AsyncFile file,
uint64_t truncateSize
);
void W9xFileSetLastWriteTime (
AsyncFile file,
uint64_t lastWriteTime
);
uint64_t W9xFileGetLastWriteTime (
const wchar_t fileName[]
);
AsyncId W9xFileFlushBuffers (
AsyncFile file,
uint64_t truncateSize,
bool notify,
void * param
);
AsyncId W9xFileRead (
AsyncFile file,
uint64_t offset,
void * buffer,
unsigned bytes,
unsigned flags,
void * param
);
AsyncId W9xFileWrite (
AsyncFile file,
uint64_t offset,
const void *buffer,
unsigned bytes,
unsigned flags,
void * param
);
AsyncId W9xFileCreateSequence (
AsyncFile file,
bool notify,
void * param
);
bool W9xFileSeek (
AsyncFile file,
uint64_t distance,
EFileSeekFrom from
);
void W9xSocketConnect (
AsyncCancelId * cancelId,
const NetAddress & netAddr,

81
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/pnAceInt.h

@ -103,76 +103,6 @@ typedef void (* FSignalShutdown) ();
typedef void (* FWaitForShutdown) ();
typedef void (* FSleep) (unsigned sleepMs);
// Files
typedef AsyncFile (* FAsyncFileOpen) (
const wchar_t fullPath[],
FAsyncNotifyFileProc notifyProc,
EFileError * error,
unsigned desiredAccess,
unsigned openMode,
unsigned shareModeFlags,
void * userState,
uint64_t * fileSize,
uint64_t * fileLastWriteTime
);
typedef void (* FAsyncFileClose) (
AsyncFile file,
uint64_t truncateSize
);
typedef void (* FAsyncFileSetLastWriteTime) (
AsyncFile file,
uint64_t lastWriteTime
);
typedef uint64_t (* FAsyncFileGetLastWriteTime) (
const wchar_t fileName[]
);
typedef AsyncId (* FAsyncFileFlushBuffers) (
AsyncFile file,
uint64_t truncateSize,
bool notify,
void * param
);
typedef AsyncId (* FAsyncFileRead) (
AsyncFile file,
uint64_t offset,
void * buffer,
unsigned bytes,
unsigned flags,
void * param
);
typedef AsyncId (* FAsyncFileWrite) (
AsyncFile file,
uint64_t offset,
const void * buffer,
unsigned bytes,
unsigned flags,
void * param
);
typedef AsyncId (* FAsyncFileCreateSequence) (
AsyncFile file,
bool notify,
void * param
);
typedef bool (* FAsyncFileSeek) (
AsyncFile file,
uint64_t distance,
EFileSeekFrom from
);
typedef bool (* FAsyncFileWaitId) (
AsyncFile file,
AsyncId asyncId,
unsigned timeoutMs
);
// Sockets
typedef void (* FAsyncSocketConnect) (
AsyncCancelId * cancelId,
@ -252,17 +182,6 @@ struct AsyncApi {
FWaitForShutdown waitForShutdown;
FSleep sleep;
// Files
FAsyncFileOpen fileOpen;
FAsyncFileClose fileClose;
FAsyncFileRead fileRead;
FAsyncFileWrite fileWrite;
FAsyncFileFlushBuffers fileFlushBuffers;
FAsyncFileSetLastWriteTime fileSetLastWriteTime;
FAsyncFileGetLastWriteTime fileGetLastWriteTime;
FAsyncFileCreateSequence fileCreateSequence;
FAsyncFileSeek fileSeek;
// Sockets
FAsyncSocketConnect socketConnect;
FAsyncSocketConnectCancel socketConnectCancel;

173
Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp

@ -203,179 +203,6 @@ static unsigned GetConnHash (
*
***/
//===========================================================================
EFileError AsyncGetLastFileError () {
const unsigned error = GetLastError();
switch (error) {
case NO_ERROR:
return kFileSuccess;
case ERROR_FILE_NOT_FOUND:
return kFileErrorFileNotFound;
case ERROR_ACCESS_DENIED:
case ERROR_FILE_EXISTS:
case ERROR_ALREADY_EXISTS:
return kFileErrorAccessDenied;
case ERROR_SHARING_VIOLATION:
return kFileErrorSharingViolation;
case ERROR_BAD_NETPATH:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_NAME:
case ERROR_BAD_NET_NAME:
case ERROR_CANT_ACCESS_DOMAIN_INFO:
case ERROR_NETWORK_UNREACHABLE:
case ERROR_HOST_UNREACHABLE:
return kFileErrorPathNotFound;
}
LogMsg(kLogPerf, "Unexpected Win32 error [%#x]", error);
return kFileErrorPathNotFound;
}
//============================================================================
const wchar_t * FileErrorToString (EFileError error) {
static wchar_t * s_fileErrorStrings[] = {
L"FileSuccess",
L"FileErrorInvalidParameter",
L"FileErrorFileNotFound",
L"FileErrorPathNotFound",
L"FileErrorAccessDenied",
L"FileErrorSharingViolation",
};
COMPILER_ASSERT(kNumFileErrors == arrsize(s_fileErrorStrings));
return s_fileErrorStrings[error];
}
//============================================================================
AsyncFile AsyncFileOpen (
const wchar_t fullPath[],
FAsyncNotifyFileProc notifyProc,
EFileError * error,
unsigned desiredAccess,
unsigned openMode,
unsigned shareModeFlags,
void * userState,
uint64_t * fileSize,
uint64_t * fileLastWriteTime
) {
ASSERT(g_api.fileOpen);
return g_api.fileOpen(
fullPath,
notifyProc,
error,
desiredAccess,
openMode,
shareModeFlags,
userState,
fileSize,
fileLastWriteTime
);
}
//============================================================================
void AsyncFileClose (
AsyncFile file,
uint64_t truncateSize
) {
ASSERT(g_api.fileClose);
g_api.fileClose(file, truncateSize);
}
//============================================================================
void AsyncFileSetLastWriteTime (
AsyncFile file,
uint64_t lastWriteTime
) {
ASSERT(g_api.fileSetLastWriteTime);
g_api.fileSetLastWriteTime(file, lastWriteTime);
}
//============================================================================
uint64_t AsyncFileGetLastWriteTime (
const wchar_t fileName[]
) {
ASSERT(g_api.fileGetLastWriteTime);
return g_api.fileGetLastWriteTime(fileName);
}
//============================================================================
AsyncId AsyncFileFlushBuffers (
AsyncFile file,
uint64_t truncateSize,
bool notify,
void * param
) {
ASSERT(g_api.fileFlushBuffers);
return g_api.fileFlushBuffers(file, truncateSize, notify, param);
}
//============================================================================
AsyncId AsyncFileRead (
AsyncFile file,
uint64_t offset,
void * buffer,
unsigned bytes,
unsigned flags,
void * param
) {
ASSERT(g_api.fileRead);
return g_api.fileRead(
file,
offset,
buffer,
bytes,
flags,
param
);
}
//============================================================================
AsyncId AsyncFileWrite (
AsyncFile file,
uint64_t offset,
const void * buffer,
unsigned bytes,
unsigned flags,
void * param
) {
ASSERT(g_api.fileWrite);
return g_api.fileWrite(
file,
offset,
buffer,
bytes,
flags,
param
);
}
//============================================================================
AsyncId AsyncFileCreateSequence (
AsyncFile file,
bool notify,
void * param
) {
ASSERT(g_api.fileCreateSequence);
return g_api.fileCreateSequence(file, notify, param);
}
//============================================================================
bool AsyncFileSeek (
AsyncFile file,
uint64_t distance,
EFileSeekFrom seekFrom
) {
ASSERT(g_api.fileSeek);
return g_api.fileSeek(file, distance, seekFrom);
}
//===========================================================================
void AsyncSocketConnect (
AsyncCancelId * cancelId,

478
Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp

@ -1,478 +0,0 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
/*****************************************************************************
*
* $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp
*
***/
#include "Pch.h"
#pragma hdrstop
#if defined(PLASMA_EXTERNAL_RELEASE)
// If this is an external build then don't write log files
#define ACELOG_NO_LOG_FILES
#endif
namespace AsyncLog {
/****************************************************************************
*
* Private
*
***/
static const unsigned kLogFlushMs = 10 * 1000;
enum ELogType {
#ifdef SERVER
kLogTypeDebug,
kLogTypePerf,
kLogTypeError,
#else
kLogTypeDebug,
#endif
kNumLogTypes
};
static bool s_breakOnErrors;
static wchar_t s_directory[MAX_PATH];
static CCritSect s_logCrit[kNumLogTypes];
static char * s_logBuf[kNumLogTypes];
static unsigned s_logPos[kNumLogTypes];
static uint64_t s_logWritePos[kNumLogTypes];
static TimeDesc s_logTime[kNumLogTypes];
static unsigned s_logWriteMs[kNumLogTypes];
static AsyncFile s_logFile[kNumLogTypes];
static long s_opsPending;
static bool s_running;
static AsyncTimer * s_timer;
static unsigned s_logSize[kNumLogTypes] = {
#ifdef SERVER
64 * 1024,
64 * 1024,
8 * 1024,
#else
64 * 1024,
#endif
};
static const wchar_t * s_logNameFmt[kNumLogTypes] = {
#ifdef SERVER
L"Dbg%02u%02u%02u.log",
L"Inf%02u%02u%02u.log",
L"Err%02u%02u%02u.log",
#else
L"%s%02u%02u%02u.log",
#endif
};
static ELogType s_logSeverityToType[kNumLogSeverity] = {
#ifdef SERVER
kLogTypeDebug, // kLogDebug
kLogTypePerf, // kLogPerf
kLogTypeError, // kLogError
kLogTypeError, // kLogFatal
#else
kLogTypeDebug, // kLogDebug
kLogTypeDebug, // kLogPerf
kLogTypeDebug, // kLogError
kLogTypeDebug, // kLogFatal
#endif
};
static char * s_logSeverityToText[kNumLogSeverity] = {
"Debug",
"Info",
"Error",
"Fatal",
};
/****************************************************************************
*
* Local functions
*
***/
//============================================================================
static void LogFileNotifyProc (
AsyncFile file,
EAsyncNotifyFile code,
AsyncNotifyFile * notify,
void ** userState
) {
switch (code) {
case kNotifyFileWrite:
free(notify->param);
AtomicAdd(&s_opsPending, -1);
break;
case kNotifyFileFlush:
AsyncFileClose(file, kAsyncFileDontTruncate);
AtomicAdd(&s_opsPending, -1);
break;
DEFAULT_FATAL(code);
}
}
//============================================================================
static void AllocLogBuffer_CS (unsigned index) {
ASSERT(!s_logBuf[index]);
s_logBuf[index] = (char *)malloc(s_logSize[index]);
s_logPos[index] = 0;
if (!s_logBuf[index])
ErrorAssert(__LINE__, __FILE__, "Out of memory");
}
//============================================================================
static void FreeLogBuffer_CS (unsigned index) {
if (s_logBuf[index]) {
free(s_logBuf[index]);
s_logBuf[index] = nil;
}
}
//============================================================================
static void GetLogFilename (
unsigned index,
TimeDesc timeDesc,
wchar_t * filename,
unsigned chars
) {
StrPrintf(
filename,
chars,
s_logNameFmt[index],
#ifndef SERVER
ProductShortName(),
#endif
timeDesc.year % 100,
timeDesc.month,
timeDesc.day
);
PathAddFilename(filename, s_directory, filename, chars);
}
//============================================================================
static bool OpenLogFile_CS (unsigned index) {
if (s_logFile[index] != nil)
return true;
// Build filename
wchar_t filename[MAX_PATH];
GetLogFilename(
index,
s_logTime[index],
filename,
arrsize(filename)
);
// Open file
uint64_t fileTime;
EFileError fileError;
bool fileExist = PathDoesFileExist(filename);
s_logFile[index] = AsyncFileOpen(
filename,
LogFileNotifyProc,
&fileError,
kAsyncFileWriteAccess,
kAsyncFileModeOpenAlways,
kAsyncFileShareRead,
nil, // userState
&s_logWritePos[index],
&fileTime
);
if (s_logFile[index] == nil)
return false;
TimeGetDesc(fileTime, &s_logTime[index]);
s_logWriteMs[index] = TimeGetMs();
// Seek to end of file
AsyncFileSeek(s_logFile[index], s_logWritePos[index], kFileSeekFromBegin);
// If this is a new file, write uint8_t Order Mark
if (!fileExist) {
static const char s_bom[] = "\xEF\xBB\xBF";
AsyncFileWrite(
s_logFile[index],
s_logWritePos[index],
s_bom,
arrsize(s_bom)- 1,
kAsyncFileRwSync, // perform blocking write
nil // param
);
s_logWritePos[index] += arrsize(s_bom) - 1;
}
// Write a sentinel in case there are multiple runs in one day
static const char s_logOpened[] = "Log Opened\r\n";
AsyncFileWrite(
s_logFile[index],
s_logWritePos[index],
s_logOpened,
arrsize(s_logOpened)- 1,
kAsyncFileRwSync, // perform blocking write
nil
);
s_logWritePos[index] += arrsize(s_logOpened) - 1;
return true;
}
//============================================================================
static void WriteLogFile_CS (unsigned index, bool close) {
unsigned flags = kAsyncFileRwSync; // kAsyncFileRwNotify
if (s_logPos[index]) {
if (OpenLogFile_CS(index)) {
AsyncFileWrite(
s_logFile[index],
s_logWritePos[index],
s_logBuf[index],
s_logPos[index],
flags,
s_logBuf[index]
);
if (flags == kAsyncFileRwSync)
delete s_logBuf[index];
else
AtomicAdd(&s_opsPending, 1);
s_logWritePos[index] += s_logPos[index];
s_logWriteMs[index] = TimeGetMs();
s_logBuf[index] = nil;
s_logPos[index] = 0;
}
}
if (close && s_logFile[index]) {
if (flags == kAsyncFileRwNotify) {
AtomicAdd(&s_opsPending, 1);
AsyncFileFlushBuffers(
s_logFile[index],
kAsyncFileDontTruncate,
true,
nil
);
}
else {
AsyncFileClose(
s_logFile[index],
kAsyncFileDontTruncate
);
}
s_logFile[index] = nil;
}
}
//============================================================================
static void FlushLogFile_CS (
unsigned index,
TimeDesc timeDesc
) {
bool close = !s_running || (s_logTime[index].day != timeDesc.day);
WriteLogFile_CS(index, close);
if (close)
s_logTime[index] = timeDesc;
}
//============================================================================
static unsigned FlushLogsTimerCallback (void *) {
AsyncLogFlush();
return kAsyncTimeInfinite;
}
} using namespace AsyncLog;
/****************************************************************************
*
* Exported functions
*
***/
//============================================================================
void AsyncLogInitialize (
const wchar_t logDirName[],
bool breakOnErrors
) {
s_running = true;
// Save options
s_breakOnErrors = breakOnErrors;
// Build log directory name
#ifdef SERVER
PathGetProgramDirectory(s_directory, arrsize(s_directory));
#else
PathGetUserDirectory(s_directory, arrsize(s_directory));
#endif
PathAddFilename(s_directory, s_directory, logDirName, arrsize(s_directory));
#ifndef ACELOG_NO_LOG_FILES
// Create log directory
if (kPathCreateDirSuccess != PathCreateDirectory(s_directory, 0))
PathRemoveFilename(s_directory, s_directory, arrsize(s_directory));
// Allocate log buffers
for (unsigned index = 0; index < kNumLogTypes; ++index) {
s_logCrit[index].Enter();
AllocLogBuffer_CS(index);
s_logCrit[index].Leave();
}
AsyncTimerCreate(&s_timer, FlushLogsTimerCallback, kAsyncTimeInfinite, nil);
#endif // ndef ACELOG_NO_LOG_FILES
}
//============================================================================
void AsyncLogDestroy () {
s_running = false;
#ifndef ACELOG_NO_LOG_FILES
AsyncTimerDelete(s_timer, kAsyncTimerDestroyWaitComplete);
for (unsigned index = 0; index < kNumLogTypes; ++index) {
s_logCrit[index].Enter();
{
WriteLogFile_CS(index, true);
FreeLogBuffer_CS(index);
}
s_logCrit[index].Leave();
}
while (s_opsPending)
AsyncSleep(10);
#endif // ndef ACELOG_NO_LOG_FILES
}
//============================================================================
void AsyncLogFlush () {
#ifndef ACELOG_NO_LOG_FILES
TimeDesc timeDesc;
TimeGetDesc(TimeGetTime(), &timeDesc);
for (unsigned index = 0; index < kNumLogTypes; ++index) {
s_logCrit[index].Enter();
FlushLogFile_CS(index, timeDesc);
s_logCrit[index].Leave();
}
#endif // ndef ACELOG_NO_LOG_FILES
}
//============================================================================
void LogBreakOnErrors (bool breakOnErrors) {
s_breakOnErrors = breakOnErrors;
}
//============================================================================
void AsyncLogWriteMsg (
const wchar_t facility[],
ELogSeverity severity,
const wchar_t msg[]
) {
if (!s_running)
return;
#ifndef ACELOG_NO_LOG_FILES
TimeDesc timeDesc;
TimeGetDesc(TimeGetTime(), &timeDesc);
char buffer[2048];
const unsigned chars = StrPrintf(
buffer,
arrsize(buffer),
"%02u/%02u/%02u % 2u:%02u:%02u [%S] %s %S\r\n",
timeDesc.month,
timeDesc.day,
timeDesc.year % 100,
timeDesc.hour,
timeDesc.minute,
timeDesc.second,
facility,
s_logSeverityToText[severity],
msg
);
unsigned index = s_logSeverityToType[severity];
s_logCrit[index].Enter();
{
// If day changed then write and flush file
if (s_logTime[index].day != timeDesc.day)
FlushLogFile_CS(index, timeDesc);
// Otherwise if the buffer is full then write to file
else if (s_logPos[index] + chars > s_logSize[index])
WriteLogFile_CS(index, false);
// Allocate log buffer if necessary
if (!s_logBuf[index])
AllocLogBuffer_CS(index);
// Add new data to the log buffer
memcpy(s_logBuf[index] + s_logPos[index], buffer, chars);
s_logPos[index] += chars;
// Write, flush and close file immediately if this is a fatal error
if (severity == kLogFatal)
WriteLogFile_CS(index, true);
// Drop to debugger if this is an error msg and that option was specified
if (s_breakOnErrors && severity >= kLogError)
DebugBreakIfDebuggerPresent();
}
s_logCrit[index].Leave();
// Queue flush
AsyncTimerUpdate(s_timer, kLogFlushMs, kAsyncTimerUpdateSetPriorityHigher);
#endif // ndef ACELOG_NO_LOG_FILES
}
//============================================================================
void AsyncLogGetDirectory (wchar_t * dest, unsigned destChars) {
ASSERT(dest);
StrCopy(dest, s_directory, destChars);
}

13
Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp

@ -151,15 +151,6 @@ static NetCommMsgHandler s_defaultHandler(0, nil, nil);
static NetCommMsgHandler s_preHandler(0, nil, nil);
//============================================================================
static void INetLogCallback (
ELogSeverity severity,
const wchar_t msg[]
) {
// Use the async log facility
AsyncLogWriteMsg(ProductShortName(), severity, msg);
}
//============================================================================
static void INetErrorCallback (
ENetProtocol protocol,
@ -755,9 +746,7 @@ void NetCommChangeMyPassword (
void NetCommStartup () {
s_shutdown = false;
LogRegisterHandler(INetLogCallback);
AsyncCoreInitialize();
AsyncLogInitialize(L"Log", false);
wchar_t productString[256];
ProductString(productString, arrsize(productString));
LogMsg(kLogPerf, L"Client: %s", productString);
@ -797,9 +786,7 @@ void NetCommShutdown () {
NetCliFileDisconnect();
NetClientDestroy(false);
AsyncLogDestroy();
AsyncCoreDestroy(30 * 1000);
LogUnregisterHandler(INetLogCallback);
}
//============================================================================

68
Sources/Plasma/PubUtilLib/plStatusLog/plLoggable.cpp

@ -45,7 +45,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsTemplates.h"
plLoggable::~plLoggable()
plLoggable::~plLoggable()
{
IDeleteLog();
}
@ -53,7 +53,7 @@ plLoggable::~plLoggable()
void plLoggable::IDeleteLog()
{
if ( fWeCreatedLog )
delete fStatusLog;
delete fStatusLog;
fWeCreatedLog = false;
fStatusLog = nil;
}
@ -86,13 +86,20 @@ void plLoggable::SetLog( plStatusLog * log, bool deleteOnDestruct/*=false */)
bool plLoggable::Log( const char * str ) const
{
if ( !str || strlen( str )==0 )
return Log(plString::FromUtf8(str));
}
bool plLoggable::Log(const plString& str) const
{
if (str.IsNull() || str.IsEmpty()) {
return true;
}
GetLog();
if ( fStatusLog )
return fStatusLog->AddLine( str );
if (fStatusLog) {
return fStatusLog->AddLine(str.c_str());
}
return true;
}
@ -101,60 +108,75 @@ bool plLoggable::LogF( const char * fmt, ... ) const
{
va_list args;
va_start(args, fmt);
return Log( xtl::formatv( fmt, args ).c_str() );
bool ret = Log(plString::IFormat(fmt, args));
va_end(args);
return ret;
}
bool plLoggable::LogV( const char * fmt, va_list args ) const
{
return Log( xtl::formatv( fmt, args ).c_str() );
return Log(plString::IFormat(fmt, args));
}
bool plLoggable::DebugMsgV(const char* fmt, va_list args) const
bool plLoggable::DebugMsgV(const char* fmt, va_list args) const
{
return LogF("DBG: %s", xtl::formatv(fmt,args).c_str());
return Log(_TEMP_CONVERT_FROM_LITERAL("DBG: ") + plString::IFormat(fmt, args));
}
bool plLoggable::ErrorMsgV(const char* fmt, va_list args) const
bool plLoggable::ErrorMsgV(const char* fmt, va_list args) const
{
return LogF("ERR: %s", xtl::formatv(fmt,args).c_str());
return Log(_TEMP_CONVERT_FROM_LITERAL("ERR: ") + plString::IFormat(fmt, args));
}
bool plLoggable::WarningMsgV(const char* fmt, va_list args) const
bool plLoggable::WarningMsgV(const char* fmt, va_list args) const
{
return LogF("WRN: %s", xtl::formatv(fmt,args).c_str());
return Log(_TEMP_CONVERT_FROM_LITERAL("WRN: ") + plString::IFormat(fmt, args));
}
bool plLoggable::AppMsgV(const char* fmt, va_list args) const
bool plLoggable::AppMsgV(const char* fmt, va_list args) const
{
return LogF("APP: %s", xtl::formatv(fmt,args).c_str());
return Log(_TEMP_CONVERT_FROM_LITERAL("APP: ") + plString::IFormat(fmt, args));
}
///////////////////////////////////////////////////////////////
bool plLoggable::DebugMsg(const char* fmt, ...) const
bool plLoggable::DebugMsg(const char* fmt, ...) const
{
va_list args;
va_start(args, fmt);
return DebugMsgV(fmt, args);
bool ret = DebugMsgV(fmt, args);
va_end(args);
return ret;
}
bool plLoggable::ErrorMsg(const char* fmt, ...) const
bool plLoggable::ErrorMsg(const char* fmt, ...) const
{
va_list args;
va_start(args, fmt);
return ErrorMsgV(fmt, args);
bool ret = ErrorMsgV(fmt, args);
va_end(args);
return ret;
}
bool plLoggable::WarningMsg(const char* fmt, ...) const
bool plLoggable::WarningMsg(const char* fmt, ...) const
{
va_list args;
va_start(args, fmt);
return WarningMsgV(fmt, args);
bool ret = WarningMsgV(fmt, args);
va_end(args);
return ret;
}
bool plLoggable::AppMsg(const char* fmt, ...) const
bool plLoggable::AppMsg(const char* fmt, ...) const
{
va_list args;
va_start(args, fmt);
return AppMsgV(fmt, args);
bool ret = AppMsgV(fmt, args);
va_end(args);
return ret;
}

4
Sources/Plasma/PubUtilLib/plStatusLog/plLoggable.h

@ -44,6 +44,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <stdio.h>
#include "HeadSpin.h"
#include "plString.h"
//
// An abstract base class which contains a status log and simple functions
@ -66,10 +67,11 @@ public:
plStatusLog* GetLog() const;
void SetLog( plStatusLog * log, bool deleteOnDestruct=false );
// logging
virtual bool Log( const char * str ) const;
virtual bool Log(const plString& str) const;
virtual bool LogF( const char * fmt, ... ) const;
virtual bool LogV( const char * fmt, va_list args ) const;
virtual bool ErrorMsgV(const char* fmt, va_list args) const ;

17
Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.cpp

@ -70,10 +70,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plEncryptLogLine.h"
#if HS_BUILD_FOR_UNIX
#include <limits.h>
#define MAX_PATH PATH_MAX
#elif HS_BUILD_FOR_WIN32
#if HS_BUILD_FOR_WIN32
#include <Shlobj.h>
#endif
@ -411,6 +408,7 @@ uint32_t plStatusLog::fLoggingOff = false;
plStatusLog::plStatusLog( uint8_t numDisplayLines, const wchar_t *filename, uint32_t flags )
{
fFileHandle = nil;
fSema = nil;
fSize = 0;
fForceLog = false;
@ -421,12 +419,16 @@ plStatusLog::plStatusLog( uint8_t numDisplayLines, const wchar_t *filename, uint
char* temp = hsWStringToString(filename);
fCFilename = temp;
delete [] temp;
fSema = new hsSemaphore(1, fCFilename.c_str());
}
else
{
fFilename = L"";
fCFilename = "";
flags |= kDontWriteFile;
fSema = new hsSemaphore(1);
}
fOrigFlags = fFlags = flags;
@ -532,6 +534,9 @@ void plStatusLog::IFini( void )
for( i = 0; i < fMaxNumLines; i++ )
delete [] fLines[ i ];
if (fSema)
delete fSema;
delete [] fLines;
delete [] fColors;
}
@ -601,7 +606,7 @@ bool plStatusLog::IAddLine( const char *line, int32_t count, uint32_t color )
return true;
/// Scroll pointers up
hsTempMutexLock lock( fMutex );
fSema->Wait();
bool ret = true;
@ -649,6 +654,8 @@ bool plStatusLog::IAddLine( const char *line, int32_t count, uint32_t color )
ret = IPrintLineToFile( line, count );
}
fSema->Signal();
return ret;
}

18
Sources/Plasma/PubUtilLib/plStatusLog/plStatusLog.h

@ -82,16 +82,16 @@ class plStatusLog
mutable uint32_t fFlags; // Mutable so we can change it in IPrintLineToFile() internally
uint32_t fOrigFlags;
uint32_t fMaxNumLines;
std::string fCFilename; // used ONLY by GetFileName()
uint32_t fMaxNumLines;
std::string fCFilename; // used ONLY by GetFileName()
std::wstring fFilename;
char **fLines;
uint32_t *fColors;
hsMutex fMutex; // To make multithreaded-safe
FILE* fFileHandle;
uint32_t fSize;
bool fEncryptMe;
bool fForceLog;
char** fLines;
uint32_t* fColors;
hsSemaphore* fSema;
FILE* fFileHandle;
uint32_t fSize;
bool fEncryptMe;
bool fForceLog;
plStatusLog *fNext, **fBack;

Loading…
Cancel
Save