1 /* 2 * Copyright 2011 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "test/platform_thread.h" 18 19 namespace sfntly { 20 21 #if defined (WIN32) 22 23 DWORD __stdcall ThreadFunc(void* params) { 24 PlatformThread::Delegate* delegate = 25 static_cast<PlatformThread::Delegate*>(params); 26 delegate->ThreadMain(); 27 return 0; 28 } 29 30 // static 31 bool PlatformThread::Create(Delegate* delegate, 32 PlatformThreadHandle* thread_handle) { 33 assert(thread_handle); 34 *thread_handle = CreateThread(NULL, 0, ThreadFunc, delegate, 0, NULL); 35 if (!(*thread_handle)) { 36 return false; 37 } 38 39 return true; 40 } 41 42 // static 43 void PlatformThread::Join(PlatformThreadHandle thread_handle) { 44 assert(thread_handle); 45 DWORD result = WaitForSingleObject(thread_handle, INFINITE); 46 assert(result == WAIT_OBJECT_0); 47 CloseHandle(thread_handle); 48 } 49 50 // static 51 void PlatformThread::Sleep(int32_t duration_ms) { 52 ::Sleep(duration_ms); 53 } 54 55 #else 56 57 void* ThreadFunc(void* params) { 58 PlatformThread::Delegate* delegate = 59 static_cast<PlatformThread::Delegate*>(params); 60 delegate->ThreadMain(); 61 return NULL; 62 } 63 64 // static 65 bool PlatformThread::Create(Delegate* delegate, 66 PlatformThreadHandle* thread_handle) { 67 assert(thread_handle); 68 69 bool success = false; 70 pthread_attr_t attributes; 71 pthread_attr_init(&attributes); 72 success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate); 73 pthread_attr_destroy(&attributes); 74 75 return success; 76 } 77 78 // static 79 void PlatformThread::Join(PlatformThreadHandle thread_handle) { 80 assert(thread_handle); 81 pthread_join(thread_handle, NULL); 82 } 83 84 // static 85 void PlatformThread::Sleep(int32_t duration_ms) { 86 struct timespec sleep_time, remaining; 87 88 // Contains the portion of duration_ms >= 1 sec. 89 sleep_time.tv_sec = duration_ms / 1000; 90 duration_ms -= sleep_time.tv_sec * 1000; 91 92 // Contains the portion of duration_ms < 1 sec. 93 sleep_time.tv_nsec = duration_ms * 1000 * 1000; // nanoseconds. 94 95 while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR) 96 sleep_time = remaining; 97 } 98 99 #endif // WIN32 100 101 } // namespace sfntly 102