1 /**
2  * @file thread/win32thread.cpp
3  * @brief Win32 thread/mutex handling
4  *
5  * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
6  *
7  * This file is part of the MEGA SDK - Client Access Engine.
8  *
9  * Applications using the MEGA API must present a valid application key
10  * and comply with the the rules set forth in the Terms of Service.
11  *
12  * The MEGA SDK is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * @copyright Simplified (2-clause) BSD License.
17  *
18  * You should have received a copy of the license along with this
19  * program.
20  *
21  * This file is also distributed under the terms of the GNU General
22  * Public License, see http://www.gnu.org/copyleft/gpl.txt for details.
23  */
24 
25 #include "mega/thread/win32thread.h"
26 #include "mega/logging.h"
27 #include <limits.h>
28 
29 #ifdef _WIN32
30 #include "windows.h"
31 #endif
32 
33 namespace mega {
34 //Thread
Win32Thread()35 Win32Thread::Win32Thread()
36 {
37 
38 }
39 
run(LPVOID lpParameter)40 DWORD WINAPI Win32Thread::run(LPVOID lpParameter)
41 {
42     Win32Thread *object = (Win32Thread *)lpParameter;
43     object->start_routine(object->pointer);
44     return 0;
45 }
46 
start(void * (* start_routine)(void *),void * parameter)47 void Win32Thread::start(void *(*start_routine)(void*), void *parameter)
48 {
49     this->start_routine = start_routine;
50     this->pointer = parameter;
51 
52     hThread = CreateThread(NULL, 0, Win32Thread::run, this, 0, NULL);
53 }
54 
join()55 void Win32Thread::join()
56 {
57     WaitForSingleObject(hThread, INFINITE);
58 }
59 
currentThreadId()60 unsigned long long Win32Thread::currentThreadId()
61 {
62     return (unsigned long long) GetCurrentThreadId();
63 }
64 
~Win32Thread()65 Win32Thread::~Win32Thread()
66 {
67     CloseHandle(hThread);
68 }
69 
70 //Semaphore
Win32Semaphore()71 Win32Semaphore::Win32Semaphore()
72 {
73     semaphore = CreateSemaphore(NULL, 0, INT_MAX, NULL);
74     if (semaphore == NULL)
75     {
76         LOG_fatal << "Error creating semaphore: " << GetLastError();
77     }
78 }
79 
release()80 void Win32Semaphore::release()
81 {
82     if (!ReleaseSemaphore(semaphore, 1, NULL))
83     {
84         LOG_fatal << "Error in ReleaseSemaphore: " << GetLastError();
85     }
86 }
87 
wait()88 void Win32Semaphore::wait()
89 {
90     DWORD ret = WaitForSingleObject(semaphore, INFINITE);
91     if (ret == WAIT_OBJECT_0)
92     {
93         return;
94     }
95 
96     LOG_fatal << "Error in WaitForSingleObject: " << GetLastError();
97 }
98 
timedwait(int milliseconds)99 int Win32Semaphore::timedwait(int milliseconds)
100 {
101     DWORD ret = WaitForSingleObject(semaphore, milliseconds);
102     if (ret == WAIT_OBJECT_0)
103     {
104         return 0;
105     }
106 
107     if (ret == WAIT_TIMEOUT)
108     {
109         return -1;
110     }
111 
112     LOG_err << "Error in WaitForSingleObject: " << GetLastError();
113     return -2;
114 }
115 
~Win32Semaphore()116 Win32Semaphore::~Win32Semaphore()
117 {
118     CloseHandle(semaphore);
119 }
120 
121 } // namespace
122