From a69784bf4cf0d8042b15b12db949ea49593e98f4 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 5 Nov 2012 00:56:54 -0500 Subject: [PATCH] Kill off Windows 9x AsyncCore Hey, guess what? TransGaming was what needed that old, obsolete crap. --- .../NucleusLib/pnAsyncCoreExe/CMakeLists.txt | 12 +- .../Plasma/NucleusLib/pnAsyncCoreExe/Pch.h | 1 - .../pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp | 81 -- .../pnAsyncCoreExe/Private/W9x/pnAceW9x.h | 64 - .../pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h | 142 -- .../Private/W9x/pnAceW9xSocket.cpp | 1224 ----------------- .../Private/W9x/pnAceW9xThread.cpp | 451 ------ .../NucleusLib/pnAsyncCoreExe/pnAceCore.cpp | 33 +- 8 files changed, 2 insertions(+), 2006 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.h delete mode 100644 Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h delete mode 100644 Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xSocket.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xThread.cpp diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt index 4ae85f4b..7831332a 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt @@ -31,14 +31,6 @@ set(pnAsyncCoreExe_PRIVATE_UNIX Private/Unix/pnAceUx.h ) -set(pnAsyncCoreExe_PRIVATE_W9X - Private/W9x/pnAceW9x.cpp - Private/W9x/pnAceW9x.h - Private/W9x/pnAceW9xInt.h - Private/W9x/pnAceW9xSocket.cpp - Private/W9x/pnAceW9xThread.cpp -) - set(pnAsyncCoreExe_PRIVATE_WIN32 Private/Win32/pnAceW32Dns.cpp Private/Win32/pnAceW32Thread.cpp @@ -49,13 +41,11 @@ set(pnAsyncCoreExe_PRIVATE_WIN32 add_library(pnAsyncCoreExe STATIC ${pnAsyncCoreExe_SOURCES} ${pnAsyncCoreExe_HEADERS} ${pnAsyncCoreExe_PRIVATE} ${pnAysncCoreExe_PRIVATE_NT} - ${pnAsyncCoreExe_PRIVATE_UNIX} ${pnAsyncCoreExe_PRIVATE_W9X} - ${pnAsyncCoreExe_PRIVATE_WIN32}) + ${pnAsyncCoreExe_PRIVATE_UNIX} ${pnAsyncCoreExe_PRIVATE_WIN32}) source_group("Source Files" FILES ${pnAsyncCoreExe_SOURCES}) source_group("Header Files" FILES ${pnAsyncCoreExe_HEADERS}) 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}) diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Pch.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Pch.h index 188a4281..6ecd3234 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Pch.h +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Pch.h @@ -57,7 +57,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "hsThread.h" #include "Private/pnAceInt.h" -#include "Private/W9x/pnAceW9x.h" #include "Private/Nt/pnAceNt.h" #include "Private/Unix/pnAceUx.h" diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp deleted file mode 100644 index 6d8a5db4..00000000 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp +++ /dev/null @@ -1,81 +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 . - -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/pnAceW9x.cpp -* -***/ - -#include "../../Pch.h" -#pragma hdrstop - -#include "pnAceW9xInt.h" - - -/**************************************************************************** -* -* Exported functions -* -***/ - -//=========================================================================== -void W9xGetApi (AsyncApi * api) { - using namespace W9x; - - api->initialize = W9xThreadInitialize; - api->destroy = W9xThreadDestroy; - api->signalShutdown = W9xThreadSignalShutdown; - api->waitForShutdown = W9xThreadWaitForShutdown; - api->sleep = W9xThreadSleep; - - api->socketConnect = W9xSocketConnect; - api->socketConnectCancel = W9xSocketConnectCancel; - api->socketDisconnect = W9xSocketDisconnect; - api->socketDelete = W9xSocketDelete; - api->socketSend = W9xSocketSend; - api->socketWrite = W9xSocketWrite; - api->socketSetNotifyProc = W9xSocketSetNotifyProc; - api->socketSetBacklogAlloc = W9xSocketSetBacklogAlloc; - api->socketStartListening = W9xSocketStartListening; - api->socketStopListening = W9xSocketStopListening; - api->socketEnableNagling = W9xSocketEnableNagling; -} diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.h deleted file mode 100644 index bf029ac5..00000000 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.h +++ /dev/null @@ -1,64 +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 . - -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/pnAceW9x.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNASYNCCOREEXE_PRIVATE_W9X_PNACEW9X_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNASYNCCOREEXE_PRIVATE_W9X_PNACEW9X_H - - -#ifdef HS_BUILD_FOR_WIN32 - -/**************************************************************************** -* -* Win9x API functions -* -***/ - -void W9xGetApi (AsyncApi * api); - -#endif // HS_BUILD_FOR_WIN32 diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h deleted file mode 100644 index 5ca8974c..00000000 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h +++ /dev/null @@ -1,142 +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 . - -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/pnAceW9xInt.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNASYNCCOREEXE_PRIVATE_W9X_PNACEW9XINT_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNASYNCCOREEXE_PRIVATE_W9X_PNACEW9XINT_H - - -namespace W9x { - -/***************************************************************************** -* -* Internal types -* -***/ - -class CThreadDispObject : public AtomicRef { -public: - CThreadDispObject (); - virtual ~CThreadDispObject () { } - void Close (); - virtual void Complete (void * op, CCritSect * critSect, AsyncId asyncId) = 0; - virtual void Delete (void * op) = 0; - AsyncId Queue (void * op); -}; - - -/***************************************************************************** -* -* W9x internal async API -* -***/ - -void W9xThreadInitialize (); -void W9xThreadDestroy (unsigned exitThreadWaitMs); -void W9xThreadSignalShutdown (); -void W9xThreadWaitForShutdown (); -void W9xThreadSleep (unsigned sleepMs); -bool W9xThreadWaitId ( - AsyncFile file, - AsyncId asyncId, - unsigned timeoutMs -); -void W9xSocketConnect ( - AsyncCancelId * cancelId, - const plNetAddress& netAddr, - FAsyncNotifySocketProc notifyProc, - void * param, - const void * sendData, - unsigned sendBytes, - unsigned connectMs, - unsigned localPort -); -void W9xSocketConnectCancel ( - FAsyncNotifySocketProc notifyProc, - AsyncCancelId cancelId -); -void W9xSocketDisconnect ( - AsyncSocket sock, - bool hardClose -); -void W9xSocketDelete (AsyncSocket sock); -void W9xSocketDestroy (); -bool W9xSocketSend ( - AsyncSocket sock, - const void * data, - unsigned bytes -); -bool W9xSocketWrite ( - AsyncSocket sock, - const void * buffer, - unsigned bytes, - void * param -); -void W9xSocketSetNotifyProc ( - AsyncSocket sock, - FAsyncNotifySocketProc notifyProc -); -void W9xSocketSetBacklogAlloc ( - AsyncSocket sock, - unsigned bufferSize -); -unsigned W9xSocketStartListening ( - const plNetAddress& listenAddr, - FAsyncNotifySocketProc notifyProc -); -void W9xSocketStopListening ( - const plNetAddress& listenAddr, - FAsyncNotifySocketProc notifyProc -); -void W9xSocketEnableNagling ( - AsyncSocket conn, - bool enable -); - - -} // namespace W9x diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xSocket.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xSocket.cpp deleted file mode 100644 index b693e0e1..00000000 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xSocket.cpp +++ /dev/null @@ -1,1224 +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 . - -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/pnAceW9xSocket.cpp -* -***/ - -#include "../../Pch.h" -#pragma hdrstop - -#include "pnAceW9xInt.h" - - -namespace W9x { - -/***************************************************************************** -* -* Private data -* -***/ - -static HWND s_window; - - -/**************************************************************************** -* -* CSocketMapper -* -***/ - -class CSocket; - -class CSocketMapper { -private: - struct Map { - AsyncCancelId sequence; - SOCKET sock; - UINT message; - CSocket * object; - FAsyncNotifySocketProc notifyProc; - }; - - ARRAY(Map) m_mapTable; - -public: - void Add ( - AsyncCancelId sequence, - CSocket * object, - UINT message, - SOCKET sock, - FAsyncNotifySocketProc notifyProc - ); - void Delete (CSocket * object); - CSocket * Find (AsyncCancelId sequence) const; - CSocket * Find (CSocket * object) const; - CSocket * Find (UINT message, SOCKET sock) const; - CSocket * Find (FAsyncNotifySocketProc notifyProc, unsigned index) const; - -}; - -//=========================================================================== -void CSocketMapper::Add ( - AsyncCancelId sequence, - CSocket * object, - UINT message, - SOCKET sock, - FAsyncNotifySocketProc notifyProc -) { - Map * mapping = m_mapTable.New(); - mapping->sequence = sequence; - mapping->object = object; - mapping->message = message; - mapping->sock = sock; - mapping->notifyProc = notifyProc; -} - -//=========================================================================== -void CSocketMapper::Delete (CSocket * object) { - for (unsigned index = m_mapTable.Count() - 1; index < m_mapTable.Count(); ) - if (m_mapTable[index].object == object) - if (index + 1 < m_mapTable.Count()) - m_mapTable[index] = m_mapTable.Pop(); - else - m_mapTable.Pop(); - else - --index; -} - -//=========================================================================== -CSocket * CSocketMapper::Find (AsyncCancelId sequence) const { - for (const Map * curr = m_mapTable.Ptr(), * term = m_mapTable.Term(); - curr != term; - ++curr) - if (curr->sequence == sequence) - return curr->object; - return nil; -} - -//=========================================================================== -CSocket * CSocketMapper::Find (CSocket * object) const { - for (const Map * curr = m_mapTable.Ptr(), * term = m_mapTable.Term(); - curr != term; - ++curr) - if (curr->object == object) - return curr->object; - return nil; -} - -//=========================================================================== -CSocket * CSocketMapper::Find (UINT message, SOCKET sock) const { - for (const Map * curr = m_mapTable.Ptr(), * term = m_mapTable.Term(); - curr != term; - ++curr) - if ((curr->message == message) && (curr->sock == sock)) - return curr->object; - return nil; -} - -//=========================================================================== -CSocket * CSocketMapper::Find (FAsyncNotifySocketProc notifyProc, unsigned index) const { - for (const Map * curr = m_mapTable.Ptr(), * term = m_mapTable.Term(); - curr != term; - ++curr) - if ((curr->notifyProc == notifyProc) && !index--) - return curr->object; - return nil; -} - -static CSocketMapper s_mapper; - - -/**************************************************************************** -* -* CSocket -* -***/ - -class CSocket { -private: - - // These constants are used to track whether a socket has been connected, - // and whether it has been disconnected. We do not track whether we have - // dispatched a connection failure notification, because socket objects - // are deleted immediately after dispatching that notification. - enum { kDispatchedConnectSuccess = (1 << 0) }; - enum { kDispatchedDisconnect = (1 << 1) }; - - struct Command { - LINK(Command) link; - enum Code { - CONNECT, - WRITE, - } code; - void * param; - union { - struct { - uint8_t connType; - } connect; - struct { - const void * data; // pointer to application's data - unsigned bytes; - } write; - }; - }; - - // These variables are protected by the critical section - CCritSect m_critSect; - LISTDECL(Command, link) m_commandList; - ARRAY(uint8_t) m_sendQueue; - - // These variables are never modified outside the constructor and - // destructor - UINT m_message; - FAsyncNotifySocketProc m_notifyProc; - AsyncCancelId m_sequence; - SOCKET m_sock; - - // These variables are only ever touched during a callback from the - // window procedure, which is single threaded - unsigned m_dispatched; - uint8_t m_readBuffer[1460 * 2]; - unsigned m_readBytes; - void * m_userState; - -public: - CSocket ( - AsyncCancelId sequence, - UINT message, - SOCKET sock, - FAsyncNotifySocketProc notifyProc - ); - ~CSocket (); - - void EnableNagling (bool enable); - void Disconnect (bool hardClose); - - inline AsyncCancelId GetSequence () const; - inline bool IsConnected () const; - inline bool IsDisconnected () const; - - void OnClose (); - void OnConnect (); - void OnReadReady (); - void OnWriteReady (); - - void ProcessQueue (); - void QueueConnect ( - void * param, - uint8_t connType - ); - void QueueWrite ( - void * param, - const void * data, - unsigned bytes - ); - - bool Send ( // returns false if disconnected - const void * data, - unsigned bytes - ); - -}; - -//=========================================================================== -CSocket::CSocket ( - AsyncCancelId sequence, - UINT message, - SOCKET sock, - FAsyncNotifySocketProc notifyProc -) : - m_dispatched(0), - m_notifyProc(notifyProc), - m_readBytes(0), - m_sequence(sequence), - m_message(message), - m_sock(sock), - m_userState(nil) -{ - - // Create a mapping for this socket - s_mapper.Add(sequence, this, message, sock, notifyProc); - -} - -//=========================================================================== -CSocket::~CSocket () { - - // If we dispatched a connect notification, verify that we also - // dispatched a disconnect notification - ASSERT(IsDisconnected() || !IsConnected()); - - // Delete the mapping for this socket - s_mapper.Delete(this); - - // Close the socket - closesocket(m_sock); - m_sock = INVALID_SOCKET; - - // Free memory - m_commandList.Clear(); - -} - -//=========================================================================== -void CSocket::EnableNagling (bool enable) { - BOOL arg = !enable; - int result = setsockopt( - m_sock, - IPPROTO_TCP, - TCP_NODELAY, - (const char *)&arg, - sizeof(arg) - ); - if (result) - LogMsg(kLogFatal, "failed: setsockopt"); -} - -//=========================================================================== -void CSocket::Disconnect (bool hardClose) { - - // This function is called outside the critical section, which is - // necessary to avoid deadlocks, so it must not modify the object state. - // The purpose of this function is to cause WinSock to generate a - // FD_CLOSE notification, which will initiate synchronous destruction - // of the socket. - - if (m_sock == INVALID_SOCKET) - return; - - // Shutdown the socket -// const unsigned SD_BOTH = 2; - shutdown(m_sock, SD_BOTH); - - // Windows always waits for an acknowledgement back from the other end - // of the connection, so we post our own FD_CLOSE notification if we need - // to terminate this socket immediately. Our notification processing code - // is robust against receiving the eventual FD_CLOSE from Windows even - // if another socket has been allocated in the interrim with the same - // socket handle. - if (hardClose) - PostMessage(s_window, m_message, m_sock, MAKELONG(FD_CLOSE, 0)); - -} - -//=========================================================================== -AsyncCancelId CSocket::GetSequence () const { - return m_sequence; -} - -//=========================================================================== -bool CSocket::IsConnected () const { - return (m_dispatched & kDispatchedConnectSuccess) != 0; -} - -//=========================================================================== -bool CSocket::IsDisconnected () const { - return (m_dispatched & kDispatchedDisconnect) != 0; -} - -//=========================================================================== -void CSocket::OnClose () { - - // If we haven't yet dispatched a connection notification, then - // dispatch a failure to connect rather than dispatching a disconnect - // notification - if (!IsConnected()) { - OnConnect(); - return; - } - - // Verify that we haven't already dispatched a disconnect notification - if (IsDisconnected()) - return; - - // Process any remaining queued commands - ProcessQueue(); - - // Remove the mapping for this object so that we will never dispatch - // another event to it - s_mapper.Delete(this); - - // Dispatch the disconnection notificaton - m_dispatched |= kDispatchedDisconnect; - m_notifyProc( - (AsyncSocket)this, - kNotifySocketDisconnect, - nil, // notify - &m_userState - ); - - // This function must not perform any processing after returning from - // the notification, because the application may have deleted the socket - // out from under us - -} - -//=========================================================================== -void CSocket::OnConnect () { - - // Verify that we haven't already dispatched a connection success - // message. We know that we haven't already dispatched a connection - // failure message, because the socket object would have already been - // deleted in that case. - if (IsConnected()) - return; - - // Verify that a connect command is queued - m_critSect.Enter(); - Command * command = m_commandList.Head(); - if (command && (command->code == command->CONNECT)) - m_commandList.Unlink(command); - else - command = nil; - m_critSect.Leave(); - if (!command) - return; - - // Check for an error - int error; - int errorLen = sizeof(error); - int result = getsockopt( - m_sock, - SOL_SOCKET, - SO_ERROR, - (char *)&error, - &errorLen - ); - if (result) - LogMsg(kLogFatal, "failed: getsockopt"); - - // Get addresses for the connection notification - AsyncNotifySocketConnect notify; - memset(¬ify.localAddr, 0, sizeof(notify.localAddr)); - memset(¬ify.remoteAddr, 0, sizeof(notify.remoteAddr)); - int nameLen = sizeof(notify.localAddr); - if (getsockname(m_sock, (sockaddr *)¬ify.localAddr, &nameLen)) - if (GetLastError() == WSAENOTCONN) - error = WSAENOTCONN; - else - LogMsg(kLogFatal, "failed: getsockname"); - nameLen = sizeof(notify.remoteAddr); - if (getpeername(m_sock, (sockaddr *)¬ify.remoteAddr, &nameLen)) - if (GetLastError() == WSAENOTCONN) - error = WSAENOTCONN; - else - LogMsg(kLogFatal, "failed: getpeername"); - - // Dispatch the connection notification - notify.param = command->param; - notify.asyncId = 0; - notify.connType = command->connect.connType; - bool notifyResult = m_notifyProc( - error ? nil : (AsyncSocket)this, - error ? kNotifySocketConnectFailed : kNotifySocketConnectSuccess, - ¬ify, - &m_userState - ); - - // Delete the connect command - delete command; - - // Handle failure to connect - if (error) { - - // Destroy the socket - delete this; - - } - - // Handle a successful connection - else { - - // Mark the socket as connected - m_dispatched |= kDispatchedConnectSuccess; - - // If the application requested the socket closed, disconnect it - if (!notifyResult) { - Disconnect(true); - OnClose(); - } - - } - -} - -//=========================================================================== -void CSocket::OnReadReady () { - for (;;) { - - // Issue the read - int recvResult = recv( - m_sock, - (char *)(m_readBuffer + m_readBytes), - sizeof(m_readBuffer) - m_readBytes, - 0 // flags - ); - if (recvResult == SOCKET_ERROR) - if (GetLastError() == WSAEWOULDBLOCK) - return; - else - LogMsg(kLogFatal, "failed: recv"); - - // If the socket reported disconnection, close it - if ((recvResult == SOCKET_ERROR) || !recvResult) { - Disconnect(true); - OnClose(); - return; - } - - // Update the read buffer state - m_readBytes += recvResult; - - // Dispatch a read notification - AsyncNotifySocketRead notify; - notify.param = nil; - notify.asyncId = 0; - notify.buffer = m_readBuffer; - notify.bytes = m_readBytes; - notify.bytesProcessed = 0; - bool notifyResult = m_notifyProc( - (AsyncSocket)this, - kNotifySocketRead, - ¬ify, - &m_userState - ); - - // If the application processed data, remove it from the read buffer - if (notify.bytesProcessed >= m_readBytes) - m_readBytes = 0; - else if (notify.bytesProcessed) { - memmove( - &m_readBuffer[0], - &m_readBuffer[notify.bytesProcessed], - m_readBytes - notify.bytesProcessed - ); - m_readBytes -= notify.bytesProcessed; - } - - // If the application returned false from its notification procedure, - // disconnect - if (!notifyResult) { - Disconnect(false); - return; - } - - } -} - -//=========================================================================== -void CSocket::OnWriteReady () { - - // Verify that the socket is ready to send data - if (IsDisconnected() || !IsConnected()) - return; - - // Enter the critical section and verify that data is queued - m_critSect.Enter(); - if (!m_sendQueue.Bytes()) { - m_critSect.Leave(); - return; - } - - // Attempt to send queued data - int result = send( - m_sock, - (const char *)m_sendQueue.Ptr(), - m_sendQueue.Bytes(), - 0 - ); - if (result == SOCKET_ERROR) - if (GetLastError() == WSAEWOULDBLOCK) - result = 0; - else - LogMsg(kLogFatal, "failed: send"); - - // Dequeue sent bytes - if (result != SOCKET_ERROR) - if ((unsigned)result == m_sendQueue.Bytes()) - m_sendQueue.Clear(); - else if (result) { - memmove( - &m_sendQueue[0], - &m_sendQueue[result], - m_sendQueue.Bytes() - result - ); - static_assert(sizeof(m_sendQueue[0]) == sizeof(uint8_t), "SendQueue array members are an unexpected size"); - m_sendQueue.SetCount(m_sendQueue.Count() - result); - } - - // Leave the critical section - m_critSect.Leave(); - - // If the send failed, close the socket - if (result == SOCKET_ERROR) { - Disconnect(true); - OnClose(); - } - - -} - -//=========================================================================== -void CSocket::ProcessQueue () { - - // Verify that the socket is connected - if (IsDisconnected() || !IsConnected()) - return; - - // Dispatch each command in the queue - for (;;) { - - // Remove the next command from the queue - m_critSect.Enter(); - Command * command = m_commandList.Head(); - if (command) - m_commandList.Unlink(command); - m_critSect.Leave(); - if (!command) - break; - - // Dispatch it - switch (command->code) { - - case Command::WRITE: { - AsyncNotifySocketWrite notify; - notify.param = command->param; - notify.asyncId = 0; - notify.buffer = (uint8_t *)command->write.data; - notify.bytes = command->write.bytes; - notify.bytesProcessed = 0; - bool notifyResult = m_notifyProc( - (AsyncSocket)this, - kNotifySocketWrite, - ¬ify, - &m_userState - ); - if (!notifyResult) - Disconnect(false); - } - break; - - DEFAULT_FATAL(command->code); - } - - // Delete the command - delete command; - - } - -} - -//=========================================================================== -void CSocket::QueueConnect ( - void * param, - uint8_t connType -) { - ASSERT(!IsConnected() && !IsDisconnected()); - - Command * command = new Command; - command->code = command->CONNECT; - command->param = param; - command->connect.connType = connType; - m_commandList.Link(command); -} - -//=========================================================================== -void CSocket::QueueWrite ( - void * param, - const void * data, - unsigned bytes -) { - ASSERT(!IsDisconnected()); - - Command * command = new Command; - command->code = command->CONNECT; - command->param = param; - command->write.data = data; - command->write.bytes = bytes; - m_commandList.Link(command); -} - -//=========================================================================== -bool CSocket::Send ( // returns false if disconnected - const void * data, - unsigned bytes -) { - - // Verify that the socket has not been disconnected - if (IsDisconnected()) - return false; - - // Enter the critical section - m_critSect.Enter(); - - // Attempt to send the data immediately - int result; - if (IsConnected() && !m_sendQueue.Bytes()) { - result = send( - m_sock, - (const char *)data, - bytes, - 0 - ); - if ((result == SOCKET_ERROR) && (GetLastError() != WSAEWOULDBLOCK)) - LogMsg(kLogFatal, "failed: send"); - } - else - result = 0; - - // If we were unable to send the entire message, queue the unsent portion - if ((unsigned)result < bytes) { - m_sendQueue.Add( - (const uint8_t *)data + result, - bytes - result - ); - } - - // Leave the critical section - m_critSect.Leave(); - - return true; -} - - -/**************************************************************************** -* -* Window procedure -* -***/ - -#define CLASS_NAME "AsyncSelectWindow" - -#define WM_CANCEL_CONNECT (WM_USER + 0) -#define WM_PROCESS_QUEUE (WM_USER + 1) - -static CCritSect s_critSect; -static HANDLE s_readyEvent; -static HANDLE s_thread; - -static unsigned THREADCALL W9xSocketThreadProc (AsyncThread *); - -static LRESULT CALLBACK WndProc ( - HWND window, - UINT message, - WPARAM wParam, - LPARAM lParam -); - -//=========================================================================== -static void OnCancelConnect ( - AsyncCancelId sequence -) { - - // Find the associated object - s_critSect.Enter(); - CSocket * object = s_mapper.Find(sequence); - s_critSect.Leave(); - - // Force the object to dispatch connect success or failure. We must not - // reference this object after the call to OnConnect() returns, because - // it may have been deleted. - if (object) - object->OnConnect(); - -} - -//=========================================================================== -static void OnProcessQueue ( - AsyncCancelId sequence -) { - - // Find the associated object - s_critSect.Enter(); - CSocket * object = s_mapper.Find(sequence); - s_critSect.Leave(); - - // Process the object's dispatch queue - if (object) - object->ProcessQueue(); - -} - -//=========================================================================== -static void OnSocketEvent ( - UINT message, - SOCKET sock, - long event -) { - - // Enter the critical section - s_critSect.Enter(); - - // Find the associated object - CSocket * object = s_mapper.Find(message, sock); - - // Verify that the object has not been disconnected. An object that - // has been disconnected can be deleted at any time, and therefore - // can't be referenced outside the critical section. However, the - // object cannot possibly have been disconnected here because objects - // once connected are only disconnected during a call to OnClose(), - // which is the last event we process for an object. - ASSERT(!object || !object->IsDisconnected()); - - // Leave the critical section - s_critSect.Leave(); - - // Dispatch the event - if (object) - switch (event) { - case FD_CLOSE: object->OnClose(); break; - case FD_CONNECT: object->OnConnect(); break; - case FD_READ: object->OnReadReady(); break; - case FD_WRITE: object->OnWriteReady(); break; - } - - // We must not reference the object after dispatching the event, - // because the event processor may have deleted it - -} - -//=========================================================================== -static void PostCancelConnect (AsyncCancelId sequence) { - s_critSect.Enter(); - if (s_window) - PostMessage(s_window, WM_CANCEL_CONNECT, 0, (LPARAM)sequence); - s_critSect.Leave(); -} - -//=========================================================================== -static void PostProcessQueue (AsyncCancelId sequence) { - s_critSect.Enter(); - if (s_window) - PostMessage(s_window, WM_PROCESS_QUEUE, 0, (LPARAM)sequence); - s_critSect.Leave(); -} - -//=========================================================================== -static void ShutdownWindow () { - s_critSect.Enter(); - - // Close the window - if (s_window) { - PostMessage(s_window, WM_CLOSE, 0, 0); - s_window = 0; - } - - // Close the thread - if (s_thread) { - HANDLE thread = s_thread; - s_thread = 0; - s_critSect.Leave(); - WaitForSingleObject(thread, INFINITE); - s_critSect.Enter(); - } - - // Close the ready event - if (s_readyEvent) { - CloseHandle(s_readyEvent); - s_readyEvent = 0; - } - - s_critSect.Leave(); -} - -//=========================================================================== -static HWND StartupWindow () { - - s_critSect.Enter(); - - // Check whether we need to create the window - if (!s_window) { - - // Check whether we need to create the thread - if (!s_thread) { - - // Create an object which the thread can use to signal creation - // of the window - ASSERT(!s_readyEvent); - s_readyEvent = CreateEvent(nil, TRUE, FALSE, nil); - - // Create a thread which will create the window and run its - // message loop - s_thread = (HANDLE) AsyncThreadCreate( - W9xSocketThreadProc, - nil, - L"W9xSockThread" - ); - - } - - // Wait for the thread to create the window - HANDLE event = s_readyEvent; - s_critSect.Leave(); - WaitForSingleObject(event, INFINITE); - s_critSect.Enter(); - - } - - // Return the window handle - HWND window = s_window; - s_critSect.Leave(); - return window; - -} - -//=========================================================================== -static unsigned THREADCALL W9xSocketThreadProc (AsyncThread *) { - ASSERT(!s_window); - - // Enter the critical section - s_critSect.Enter(); - - // Register the window class - HINSTANCE instance = (HINSTANCE)GetModuleHandle(nil); - WNDCLASS wndClass; - memset(&wndClass, 0, sizeof(wndClass)); - wndClass.lpfnWndProc = WndProc; - wndClass.hInstance = instance; - wndClass.lpszClassName = CLASS_NAME; - RegisterClass(&wndClass); - - // Create the window - s_window = CreateWindow( - CLASS_NAME, - CLASS_NAME, - WS_OVERLAPPED, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - 0, // parent window - 0, // menu - instance, - nil // param - ); - - // Leave the critical section - s_critSect.Leave(); - - // Trigger an event to allow anyone blocking on window creation to proceed - SetEvent(s_readyEvent); - - // Dispatch messages - MSG msg; - while (GetMessage(&msg, nil, 0, 0)) - if (msg.message == WM_CLOSE) - break; - else { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - // Destroy the window - s_critSect.Enter(); - if (s_window) { - DestroyWindow(s_window); - s_window = 0; - } - s_critSect.Leave(); - - return 0; -} - -//=========================================================================== -static LRESULT CALLBACK WndProc ( - HWND window, - UINT message, - WPARAM wParam, - LPARAM lParam -) { - switch (message) { - - case WM_CANCEL_CONNECT: - OnCancelConnect((AsyncCancelId)lParam); - return 0; - - case WM_PROCESS_QUEUE: - OnProcessQueue((AsyncCancelId)lParam); - return 0; - - default: - if ((message >= WM_APP) && (message < 0xc000)) - OnSocketEvent(message, (SOCKET)wParam, WSAGETSELECTEVENT(lParam)); - else - return DefWindowProc(window, message, wParam, lParam); - break; - - } - return 0; -} - - -/**************************************************************************** -* -* Exported functions -* -***/ - -//=========================================================================== -void W9xSocketConnect ( - AsyncCancelId * cancelId, - const plNetAddress& netAddr, - FAsyncNotifySocketProc notifyProc, - void * param, - const void * sendData, - unsigned sendBytes, - unsigned connectMs, - unsigned localPort -) { - // If necessary, startup the window and message queue - HWND window = StartupWindow(); - - // Create a socket - SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (!sock) - LogMsg(kLogFatal, "failed: socket"); - - // Assign a sequence number - static unsigned s_sequence; - AsyncCancelId sequence = (AsyncCancelId)++s_sequence; - if (!sequence) - sequence = (AsyncCancelId)++s_sequence; - *cancelId = sequence; - - // Assign a message id - static UINT s_message; - UINT message = (s_message++ & 0x3fff) | WM_APP; // range 0x8000 - 0xbfff - - // Create a socket object - CSocket * object = new CSocket( - sequence, - message, - sock, - notifyProc - ); - - // Queue a connect notification for the socket - object->QueueConnect( - param, - sendBytes ? ((const uint8_t *)sendData)[0] : (uint8_t)0 - ); - - // Queue sending data - if (sendBytes) - object->Send(sendData, sendBytes); - - // Setup notifications for the socket - int result = WSAAsyncSelect( - sock, - window, - message, - FD_CLOSE | FD_CONNECT | FD_READ | FD_WRITE - ); - if (result) - LogMsg(kLogFatal, "failed: WSAAsyncSelect"); - - // Start the connection - if ( connect(sock, (const sockaddr *)&netAddr, sizeof(sockaddr)) && - (GetLastError() != WSAEWOULDBLOCK) ) - LogMsg(kLogFatal, "failed: connect. err=%u", GetLastError()); - -} - -//=========================================================================== -void W9xSocketConnectCancel ( - FAsyncNotifySocketProc notifyProc, - AsyncCancelId cancelId -) { - - // Enter the critical section - s_critSect.Enter(); - - // If a cancel id was given, cancel that one connection - if (cancelId) - PostCancelConnect(cancelId); - - // Otherwise, cancel all connections using the specified notification - // procedure - else - for (unsigned index = 0; ; ++index) { - - // Find the next socket object - CSocket * object = s_mapper.Find(notifyProc, index); - if (!object) - break; - - // If the object exists and is not yet connected, cancel it - if (object) - PostCancelConnect(object->GetSequence()); - - } - - // Leave the critical section - s_critSect.Leave(); - -} - -//=========================================================================== -void W9xSocketDelete ( - AsyncSocket sock -) { - - // Dereference the object - CSocket * object = (CSocket *)sock; - - // Delete the object - s_critSect.Enter(); - delete object; - s_critSect.Leave(); - -} - -//=========================================================================== -void W9xSocketDestroy () { - - // Shutdown the window and message queue - ShutdownWindow(); - -} - -//=========================================================================== -void W9xSocketEnableNagling ( - AsyncSocket sock, - bool enable -) { - - // Dereference the object - CSocket * object = (CSocket *)sock; - - // set nagling state - object->EnableNagling(enable); - -} - -//=========================================================================== -void W9xSocketDisconnect ( - AsyncSocket sock, - bool hardClose -) { - - // Dereference the object - CSocket * object = (CSocket *)sock; - - // Disconnect - object->Disconnect(hardClose); - -} - -//=========================================================================== -unsigned W9xSocketStartListening ( - const plNetAddress& listenAddr, - FAsyncNotifySocketProc notifyProc -) { - return 0; - -} - -//=========================================================================== -void W9xSocketStopListening ( - const plNetAddress& listenAddr, - FAsyncNotifySocketProc notifyProc -) { -} - -//=========================================================================== -bool W9xSocketSend ( - AsyncSocket sock, - const void * data, - unsigned bytes -) { - - // Dereference the object - CSocket * object = (CSocket *)sock; - - // Send the data - return object->Send(data, bytes); - -} - -//=========================================================================== -void W9xSocketSetNotifyProc ( - AsyncSocket sock, - FAsyncNotifySocketProc notifyProc -) { - // This provider does not allow changing the notification procedure - FATAL("SocketSetNotifyProc"); -} - -//=========================================================================== -void W9xSocketSetBacklogAlloc ( - AsyncSocket sock, - unsigned bufferSize -) { - - // This provider does not limit the maximum backlog allocation - -} - -//=========================================================================== -bool W9xSocketWrite ( - AsyncSocket sock, - const void * data, - unsigned bytes, - void * param -) { - - // Dereference the object - CSocket * object = (CSocket *)sock; - - // Send the data - if (!object->Send(data, bytes)) - return false; - - // Queue a completion notification - object->QueueWrite(param, data, bytes); - - // Trigger processing the queue - PostProcessQueue(object->GetSequence()); - - return true; -} - - -} // namespace W9x diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xThread.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xThread.cpp deleted file mode 100644 index cf291ac8..00000000 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xThread.cpp +++ /dev/null @@ -1,451 +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 . - -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/pnAceW9xThread.cpp -* -***/ - -#include "../../Pch.h" -#pragma hdrstop - -#include "pnAceW9xInt.h" - - -namespace W9x { - -/***************************************************************************** -* -* Private data -* -***/ - -const unsigned kThreadCount = 2; - -static CCritSect s_critSect; -static bool s_destroying; -static HANDLE s_destroyEvent; -static unsigned s_sequence; -static HANDLE s_shutdownEvent; -static HANDLE s_signalEvent; -static HANDLE s_thread[kThreadCount]; - - -/**************************************************************************** -* -* ThreadWaitRec -* -***/ - -struct ThreadWaitRec { - HANDLE event; - LINK(ThreadWaitRec) link; -}; - - -/**************************************************************************** -* -* CThreadDispRec -* -***/ - -class CThreadDispRec { -private: - CThreadDispObject * m_object; - void * m_op; - AsyncId m_ioId; - LISTDECL(ThreadWaitRec, link) m_waitList; - -public: - LINK(CThreadDispRec) m_link; - - CThreadDispRec ( - CThreadDispObject * object, - void * op, - AsyncId * asyncId - ); - ~CThreadDispRec (); - - void Complete (CCritSect * critSect); - AsyncId GetId () const { return m_ioId; } - void LinkWait (ThreadWaitRec * wait); - -}; - -static LISTDECL(CThreadDispRec, m_link) s_dispList; -static LISTDECL(CThreadDispRec, m_link) s_dispInProcList; - -//=========================================================================== -CThreadDispRec::CThreadDispRec ( - CThreadDispObject * object, - void * op, - AsyncId * asyncId -) : - m_object(object), - m_op(op) -{ - s_critSect.Enter(); - - // Verify that this module is not being destroyed - ASSERT(!s_destroying); - - // Increment the owning object's reference count - object->IncRef(); - - // Assign an id - m_ioId = (AsyncId)++s_sequence; - if (!m_ioId) - m_ioId = (AsyncId)++s_sequence; - *asyncId = m_ioId; - - // Link this record to the dispatch list - s_dispList.Link(this); - - s_critSect.Leave(); -} - -//=========================================================================== -CThreadDispRec::~CThreadDispRec () { - - // Delete the operation data - CThreadDispObject * object = m_object; - object->Delete(m_op); - - s_critSect.Enter(); - - // Unlink this record - m_link.Unlink(); - - // Wake up all threads blocking on this operation. We must unlink each - // wait record before we signal it. - for (ThreadWaitRec * rec; (rec = m_waitList.Head()) != nil; ) { - m_waitList.Unlink(rec); - SetEvent(rec->event); - } - - // Decrement the owning object's reference count - object->DecRef(); - - s_critSect.Leave(); - -} - -//=========================================================================== -void CThreadDispRec::Complete (CCritSect * critSect) { - m_object->Complete(m_op, critSect, m_ioId); -} - -//=========================================================================== -void CThreadDispRec::LinkWait (ThreadWaitRec * wait) { - - // The caller should have already claimed the critical section before - // calling this function - - m_waitList.Link(wait); - -} - - -/**************************************************************************** -* -* CThreadDispObject -* -***/ - -//=========================================================================== -CThreadDispObject::CThreadDispObject () { - IncRef(); -} - -//=========================================================================== -void CThreadDispObject::Close () { - s_critSect.Enter(); - DecRef(); - s_critSect.Leave(); -} - -//=========================================================================== -AsyncId CThreadDispObject::Queue (void * op) { - AsyncId asyncId = 0; - new CThreadDispRec(this, op, &asyncId); - SetEvent(s_signalEvent); - return asyncId; -} - - -/**************************************************************************** -* -* Thread procedure -* -***/ - -//=========================================================================== -static unsigned THREADCALL W9xThreadProc (AsyncThread *) { - - // Perform the main thread loop - for (;;) { - unsigned timeout = (unsigned)-1; - - // If an operation is queued, complete it and dispatch a notification. - // The code that processes the operation is responsible for leaving - // our critical section. This ensures that operations are completed - // in order. - s_critSect.Enter(); - CThreadDispRec * rec = s_dispList.Head(); - if (rec) { - s_dispInProcList.Link(rec); - rec->Complete(&s_critSect); - delete rec; - timeout = 0; - } - else { - s_critSect.Leave(); - } - - - // Consume events, check for destruction, and block if we have - // nothing to do. - HANDLE events[] = {s_destroyEvent, s_signalEvent}; - uint32_t result = WaitForMultipleObjects( - arrsize(events), - events, - FALSE, - INFINITE - ); - if (result == WAIT_OBJECT_0) - return 0; - } -} - - -/**************************************************************************** -* -* Exported functions -* -***/ - -//=========================================================================== -void W9xThreadDestroy ( - unsigned exitThreadWaitMs -) { - - // Wait until all outstanding I/O is complete. We allow new I/O - // operations to be queued while old ones are completing. - s_critSect.Enter(); - while (s_dispList.Head() || s_dispInProcList.Head()) { - s_critSect.Leave(); - Sleep(10); - s_critSect.Enter(); - } - - // Once all I/O operations are complete, we disallow any future - // I/O operations from being queued. - s_destroying = true; - s_critSect.Leave(); - - // Signal thread destruction - if (s_destroyEvent) - SetEvent(s_destroyEvent); - - // Wait for thread destruction - for (unsigned thread = kThreadCount; thread--; ) - if (s_thread[thread]) { - - // Wait for the thread to terminate - WaitForSingleObject(s_thread[thread], exitThreadWaitMs); - - // Close the thread handle - CloseHandle(s_thread[thread]); - s_thread[thread] = 0; - - } - - // Destroy internal modules - W9xSocketDestroy(); - - // Destroy events - if (s_destroyEvent) { - CloseHandle(s_destroyEvent); - s_destroyEvent = 0; - } - if (s_shutdownEvent) { - CloseHandle(s_shutdownEvent); - s_shutdownEvent = 0; - } - if (s_signalEvent) { - CloseHandle(s_signalEvent); - s_signalEvent = 0; - } - -} - -//=========================================================================== -void W9xThreadInitialize () { - - // Reset static variables - s_destroying = false; - - // Create a manual reset event to use for signaling thread destruction - if (s_destroyEvent) - ResetEvent(s_destroyEvent); - else { - s_destroyEvent = CreateEvent(nil, TRUE, FALSE, nil); - ASSERT(s_destroyEvent); - } - - // Create an auto-reset event to use for signaling the thread to process - // notifications - if (!s_signalEvent) { - s_signalEvent = CreateEvent(nil, FALSE, FALSE, nil); - ASSERT(s_signalEvent); - } - - // Create a manual reset event to use for signaling application shutdown - if (s_shutdownEvent) - ResetEvent(s_shutdownEvent); - else { - s_shutdownEvent = CreateEvent(nil, TRUE, FALSE, nil); - ASSERT(s_shutdownEvent); - } - - // Create threads - for (unsigned thread = 0; thread < kThreadCount; ++thread) { - if (!s_thread[thread]) { - s_thread[thread] = (HANDLE) AsyncThreadCreate( - W9xThreadProc, - (void *) thread, - L"W9xWorkerThread" - ); - } - } - -} - -//=========================================================================== -void W9xThreadSignalShutdown () { - SetEvent(s_shutdownEvent); -} - -//=========================================================================== -void W9xThreadSleep ( - unsigned sleepMs -) { - Sleep(sleepMs); -} - -//=========================================================================== -void W9xThreadWaitForShutdown () { - - // We know that the applicaton is finished initializing at this point. - // While it was still initializing, it may have returned an infinite - // sleep time from the idle procedure, which would prevent us from ever - // calling it again. Therefore, we trigger an idle callback here. - SetEvent(s_signalEvent); - - // Wait for the application to signal shutdown - WaitForSingleObject(s_shutdownEvent, INFINITE); - -} - -//=========================================================================== -bool W9xThreadWaitId ( - AsyncFile file, - AsyncId asyncId, - unsigned timeoutMs -) { - // Find a pending I/O operation with the given id - s_critSect.Enter(); - CThreadDispRec * disp; - for (disp = s_dispList.Head(); disp && (disp->GetId() != asyncId); disp = s_dispList.Next(disp)) - ; - if (!disp) - for (disp = s_dispInProcList.Head(); disp && (disp->GetId() != asyncId); disp = s_dispInProcList.Next(disp)) - ; - - // If we couldn't find the given id, the operation must have already - // completed, so return true. - if (!disp) { - s_critSect.Leave(); - return true; - } - - // The operation has not completed. If the timeout is zero, return - // false. - if (!timeoutMs) { - s_critSect.Leave(); - return false; - } - - // Create a wait event - HANDLE event = CreateEvent(nil, FALSE, FALSE, nil); - - // Create a wait record and link it to the I/O operation - ThreadWaitRec wait; - wait.event = event; - disp->LinkWait(&wait); - s_critSect.Leave(); - - // Wait for the operation to complete - DWORD result = WaitForSingleObject(event, timeoutMs); - - // If the operation completed then the dispatcher unlinked our wait - // record before signaling it. We can simply free the event and return. - if (result == WAIT_OBJECT_0) { - CloseHandle(event); - return true; - } - - // Unlink our wait record from the I/O operation - s_critSect.Enter(); - wait.link.Unlink(); - s_critSect.Leave(); - - // Free the event - CloseHandle(event); - - // Return false, because the operation did not complete during the - // timeout period - return false; - -} - -} // namespace W9x diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp index 518e2411..8d109840 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp @@ -65,7 +65,6 @@ static long s_perf[kNumAsyncPerfCounters]; ***/ AsyncApi g_api; -bool s_transgaming; /***************************************************************************** @@ -74,30 +73,6 @@ bool s_transgaming; * ***/ -//============================================================================ -static void DoTransgamingCheck () { -#ifdef HS_BUILD_FOR_WIN32 -#ifdef CLIENT - - HMODULE hMod = GetModuleHandle("ntdll"); - if (!hMod) - return; - - s_transgaming = GetProcAddress(hMod, "IsTransgaming") != nil; - -#endif -#endif -} - -//=========================================================================== -static void IAsyncInitUseW9x () { -#ifdef HS_BUILD_FOR_WIN32 - W9xGetApi(&g_api); -#else - ErrorAssert("W9x I/O Not supported on this platform"); -#endif -} - //=========================================================================== static void IAsyncInitUseNt () { #ifdef HS_BUILD_FOR_WIN32 @@ -120,13 +95,7 @@ static void IAsyncInitUseUnix () { //=========================================================================== static void IAsyncInitForClient () { #ifdef HS_BUILD_FOR_WIN32 - DoTransgamingCheck(); - if (s_transgaming) { - IAsyncInitUseW9x(); - } - else { - IAsyncInitUseNt(); - } + IAsyncInitUseNt(); #elif HS_BUILD_FOR_UNIX IAsyncInitUseUnix(); #else