mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-08-20 09:57:10 +00:00
Horrible code alert
This commit is contained in:
parent
cb4e0e82b7
commit
44b4ba84c2
|
|
@ -7729,7 +7729,7 @@ unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, __int64 see
|
||||||
if(hasSeed)
|
if(hasSeed)
|
||||||
{
|
{
|
||||||
strcpy((char *)bTextMetadata,"4J_SEED");
|
strcpy((char *)bTextMetadata,"4J_SEED");
|
||||||
snprintf((char *)&bTextMetadata[8], 42, NULL, seed);
|
snprintf((char *)&bTextMetadata[8], 42, "%lld", (long long)seed);
|
||||||
|
|
||||||
// get the length
|
// get the length
|
||||||
iTextMetadataBytes+=8;
|
iTextMetadataBytes+=8;
|
||||||
|
|
|
||||||
|
|
@ -226,8 +226,10 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
|
||||||
thread->SetProcessor(CPU_CORE_SERVER);
|
thread->SetProcessor(CPU_CORE_SERVER);
|
||||||
thread->Run();
|
thread->Run();
|
||||||
|
|
||||||
|
app.DebugPrintf("[NET] Waiting for server ready...\n");
|
||||||
ServerReadyWait();
|
ServerReadyWait();
|
||||||
ServerReadyDestroy();
|
ServerReadyDestroy();
|
||||||
|
app.DebugPrintf("[NET] Server ready! serverHalted=%d\n", MinecraftServer::serverHalted());
|
||||||
|
|
||||||
if( MinecraftServer::serverHalted() )
|
if( MinecraftServer::serverHalted() )
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -241,6 +243,7 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
|
||||||
|
|
||||||
#ifndef _XBOX
|
#ifndef _XBOX
|
||||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||||
|
app.DebugPrintf("[NET] IsReadyToPlayOrIdle=%d IsInSession=%d\n", IsReadyToPlayOrIdle(), IsInSession());
|
||||||
// Make sure that we have transitioned through any joining/creating stages and are actually playing the game, so that we know the players should be valid
|
// Make sure that we have transitioned through any joining/creating stages and are actually playing the game, so that we know the players should be valid
|
||||||
bool changedMessage = false;
|
bool changedMessage = false;
|
||||||
while(!IsReadyToPlayOrIdle())
|
while(!IsReadyToPlayOrIdle())
|
||||||
|
|
@ -257,12 +260,15 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we aren't in session, then something bad must have happened - we aren't joining, creating or ready play
|
// If we aren't in session, then something bad must have happened - we aren't joining, creating or ready play
|
||||||
|
app.DebugPrintf("[NET] Checking IsInSession...=%d\n", IsInSession());
|
||||||
if(!IsInSession() )
|
if(!IsInSession() )
|
||||||
{
|
{
|
||||||
|
app.DebugPrintf("[NET] NOT in session! Halting server.\n");
|
||||||
MinecraftServer::HaltServer();
|
MinecraftServer::HaltServer();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.DebugPrintf("[NET] DLC check: completed=%d pending=%d\n", app.DLCInstallProcessCompleted(), app.DLCInstallPending());
|
||||||
// 4J Stu - Wait a while to make sure that DLC is loaded. This is the last point before the network communication starts
|
// 4J Stu - Wait a while to make sure that DLC is loaded. This is the last point before the network communication starts
|
||||||
// so the latest we can check this
|
// so the latest we can check this
|
||||||
while( !app.DLCInstallProcessCompleted() && app.DLCInstallPending() && !g_NetworkManager.IsLeavingGame() )
|
while( !app.DLCInstallProcessCompleted() && app.DLCInstallPending() && !g_NetworkManager.IsLeavingGame() )
|
||||||
|
|
@ -277,12 +283,14 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
|
||||||
|
|
||||||
// PRIMARY PLAYER
|
// PRIMARY PLAYER
|
||||||
|
|
||||||
|
app.DebugPrintf("[NET] Creating ClientConnection (IsHost=%d)...\n", g_NetworkManager.IsHost());
|
||||||
vector<ClientConnection *> createdConnections;
|
vector<ClientConnection *> createdConnections;
|
||||||
ClientConnection *connection;
|
ClientConnection *connection;
|
||||||
|
|
||||||
if( g_NetworkManager.IsHost() )
|
if( g_NetworkManager.IsHost() )
|
||||||
{
|
{
|
||||||
connection = new ClientConnection(minecraft, NULL);
|
connection = new ClientConnection(minecraft, NULL);
|
||||||
|
app.DebugPrintf("[NET] ClientConnection created, createdOk=%d\n", connection->createdOk);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -318,7 +326,9 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.DebugPrintf("[NET] Sending PreLoginPacket...\n");
|
||||||
connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(minecraft->user->name) ) );
|
connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(minecraft->user->name) ) );
|
||||||
|
app.DebugPrintf("[NET] PreLoginPacket sent. Entering connection tick loop...\n");
|
||||||
|
|
||||||
// Tick connection until we're ready to go. The stages involved in this are:
|
// Tick connection until we're ready to go. The stages involved in this are:
|
||||||
// (1) Creating the ClientConnection sends a prelogin packet to the server
|
// (1) Creating the ClientConnection sends a prelogin packet to the server
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,10 @@ void UIScene_FullscreenProgress::tick()
|
||||||
int code = thread->GetExitCode();
|
int code = thread->GetExitCode();
|
||||||
DWORD exitcode = *((DWORD *)&code);
|
DWORD exitcode = *((DWORD *)&code);
|
||||||
|
|
||||||
|
static int s_FPTickCount = 0;
|
||||||
|
if(s_FPTickCount % 60 == 0) app.DebugPrintf("[FP] tick #%d exitcode=%u STILL_ACTIVE=%u\n", s_FPTickCount, exitcode, (DWORD)STILL_ACTIVE);
|
||||||
|
s_FPTickCount++;
|
||||||
|
|
||||||
//app.DebugPrintf("CScene_FullscreenProgress Timer %d\n",pTimer->nId);
|
//app.DebugPrintf("CScene_FullscreenProgress Timer %d\n",pTimer->nId);
|
||||||
|
|
||||||
if( exitcode != STILL_ACTIVE )
|
if( exitcode != STILL_ACTIVE )
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static int s_introTickCount = 0;
|
static int s_introTickCount = 0;
|
||||||
#endif
|
#endif
|
||||||
#include <Linux_UIController.h>
|
|
||||||
|
|
||||||
UIScene_Intro::UIScene_Intro(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
UIScene_Intro::UIScene_Intro(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1806,6 +1806,7 @@ void UIScene_MainMenu::tick()
|
||||||
{
|
{
|
||||||
static int s_mainMenuTickCount = 0;
|
static int s_mainMenuTickCount = 0;
|
||||||
s_mainMenuTickCount++;
|
s_mainMenuTickCount++;
|
||||||
|
if(s_mainMenuTickCount % 60 == 1) { fprintf(stderr, "[MM] tick %d\n", s_mainMenuTickCount); fflush(stderr); }
|
||||||
if(s_mainMenuTickCount == 90) // ~3 seconds at 30fps
|
if(s_mainMenuTickCount == 90) // ~3 seconds at 30fps
|
||||||
{
|
{
|
||||||
fprintf(stderr, "[Linux] Auto-starting trial world from MainMenu after %d ticks\n", s_mainMenuTickCount);
|
fprintf(stderr, "[Linux] Auto-starting trial world from MainMenu after %d ticks\n", s_mainMenuTickCount);
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
// logger.info("Preparing level \"" + levelName + "\"");
|
// logger.info("Preparing level \"" + levelName + "\"");
|
||||||
m_bLoaded = loadLevel(new McRegionLevelStorageSource(File(L".")), levelName, seed, pLevelType, initData);
|
m_bLoaded = loadLevel(new McRegionLevelStorageSource(File(L".")), levelName, seed, pLevelType, initData);
|
||||||
// logger.info("Done (" + (System.nanoTime() - levelNanoTime) + "ns)! For help, type \"help\" or \"?\"");
|
// logger.info("Done (" + (System.nanoTime() - levelNanoTime) + "ns)! For help, type \"help\" or \"?\"");
|
||||||
|
app.DebugPrintf("[SRV] loadLevel returned %d\n", m_bLoaded);
|
||||||
|
|
||||||
// 4J delete passed in save data now - this is only required for the tutorial which is loaded by passing data directly in rather than using the storage manager
|
// 4J delete passed in save data now - this is only required for the tutorial which is loaded by passing data directly in rather than using the storage manager
|
||||||
if( initData->saveData )
|
if( initData->saveData )
|
||||||
|
|
@ -266,7 +267,9 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
initData->saveData->fileSize = 0;
|
initData->saveData->fileSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.DebugPrintf("[SRV] Signaling ServerReady\n");
|
||||||
g_NetworkManager.ServerReady(); // 4J added
|
g_NetworkManager.ServerReady(); // 4J added
|
||||||
|
app.DebugPrintf("[SRV] ServerReady signaled, returning m_bLoaded=%d\n", m_bLoaded);
|
||||||
return m_bLoaded;
|
return m_bLoaded;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -508,8 +511,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
// 4J - Make a new thread to do post processing
|
// 4J - Make a new thread to do post processing
|
||||||
InitializeCriticalSection(&m_postProcessCS);
|
InitializeCriticalSection(&m_postProcessCS);
|
||||||
|
|
||||||
// 4J-PB - fix for 108310 - TCR #001 BAS Game Stability: TU12: Code: Compliance: Crash after creating world on "journey" seed.
|
app.DebugPrintf("[SRV] Starting post-processing thread\n");
|
||||||
// Stack gets very deep with some sand tower falling, so increased the stacj to 256K from 128k on other platforms (was already set to that on PS3 and Orbis)
|
|
||||||
|
|
||||||
m_postUpdateThread = new C4JThread(runPostUpdate, this, "Post processing", 256*1024);
|
m_postUpdateThread = new C4JThread(runPostUpdate, this, "Post processing", 256*1024);
|
||||||
|
|
||||||
|
|
@ -517,6 +519,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
m_postUpdateThread->SetProcessor(CPU_CORE_POST_PROCESSING);
|
m_postUpdateThread->SetProcessor(CPU_CORE_POST_PROCESSING);
|
||||||
m_postUpdateThread->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
|
m_postUpdateThread->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
|
||||||
m_postUpdateThread->Run();
|
m_postUpdateThread->Run();
|
||||||
|
app.DebugPrintf("[SRV] Post-processing thread started\n");
|
||||||
|
|
||||||
__int64 startTime = System::currentTimeMillis();
|
__int64 startTime = System::currentTimeMillis();
|
||||||
|
|
||||||
|
|
@ -589,9 +592,11 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
#else
|
#else
|
||||||
__int64 lastStorageTickTime = System::currentTimeMillis();
|
__int64 lastStorageTickTime = System::currentTimeMillis();
|
||||||
Pos *spawnPos = level->getSharedSpawnPos();
|
Pos *spawnPos = level->getSharedSpawnPos();
|
||||||
|
app.DebugPrintf("[SRV] dim=%d spawn=(%d,%d) r=%d\n", i, spawnPos->x, spawnPos->z, r);
|
||||||
|
|
||||||
int twoRPlusOne = r*2 + 1;
|
int twoRPlusOne = r*2 + 1;
|
||||||
int total = twoRPlusOne * twoRPlusOne;
|
int total = twoRPlusOne * twoRPlusOne;
|
||||||
|
int chunksDone = 0;
|
||||||
for (int x = -r; x <= r && running; x += 16)
|
for (int x = -r; x <= r && running; x += 16)
|
||||||
{
|
{
|
||||||
for (int z = -r; z <= r && running; z += 16)
|
for (int z = -r; z <= r && running; z += 16)
|
||||||
|
|
@ -617,6 +622,8 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
PIXBeginNamedEvent(0,"Creating %d ", (count++)%8);
|
PIXBeginNamedEvent(0,"Creating %d ", (count++)%8);
|
||||||
level->cache->create((spawnPos->x + x) >> 4, (spawnPos->z + z) >> 4, true); // 4J - added parameter to disable postprocessing here
|
level->cache->create((spawnPos->x + x) >> 4, (spawnPos->z + z) >> 4, true); // 4J - added parameter to disable postprocessing here
|
||||||
PIXEndNamedEvent();
|
PIXEndNamedEvent();
|
||||||
|
chunksDone++;
|
||||||
|
if(chunksDone % 50 == 0) app.DebugPrintf("[SRV] dim=%d chunk %d/%d\n", i, chunksDone, total);
|
||||||
// while (level->updateLights() && running)
|
// while (level->updateLights() && running)
|
||||||
// ;
|
// ;
|
||||||
if( System::currentTimeMillis() - lastStorageTickTime > 50 )
|
if( System::currentTimeMillis() - lastStorageTickTime > 50 )
|
||||||
|
|
@ -649,10 +656,12 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
}
|
}
|
||||||
// printf("Main thread complete at %dms\n",System::currentTimeMillis() - startTime);
|
// printf("Main thread complete at %dms\n",System::currentTimeMillis() - startTime);
|
||||||
|
|
||||||
|
app.DebugPrintf("[SRV] All chunk loops done, waiting for postProcess\n");
|
||||||
// Wait for post processing, then lighting threads, to end (post-processing may make more lighting changes)
|
// Wait for post processing, then lighting threads, to end (post-processing may make more lighting changes)
|
||||||
m_postUpdateTerminate = true;
|
m_postUpdateTerminate = true;
|
||||||
|
|
||||||
postProcessTerminate(mcprogress);
|
postProcessTerminate(mcprogress);
|
||||||
|
app.DebugPrintf("[SRV] postProcessTerminate done\n");
|
||||||
|
|
||||||
|
|
||||||
// stronghold position?
|
// stronghold position?
|
||||||
|
|
@ -713,14 +722,18 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
|
|
||||||
if( levels[0]->isNew )
|
if( levels[0]->isNew )
|
||||||
{
|
{
|
||||||
|
app.DebugPrintf("[SRV] Saving level 0...\n");
|
||||||
levels[0]->save(true, mcprogress);
|
levels[0]->save(true, mcprogress);
|
||||||
|
app.DebugPrintf("[SRV] Level 0 saved\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if( s_bServerHalted || !g_NetworkManager.IsInSession() ) return false;
|
if( s_bServerHalted || !g_NetworkManager.IsInSession() ) return false;
|
||||||
|
|
||||||
if( levels[0]->isNew || levels[1]->isNew || levels[2]->isNew )
|
if( levels[0]->isNew || levels[1]->isNew || levels[2]->isNew )
|
||||||
{
|
{
|
||||||
|
app.DebugPrintf("[SRV] Saving to disc...\n");
|
||||||
levels[0]->saveToDisc(mcprogress, false);
|
levels[0]->saveToDisc(mcprogress, false);
|
||||||
|
app.DebugPrintf("[SRV] saveToDisc done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if( s_bServerHalted || !g_NetworkManager.IsInSession() ) return false;
|
if( s_bServerHalted || !g_NetworkManager.IsInSession() ) return false;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,29 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
//#include <system_service.h>
|
//#include <system_service.h>
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <signal.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
static void sigsegv_handler(int sig) {
|
||||||
|
const char msg[] = "\n=== SIGNAL CAUGHT: ";
|
||||||
|
write(STDERR_FILENO, msg, sizeof(msg)-1);
|
||||||
|
char signum[8];
|
||||||
|
int len = 0;
|
||||||
|
int s = sig;
|
||||||
|
if (s == 0) { signum[len++] = '0'; }
|
||||||
|
else { char tmp[8]; int tl = 0; while(s > 0) { tmp[tl++] = '0' + (s%10); s /= 10; } for(int i = tl-1; i >= 0; i--) signum[len++] = tmp[i]; }
|
||||||
|
write(STDERR_FILENO, signum, len);
|
||||||
|
const char msg1b[] = " ===\n";
|
||||||
|
write(STDERR_FILENO, msg1b, sizeof(msg1b)-1);
|
||||||
|
void *array[64];
|
||||||
|
int size = backtrace(array, 64);
|
||||||
|
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
||||||
|
const char msg2[] = "=== END BACKTRACE ===\n";
|
||||||
|
write(STDERR_FILENO, msg2, sizeof(msg2)-1);
|
||||||
|
_exit(139);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#include "../Windows64/GameConfig/Minecraft.spa.h"
|
#include "../Windows64/GameConfig/Minecraft.spa.h"
|
||||||
#include "../../MinecraftServer.h"
|
#include "../../MinecraftServer.h"
|
||||||
#include "../../Player/LocalPlayer.h"
|
#include "../../Player/LocalPlayer.h"
|
||||||
|
|
@ -552,6 +575,16 @@ int StartMinecraftThreadProc( void* lpParameter )
|
||||||
|
|
||||||
int main(int argc, const char *argv[] )
|
int main(int argc, const char *argv[] )
|
||||||
{
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
struct sigaction sa;
|
||||||
|
sa.sa_handler = sigsegv_handler;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = SA_RESETHAND;
|
||||||
|
sigaction(SIGSEGV, &sa, NULL);
|
||||||
|
sigaction(SIGABRT, &sa, NULL);
|
||||||
|
sigaction(SIGBUS, &sa, NULL);
|
||||||
|
sigaction(SIGTRAP, &sa, NULL);
|
||||||
|
#endif
|
||||||
app.DebugPrintf("---main()\n");
|
app.DebugPrintf("---main()\n");
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
||||||
|
|
@ -808,10 +808,9 @@ static inline BOOL ResetEvent(HANDLE hEvent) {
|
||||||
|
|
||||||
#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
|
#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
|
||||||
#define INFINITE 0xFFFFFFFF
|
#define INFINITE 0xFFFFFFFF
|
||||||
|
#define HANDLE_TYPE_THREAD 0x54485200
|
||||||
|
|
||||||
static inline DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
|
static inline DWORD _WaitForEvent(Event* ev, DWORD dwMilliseconds) {
|
||||||
Event* ev = (Event*)hHandle;
|
|
||||||
if (!ev) return WAIT_FAILED;
|
|
||||||
pthread_mutex_lock(&ev->mutex);
|
pthread_mutex_lock(&ev->mutex);
|
||||||
if (dwMilliseconds == INFINITE) {
|
if (dwMilliseconds == INFINITE) {
|
||||||
while (!ev->signaled) pthread_cond_wait(&ev->cond, &ev->mutex);
|
while (!ev->signaled) pthread_cond_wait(&ev->cond, &ev->mutex);
|
||||||
|
|
@ -835,6 +834,18 @@ static inline DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
|
||||||
return WAIT_OBJECT_0;
|
return WAIT_OBJECT_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LinuxThread;
|
||||||
|
static inline DWORD _WaitForThread(struct LinuxThread* lt, DWORD dwMilliseconds);
|
||||||
|
|
||||||
|
static inline DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
|
||||||
|
if (!hHandle) return WAIT_FAILED;
|
||||||
|
// Check if this is a thread handle (LinuxThread has magic number as first field)
|
||||||
|
if (*(int*)hHandle == HANDLE_TYPE_THREAD) {
|
||||||
|
return _WaitForThread((struct LinuxThread*)hHandle, dwMilliseconds);
|
||||||
|
}
|
||||||
|
return _WaitForEvent((Event*)hHandle, dwMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
static inline DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds) {
|
static inline DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds) {
|
||||||
if (bWaitAll) {
|
if (bWaitAll) {
|
||||||
for (DWORD i = 0; i < nCount; i++) WaitForSingleObject(lpHandles[i], dwMilliseconds);
|
for (DWORD i = 0; i < nCount; i++) WaitForSingleObject(lpHandles[i], dwMilliseconds);
|
||||||
|
|
@ -862,6 +873,7 @@ static inline void CloseHandle_Event(HANDLE hEvent) {
|
||||||
typedef DWORD (*LPTHREAD_START_ROUTINE)(void*);
|
typedef DWORD (*LPTHREAD_START_ROUTINE)(void*);
|
||||||
|
|
||||||
struct LinuxThread {
|
struct LinuxThread {
|
||||||
|
int handleType;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
LPTHREAD_START_ROUTINE func;
|
LPTHREAD_START_ROUTINE func;
|
||||||
void* param;
|
void* param;
|
||||||
|
|
@ -870,6 +882,9 @@ struct LinuxThread {
|
||||||
int suspended;
|
int suspended;
|
||||||
pthread_mutex_t suspendMutex;
|
pthread_mutex_t suspendMutex;
|
||||||
pthread_cond_t suspendCond;
|
pthread_cond_t suspendCond;
|
||||||
|
pthread_mutex_t completionMutex;
|
||||||
|
pthread_cond_t completionCond;
|
||||||
|
int completed;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void* _linux_thread_entry(void* arg) {
|
static inline void* _linux_thread_entry(void* arg) {
|
||||||
|
|
@ -878,20 +893,58 @@ static inline void* _linux_thread_entry(void* arg) {
|
||||||
while (lt->suspended) pthread_cond_wait(<->suspendCond, <->suspendMutex);
|
while (lt->suspended) pthread_cond_wait(<->suspendCond, <->suspendMutex);
|
||||||
pthread_mutex_unlock(<->suspendMutex);
|
pthread_mutex_unlock(<->suspendMutex);
|
||||||
lt->exitCode = lt->func(lt->param);
|
lt->exitCode = lt->func(lt->param);
|
||||||
|
// Signal completion
|
||||||
|
pthread_mutex_lock(<->completionMutex);
|
||||||
|
lt->completed = 1;
|
||||||
|
pthread_cond_broadcast(<->completionCond);
|
||||||
|
pthread_mutex_unlock(<->completionMutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline DWORD _WaitForThread(struct LinuxThread* lt, DWORD dwMilliseconds) {
|
||||||
|
pthread_mutex_lock(<->completionMutex);
|
||||||
|
if (lt->completed) {
|
||||||
|
pthread_mutex_unlock(<->completionMutex);
|
||||||
|
return WAIT_OBJECT_0;
|
||||||
|
}
|
||||||
|
if (dwMilliseconds == 0) {
|
||||||
|
pthread_mutex_unlock(<->completionMutex);
|
||||||
|
return WAIT_TIMEOUT;
|
||||||
|
}
|
||||||
|
if (dwMilliseconds == INFINITE) {
|
||||||
|
while (!lt->completed) pthread_cond_wait(<->completionCond, <->completionMutex);
|
||||||
|
} else {
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
ts.tv_sec += dwMilliseconds / 1000;
|
||||||
|
ts.tv_nsec += (dwMilliseconds % 1000) * 1000000;
|
||||||
|
if (ts.tv_nsec >= 1000000000) { ts.tv_sec++; ts.tv_nsec -= 1000000000; }
|
||||||
|
while (!lt->completed) {
|
||||||
|
if (pthread_cond_timedwait(<->completionCond, <->completionMutex, &ts) != 0) {
|
||||||
|
pthread_mutex_unlock(<->completionMutex);
|
||||||
|
return WAIT_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(<->completionMutex);
|
||||||
|
return WAIT_OBJECT_0;
|
||||||
|
}
|
||||||
|
|
||||||
static DWORD g_nextThreadId = 1000;
|
static DWORD g_nextThreadId = 1000;
|
||||||
|
|
||||||
static inline HANDLE CreateThread(void*, SIZE_T stackSize, LPTHREAD_START_ROUTINE lpStartAddress, void* lpParameter, DWORD dwCreationFlags, DWORD* lpThreadId) {
|
static inline HANDLE CreateThread(void*, SIZE_T stackSize, LPTHREAD_START_ROUTINE lpStartAddress, void* lpParameter, DWORD dwCreationFlags, DWORD* lpThreadId) {
|
||||||
LinuxThread* lt = (LinuxThread*)calloc(1, sizeof(LinuxThread));
|
LinuxThread* lt = (LinuxThread*)calloc(1, sizeof(LinuxThread));
|
||||||
|
lt->handleType = HANDLE_TYPE_THREAD;
|
||||||
lt->func = lpStartAddress;
|
lt->func = lpStartAddress;
|
||||||
lt->param = lpParameter;
|
lt->param = lpParameter;
|
||||||
lt->exitCode = STILL_ACTIVE;
|
lt->exitCode = STILL_ACTIVE;
|
||||||
lt->suspended = (dwCreationFlags & CREATE_SUSPENDED) ? 1 : 0;
|
lt->suspended = (dwCreationFlags & CREATE_SUSPENDED) ? 1 : 0;
|
||||||
|
lt->completed = 0;
|
||||||
lt->threadId = __sync_fetch_and_add(&g_nextThreadId, 1);
|
lt->threadId = __sync_fetch_and_add(&g_nextThreadId, 1);
|
||||||
pthread_mutex_init(<->suspendMutex, NULL);
|
pthread_mutex_init(<->suspendMutex, NULL);
|
||||||
pthread_cond_init(<->suspendCond, NULL);
|
pthread_cond_init(<->suspendCond, NULL);
|
||||||
|
pthread_mutex_init(<->completionMutex, NULL);
|
||||||
|
pthread_cond_init(<->completionCond, NULL);
|
||||||
if (lpThreadId) *lpThreadId = lt->threadId;
|
if (lpThreadId) *lpThreadId = lt->threadId;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
|
|
|
||||||
1
Minecraft.World/Build/stlHaEcC
Normal file
1
Minecraft.World/Build/stlHaEcC
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
!<arch>
|
||||||
|
|
@ -20,11 +20,9 @@ int Connection::writeSizes[256];
|
||||||
void Connection::_init()
|
void Connection::_init()
|
||||||
{
|
{
|
||||||
// printf("Con:0x%x init\n",this);
|
// printf("Con:0x%x init\n",this);
|
||||||
#if !defined(__linux__)
|
|
||||||
InitializeCriticalSection(&writeLock);
|
InitializeCriticalSection(&writeLock);
|
||||||
InitializeCriticalSection(&threadCounterLock);
|
InitializeCriticalSection(&threadCounterLock);
|
||||||
InitializeCriticalSection(&incoming_cs);
|
InitializeCriticalSection(&incoming_cs);
|
||||||
#endif
|
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
quitting = false;
|
quitting = false;
|
||||||
|
|
@ -51,11 +49,9 @@ Connection::~Connection()
|
||||||
// may get stuck whilst blocking waiting on a read
|
// may get stuck whilst blocking waiting on a read
|
||||||
readThread->WaitForCompletion(INFINITE);
|
readThread->WaitForCompletion(INFINITE);
|
||||||
writeThread->WaitForCompletion(INFINITE);
|
writeThread->WaitForCompletion(INFINITE);
|
||||||
#if defined(__linux__)
|
|
||||||
DeleteCriticalSection(&writeLock);
|
DeleteCriticalSection(&writeLock);
|
||||||
DeleteCriticalSection(&threadCounterLock);
|
DeleteCriticalSection(&threadCounterLock);
|
||||||
DeleteCriticalSection(&incoming_cs);
|
DeleteCriticalSection(&incoming_cs);
|
||||||
#endif // __linux__
|
|
||||||
delete m_hWakeReadThread;
|
delete m_hWakeReadThread;
|
||||||
delete m_hWakeWriteThread;
|
delete m_hWakeWriteThread;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue