From 6aa9bd0f77dcb5128167fae62e32aa5252fe85c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 2 Dec 2013 00:55:24 +0100 Subject: Renew the updater branch Now with some actual consensus on what the updater will do! --- mmc_updater/depends/win32cpp/thread.h | 241 ++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 mmc_updater/depends/win32cpp/thread.h (limited to 'mmc_updater/depends/win32cpp/thread.h') diff --git a/mmc_updater/depends/win32cpp/thread.h b/mmc_updater/depends/win32cpp/thread.h new file mode 100644 index 00000000..5564d888 --- /dev/null +++ b/mmc_updater/depends/win32cpp/thread.h @@ -0,0 +1,241 @@ +// Win32++ Version 7.2 +// Released: 5th AUgust 2011 +// +// David Nash +// email: dnash@bigpond.net.au +// url: https://sourceforge.net/projects/win32-framework +// +// +// Copyright (c) 2005-2011 David Nash +// +// Permission is hereby granted, free of charge, to +// any person obtaining a copy of this software and +// associated documentation files (the "Software"), +// to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, +// merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom +// the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +// +//////////////////////////////////////////////////////// + + +// The CThread class simplifies the use of threads with Win32++. +// To use threads in your Win32++ application, inherit a class from +// CThread, and override InitInstance. When your class is instanciated, +// a new thread is started, and the InitInstance function is called to +// run in the new thread. + +// If your thread is used to run one or more windows, InitInstance should +// return TRUE, causing the MessageLoop function to be called. If your +// thread doesn't require a MessageLoop, it should return FALSE. Threads +// which don't run a message loop as sometimes referred to as "worker" threads. + +// Note: It is your job to end the thread before CThread ends! +// To end a thread with a message loop, use PostQuitMessage on the thread. +// To end a thread without a message loop, set an event, and end the thread +// when the event is received. + +// Hint: It is never a good idea to use things like TerminateThread or ExitThread to +// end your thread. These represent poor programming techniques, and are likely +// to leak memory and resources. + +// More Hints for thread programming: +// 1) Avoid using SendMessage between threads, as this will cause one thread to wait for +// the other to respond. Use PostMessage between threads to avoid this problem. +// 2) Access to variables and resources shared between threads need to be made thread safe. +// Having one thread modify a resouce or variable while another thread is accessing it is +// a recipe for disaster. +// 3) Thread Local Storage (TLS) can be used to replace global variables to make them thread +// safe. With TLS, each thread gets its own copy of the variable. +// 4) Critical Sections can be used to make shared resources thread safe. +// 5) Window messages (including user defined messages) can be posted between GUI threads to +// communicate information between them. +// 6) Events (created by CreateEvent) can be used to comunicate information between threads +// (both GUI and worker threads). +// 7) Avoid using sleep to synchronise threads. Generally speaking, the various wait +// functions (e.g. WaitForSingleObject) will be better for this. + +// About Threads: +// Each program that executes has a "process" allocated to it. A process has one or more +// threads. Threads run independantly of each other. It is the job of the operating system +// to manage the running of the threads, and do the task switching between threads as required. +// Systems with multiple CPUs will be able to run as many threads simultaneously as there are +// CPUs. + +// Threads behave like a program within a program. When the main thread starts, the application +// runs the WinMain function and ends when WinMain ends. When another thread starts, it too +// will run the function provided to it, and end when that function ends. + + +#ifndef _WIN32XX_WINTHREAD_H_ +#define _WIN32XX_WINTHREAD_H_ + + +#include + + +namespace Win32xx +{ + + ////////////////////////////////////// + // Declaration of the CThread class + // + class CThread + { + public: + CThread(); + CThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag); + virtual ~CThread(); + + // Overridables + virtual BOOL InitInstance(); + virtual int MessageLoop(); + + // Operations + HANDLE GetThread() const; + int GetThreadID() const; + int GetThreadPriority() const; + DWORD ResumeThread() const; + BOOL SetThreadPriority(int nPriority) const; + DWORD SuspendThread() const; + + private: + CThread(const CThread&); // Disable copy construction + CThread& operator = (const CThread&); // Disable assignment operator + void CreateThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag); + static UINT WINAPI StaticThreadCallback(LPVOID pCThread); + + HANDLE m_hThread; // Handle of this thread + UINT m_nThreadID; // ID of this thread + }; + +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +namespace Win32xx +{ + + /////////////////////////////////////// + // Definitions for the CThread class + // + inline CThread::CThread() : m_hThread(0), m_nThreadID(0) + { + CreateThread(0, 0, CREATE_SUSPENDED); + } + + inline CThread::CThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag) + : m_hThread(0), m_nThreadID(0) + + { + // Valid argument values: + // pSecurityAttributes Either a pointer to SECURITY_ATTRIBUTES or 0 + // stack_size Either the stack size or 0 + // initflag Either CREATE_SUSPENDED or 0 + + CreateThread(pSecurityAttributes, stack_size, initflag); + } + + inline CThread::~CThread() + { + // A thread's state is set to signalled when the thread terminates. + // If your thread is still running at this point, you have a bug. + if (0 != WaitForSingleObject(m_hThread, 0)) + TRACE(_T("*** Error *** Ending CThread before ending its thread\n")); + + // Close the thread's handle + ::CloseHandle(m_hThread); + } + + inline void CThread::CreateThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag) + { + // NOTE: By default, the thread is created in the default state. + m_hThread = (HANDLE)_beginthreadex(pSecurityAttributes, stack_size, CThread::StaticThreadCallback, (LPVOID) this, initflag, &m_nThreadID); + + if (0 == m_hThread) + throw CWinException(_T("Failed to create thread")); + } + + inline HANDLE CThread::GetThread() const + { + assert(m_hThread); + return m_hThread; + } + + inline int CThread::GetThreadID() const + { + assert(m_hThread); + return m_nThreadID; + } + + inline int CThread::GetThreadPriority() const + { + assert(m_hThread); + return ::GetThreadPriority(m_hThread); + } + + inline BOOL CThread::InitInstance() + { + // Override this function to perform tasks when the thread starts. + + // return TRUE to run a message loop, otherwise return FALSE. + // A thread with a window must run a message loop. + return FALSE; + } + + inline int CThread::MessageLoop() + { + // Override this function if your thread needs a different message loop + return GetApp()->MessageLoop(); + } + + inline DWORD CThread::ResumeThread() const + { + assert(m_hThread); + return ::ResumeThread(m_hThread); + } + + inline DWORD CThread::SuspendThread() const + { + assert(m_hThread); + return ::SuspendThread(m_hThread); + } + + inline BOOL CThread::SetThreadPriority(int nPriority) const + { + assert(m_hThread); + return ::SetThreadPriority(m_hThread, nPriority); + } + + inline UINT WINAPI CThread::StaticThreadCallback(LPVOID pCThread) + // When the thread starts, it runs this function. + { + // Get the pointer for this CMyThread object + CThread* pThread = (CThread*)pCThread; + + if (pThread->InitInstance()) + return pThread->MessageLoop(); + + return 0; + } + +} + +#endif // #define _WIN32XX_WINTHREAD_H_ + -- cgit v1.2.3