Thread.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/System/Win32/Thread.hpp>
00029 #include <process.h>
00030 #include <iostream>
00031 
00032 
00036 sfThread::sfThread() :
00037 myHandle  (NULL),
00038 myFunction(NULL),
00039 myUserData(NULL)
00040 {
00041 
00042 }
00043 
00044 
00048 sfThread::sfThread(sfThread::FuncType Function, void* UserData) :
00049 myHandle  (NULL),
00050 myFunction(Function),
00051 myUserData(UserData)
00052 {
00053 
00054 }
00055 
00056 
00060 sfThread::~sfThread()
00061 {
00062     // Wait for the thread to finish before destroying the instance
00063     if (myHandle)
00064         Wait();
00065 }
00066 
00067 
00071 void sfThread::Launch()
00072 {
00073     // Create the thread
00074     myHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &sfThread::ThreadFunc, this, 0, NULL));
00075 
00076     // Error ?
00077     if (myHandle == NULL)
00078         std::cerr << "Failed to create thread" << std::endl;
00079 }
00080 
00081 
00085 void sfThread::Wait()
00086 {
00087     if (myHandle)
00088     {
00089         // Wait for the thread to finish, no timeout
00090         WaitForSingleObject(myHandle, INFINITE);
00091 
00092         // Don't forget to close the thread handle (__endthreadex doesn't do it)
00093         CloseHandle(myHandle);
00094         myHandle = NULL;
00095     }
00096 }
00097 
00098 
00105 void sfThread::Terminate()
00106 {
00107     if (myHandle)
00108     {
00109         TerminateThread(myHandle, 0);
00110         myHandle = NULL;
00111     }
00112 }
00113 
00114 
00118 void sfThread::Run()
00119 {
00120     if (myFunction)
00121         myFunction(myUserData);
00122 }
00123 
00124 
00128 unsigned int __stdcall sfThread::ThreadFunc(void* UserData)
00129 {
00130     // The sfThread instance is stored in the user data
00131     sfThread* Thread = reinterpret_cast<sfThread*>(UserData);
00132 
00133     // Forward to the instance
00134     Thread->Run();
00135 
00136     // Optional, but it is cleaner
00137     _endthreadex(0);
00138 
00139     return 0;
00140 }