From 4e8d1c9e179d664c2c147df77d3b77a0c9aa2477 Mon Sep 17 00:00:00 2001 From: notmatthewbeshay <92357869+NotMachow@users.noreply.github.com> Date: Wed, 11 Mar 2026 07:40:52 +1100 Subject: [PATCH] Use platform TLS keys in portal and piston state --- Minecraft.World/Blocks/PistonBaseTile.cpp | 41 ++++++++++++++++++++- Minecraft.World/Blocks/PistonBaseTile.h | 10 ++++- Minecraft.World/Blocks/TheEndPortalTile.cpp | 41 ++++++++++++++++++++- Minecraft.World/Blocks/TheEndPortalTile.h | 10 ++++- 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index 786ee7069..cffdeb760 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -1,4 +1,5 @@ #include "../Platform/stdafx.h" +#include #include "PistonBaseTile.h" #include "PistonMovingTileEntity.h" #include "TileEntities/PistonPieceTileEntity.h" @@ -19,7 +20,43 @@ const std::wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top"; const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f; +namespace +{ +#if defined(_WIN32) + inline void *PistonTlsGetValue(DWORD key) + { + return TlsGetValue(key); + } + + inline void PistonTlsSetValue(DWORD key, void *value) + { + TlsSetValue(key, value); + } +#else + pthread_key_t CreatePistonTlsKey() + { + pthread_key_t key; + pthread_key_create(&key, NULL); + return key; + } + + inline void *PistonTlsGetValue(pthread_key_t key) + { + return pthread_getspecific(key); + } + + inline void PistonTlsSetValue(pthread_key_t key, void *value) + { + pthread_setspecific(key, value); + } +#endif +} + +#if defined(_WIN32) DWORD PistonBaseTile::tlsIdx = TlsAlloc(); +#else +pthread_key_t PistonBaseTile::tlsIdx = CreatePistonTlsKey(); +#endif // 4J - NOTE - this ignoreUpdate stuff has been removed from the java version, but I'm not currently sure how the java version does without it... there must be // some other mechanism that we don't have that stops the event from one piston being processed, from causing neighbours to have extra events created for them. @@ -28,12 +65,12 @@ DWORD PistonBaseTile::tlsIdx = TlsAlloc(); // 4J - ignoreUpdate is a static in java, implementing as TLS here to make thread safe bool PistonBaseTile::ignoreUpdate() { - return (TlsGetValue(tlsIdx) != NULL); + return PistonTlsGetValue(tlsIdx) != NULL; } void PistonBaseTile::ignoreUpdate(bool set) { - TlsSetValue(tlsIdx,(LPVOID)(intptr_t)(set?1:0)); + PistonTlsSetValue(tlsIdx, reinterpret_cast(static_cast(set ? 1 : 0))); } PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, isSolidRender() ) diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index 9e5ca11e1..4e844a7e2 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -1,6 +1,10 @@ #pragma once #include "Tile.h" +#if !defined(_WIN32) +#include +#endif + class PistonBaseTile : public Tile { public: @@ -25,7 +29,11 @@ private: Icon *iconBack; Icon *iconPlatform; +#if defined(_WIN32) static DWORD tlsIdx; +#else + static pthread_key_t tlsIdx; +#endif // 4J - was just a static but implemented with TLS for our version static bool ignoreUpdate(); static void ignoreUpdate(bool set); @@ -68,4 +76,4 @@ private: static void stopSharingIfServer(Level *level, int x, int y, int z); // 4J added bool createPush(Level *level, int sx, int sy, int sz, int facing); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/TheEndPortalTile.cpp b/Minecraft.World/Blocks/TheEndPortalTile.cpp index 967acae3d..27928c0fc 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalTile.cpp @@ -7,18 +7,55 @@ #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.h" +#include +namespace +{ +#if defined(_WIN32) + inline void *TheEndPortalTlsGetValue(DWORD key) + { + return TlsGetValue(key); + } + + inline void TheEndPortalTlsSetValue(DWORD key, void *value) + { + TlsSetValue(key, value); + } +#else + pthread_key_t CreateTheEndPortalTlsKey() + { + pthread_key_t key; + pthread_key_create(&key, NULL); + return key; + } + + inline void *TheEndPortalTlsGetValue(pthread_key_t key) + { + return pthread_getspecific(key); + } + + inline void TheEndPortalTlsSetValue(pthread_key_t key, void *value) + { + pthread_setspecific(key, value); + } +#endif +} + +#if defined(_WIN32) DWORD TheEndPortal::tlsIdx = TlsAlloc(); +#else +pthread_key_t TheEndPortal::tlsIdx = CreateTheEndPortalTlsKey(); +#endif // 4J - allowAnywhere is a static in java, implementing as TLS here to make thread safe bool TheEndPortal::allowAnywhere() { - return (TlsGetValue(tlsIdx) != NULL); + return TheEndPortalTlsGetValue(tlsIdx) != NULL; } void TheEndPortal::allowAnywhere(bool set) { - TlsSetValue(tlsIdx,(LPVOID)(intptr_t)(set?1:0)); + TheEndPortalTlsSetValue(tlsIdx, reinterpret_cast(static_cast(set ? 1 : 0))); } TheEndPortal::TheEndPortal(int id, Material *material) : EntityTile(id, material, isSolidRender()) diff --git a/Minecraft.World/Blocks/TheEndPortalTile.h b/Minecraft.World/Blocks/TheEndPortalTile.h index b344ce796..130a4232b 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.h +++ b/Minecraft.World/Blocks/TheEndPortalTile.h @@ -1,10 +1,18 @@ #pragma once #include "TileEntities/EntityTile.h" +#if !defined(_WIN32) +#include +#endif + class TheEndPortal : public EntityTile { public: +#if defined(_WIN32) static DWORD tlsIdx; +#else + static pthread_key_t tlsIdx; +#endif // 4J - was just a static but implemented with TLS for our version static bool allowAnywhere(); static void allowAnywhere(bool set); @@ -24,4 +32,4 @@ public: virtual void onPlace(Level *level, int x, int y, int z); virtual int cloneTileId(Level *level, int x, int y, int z); void registerIcons(IconRegister *iconRegister); -}; \ No newline at end of file +};