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