1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WARNING: You should *NOT* be using this class directly. PlatformThread is 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the low-level platform-specific abstraction to the OS's threading interface. 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// You should instead be using a message-loop driven Thread, see thread.h. 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#ifndef BASE_THREADING_PLATFORM_THREAD_H_ 103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#define BASE_THREADING_PLATFORM_THREAD_H_ 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "build/build_config.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN) 183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <windows.h> 193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#elif defined(OS_POSIX) 203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <pthread.h> 213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_MACOSX) 223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <mach/mach.h> 233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#else // OS_POSIX && !OS_MACOSX 243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <unistd.h> 253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif 263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif 273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace base { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// PlatformThreadHandle should not be assumed to be a numeric type, since the 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// standard intends to allow pthread_t to be a structure. This means you 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// should not initialize it to a value, like 0. If it's a member variable, the 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// constructor can safely "value initialize" using () in the initializer list. 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef DWORD PlatformThreadId; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef void* PlatformThreadHandle; // HANDLE 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst PlatformThreadHandle kNullThreadHandle = NULL; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX) 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef pthread_t PlatformThreadHandle; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst PlatformThreadHandle kNullThreadHandle = 0; 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_MACOSX) 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef mach_port_t PlatformThreadId; 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else // OS_POSIX && !OS_MACOSX 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef pid_t PlatformThreadId; 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst PlatformThreadId kInvalidThreadId = 0; 49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A namespace for low-level thread functions. 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API PlatformThread { 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Implement this interface to run code on a background thread. Your 54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // ThreadMain method will be called on the newly created thread. 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen class BASE_API Delegate { 56201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 57201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual ~Delegate() {} 58201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void ThreadMain() = 0; 59201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 60201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Gets the current thread id, which may be useful for logging purposes. 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static PlatformThreadId CurrentId(); 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Yield the current thread so another thread can be scheduled. 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void YieldCurrentThread(); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sleeps for the specified duration (units are milliseconds). 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void Sleep(int duration_ms); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sets the thread name visible to a debugger. This has no effect otherwise. 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void SetName(const char* name); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Creates a new thread. The |stack_size| parameter can be 0 to indicate 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that the default stack size should be used. Upon success, 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |*thread_handle| will be assigned a handle to the newly created thread, 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and |delegate|'s ThreadMain method will be executed on the newly created 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // thread. 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: When you are done with the thread handle, you must call Join to 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // release system resources associated with the thread. You must ensure that 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the Delegate object outlives the thread. 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool Create(size_t stack_size, Delegate* delegate, 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PlatformThreadHandle* thread_handle); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // CreateNonJoinable() does the same thing as Create() except the thread 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cannot be Join()'d. Therefore, it also does not output a 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // PlatformThreadHandle. 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool CreateNonJoinable(size_t stack_size, Delegate* delegate); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Joins with a thread created via the Create function. This function blocks 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the caller until the designated thread exits. This will invalidate 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |thread_handle|. 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void Join(PlatformThreadHandle thread_handle); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} // namespace base 993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif // BASE_THREADING_PLATFORM_THREAD_H_ 101