Branan Purvine-Riley
12 years ago
12 changed files with 13 additions and 2373 deletions
@ -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 <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/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; |
|
||||||
} |
|
@ -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 <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/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
|
|
@ -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 <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/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
|
|
File diff suppressed because it is too large
Load Diff
@ -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 <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/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
|
|
Loading…
Reference in new issue