Home | History | Annotate | Download | only in threading
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // WARNING: You should *NOT* be using this class directly.  PlatformThread is
      6 // the low-level platform-specific abstraction to the OS's threading interface.
      7 // You should instead be using a message-loop driven Thread, see thread.h.
      8 
      9 #ifndef BASE_THREADING_PLATFORM_THREAD_H_
     10 #define BASE_THREADING_PLATFORM_THREAD_H_
     11 
     12 #include "base/base_export.h"
     13 #include "base/basictypes.h"
     14 #include "base/time/time.h"
     15 #include "build/build_config.h"
     16 
     17 #if defined(OS_WIN)
     18 #include <windows.h>
     19 #elif defined(OS_POSIX)
     20 #include <pthread.h>
     21 #include <unistd.h>
     22 #endif
     23 
     24 namespace base {
     25 
     26 #if defined(OS_WIN)
     27 typedef DWORD PlatformThreadId;
     28 #elif defined(OS_POSIX)
     29 typedef pid_t PlatformThreadId;
     30 #endif
     31 
     32 class PlatformThreadHandle {
     33  public:
     34 #if defined(OS_WIN)
     35   typedef void* Handle;
     36 #elif defined(OS_POSIX)
     37   typedef pthread_t Handle;
     38 #endif
     39 
     40   PlatformThreadHandle()
     41       : handle_(0),
     42         id_(0) {
     43   }
     44 
     45   explicit PlatformThreadHandle(Handle handle)
     46       : handle_(handle),
     47         id_(0) {
     48   }
     49 
     50   PlatformThreadHandle(Handle handle,
     51                        PlatformThreadId id)
     52       : handle_(handle),
     53         id_(id) {
     54   }
     55 
     56   bool is_equal(const PlatformThreadHandle& other) {
     57     return handle_ == other.handle_;
     58   }
     59 
     60   bool is_null() {
     61     return !handle_;
     62   }
     63 
     64   Handle platform_handle() {
     65     return handle_;
     66   }
     67 
     68  private:
     69   friend class PlatformThread;
     70 
     71   Handle handle_;
     72   PlatformThreadId id_;
     73 };
     74 
     75 const PlatformThreadId kInvalidThreadId(0);
     76 
     77 // Valid values for SetThreadPriority()
     78 enum ThreadPriority{
     79   kThreadPriority_Normal,
     80   // Suitable for low-latency, glitch-resistant audio.
     81   kThreadPriority_RealtimeAudio,
     82   // Suitable for threads which generate data for the display (at ~60Hz).
     83   kThreadPriority_Display,
     84   // Suitable for threads that shouldn't disrupt high priority work.
     85   kThreadPriority_Background
     86 };
     87 
     88 // A namespace for low-level thread functions.
     89 class BASE_EXPORT PlatformThread {
     90  public:
     91   // Implement this interface to run code on a background thread.  Your
     92   // ThreadMain method will be called on the newly created thread.
     93   class BASE_EXPORT Delegate {
     94    public:
     95     virtual void ThreadMain() = 0;
     96 
     97    protected:
     98     virtual ~Delegate() {}
     99   };
    100 
    101   // Gets the current thread id, which may be useful for logging purposes.
    102   static PlatformThreadId CurrentId();
    103 
    104   // Get the current handle.
    105   static PlatformThreadHandle CurrentHandle();
    106 
    107   // Yield the current thread so another thread can be scheduled.
    108   static void YieldCurrentThread();
    109 
    110   // Sleeps for the specified duration.
    111   static void Sleep(base::TimeDelta duration);
    112 
    113   // Sets the thread name visible to debuggers/tools. This has no effect
    114   // otherwise. This name pointer is not copied internally. Thus, it must stay
    115   // valid until the thread ends.
    116   static void SetName(const char* name);
    117 
    118   // Gets the thread name, if previously set by SetName.
    119   static const char* GetName();
    120 
    121   // Creates a new thread.  The |stack_size| parameter can be 0 to indicate
    122   // that the default stack size should be used.  Upon success,
    123   // |*thread_handle| will be assigned a handle to the newly created thread,
    124   // and |delegate|'s ThreadMain method will be executed on the newly created
    125   // thread.
    126   // NOTE: When you are done with the thread handle, you must call Join to
    127   // release system resources associated with the thread.  You must ensure that
    128   // the Delegate object outlives the thread.
    129   static bool Create(size_t stack_size, Delegate* delegate,
    130                      PlatformThreadHandle* thread_handle);
    131 
    132   // CreateWithPriority() does the same thing as Create() except the priority of
    133   // the thread is set based on |priority|.  Can be used in place of Create()
    134   // followed by SetThreadPriority().  SetThreadPriority() has not been
    135   // implemented on the Linux platform yet, this is the only way to get a high
    136   // priority thread on Linux.
    137   static bool CreateWithPriority(size_t stack_size, Delegate* delegate,
    138                                  PlatformThreadHandle* thread_handle,
    139                                  ThreadPriority priority);
    140 
    141   // CreateNonJoinable() does the same thing as Create() except the thread
    142   // cannot be Join()'d.  Therefore, it also does not output a
    143   // PlatformThreadHandle.
    144   static bool CreateNonJoinable(size_t stack_size, Delegate* delegate);
    145 
    146   // Joins with a thread created via the Create function.  This function blocks
    147   // the caller until the designated thread exits.  This will invalidate
    148   // |thread_handle|.
    149   static void Join(PlatformThreadHandle thread_handle);
    150 
    151   static void SetThreadPriority(PlatformThreadHandle handle,
    152                                 ThreadPriority priority);
    153 
    154  private:
    155   DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread);
    156 };
    157 
    158 }  // namespace base
    159 
    160 #endif  // BASE_THREADING_PLATFORM_THREAD_H_
    161