rcthread.h (5171B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* RCThread.h */ 7 8 #if defined(_RCTHREAD_H) 9 #else 10 #define _RCTHREAD_H 11 12 #include "rcbase.h" 13 14 #include <prthread.h> 15 16 class RCInterval; 17 18 class PR_IMPLEMENT(RCThreadPrivateData) 19 { 20 public: 21 RCThreadPrivateData(); 22 RCThreadPrivateData(const RCThreadPrivateData&); 23 24 virtual ~RCThreadPrivateData(); 25 26 virtual void Release() = 0; 27 28 }; /* RCThreadPrivateData */ 29 30 class PR_IMPLEMENT(RCThread): public RCBase 31 { 32 public: 33 34 typedef enum 35 { 36 local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD 37 } Scope; 38 39 typedef enum 40 { 41 joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD 42 } State; 43 44 typedef enum 45 { 46 first = PR_PRIORITY_FIRST, 47 low = PR_PRIORITY_LOW, 48 normal = PR_PRIORITY_NORMAL, 49 high = PR_PRIORITY_HIGH, 50 urgent = PR_PRIORITY_URGENT, 51 last = PR_PRIORITY_LAST 52 } Priority; 53 54 /* 55 * Create a new thread, providing scope and joinability state. 56 */ 57 RCThread(Scope scope, State state, PRUint32 stackSize=0); 58 59 /* 60 * New threads are created in a suspended state. It must be 'started" 61 * before it begins execution in the class' defined 'RootFunction()'. 62 */ 63 virtual PRStatus Start(); 64 65 /* 66 * If a thread is created joinable, then the thread's object exists 67 * until join is called. The thread that calls join will block until 68 * the target thread returns from it's root function. 69 */ 70 virtual PRStatus Join(); 71 72 /* 73 * The priority of a newly created thread is the same as the creator. 74 * The priority may be changed either by the new thread itself, by 75 * the creator or any other arbitrary thread. 76 */ 77 virtual void SetPriority(Priority newPriority); 78 79 80 /* 81 * Interrupt another thread, causing it to stop what it 82 * is doing and return with a well known error code. 83 */ 84 virtual PRStatus Interrupt(); 85 86 /* 87 * And in case a thread was interrupted and didn't get a chance 88 * to have the notification delivered, a way to cancel the pending 89 * status. 90 */ 91 static void ClearInterrupt(); 92 93 /* 94 * Methods to discover the attributes of an existing thread. 95 */ 96 static PRThread *Self(); 97 Scope GetScope() const; 98 State GetState() const; 99 Priority GetPriority() const; 100 101 /* 102 * Thread private data 103 */ 104 static PRStatus NewPrivateIndex(PRUintn* index); 105 106 /* 107 * Getting it - if you want to modify, make a copy 108 */ 109 static RCThreadPrivateData* GetPrivateData(PRUintn index); 110 111 /* 112 * Setting it to <empty> - deletes existing data 113 */ 114 static PRStatus SetPrivateData(PRUintn index); 115 116 /* 117 * Setting it - runtime will make a copy, freeing old iff necessary 118 */ 119 static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data); 120 121 /* 122 * Scheduling control 123 */ 124 static PRStatus Sleep(const RCInterval& ticks); 125 126 friend void nas_Root(void*); 127 friend class RCPrimordialThread; 128 protected: 129 130 /* 131 * The instantiator of a class must not call the destructor. The base 132 * implementation of Join will, and if the thread is created unjoinable, 133 * then the code that called the RootFunction will call the desctructor. 134 */ 135 virtual ~RCThread(); 136 137 private: 138 139 /* 140 * This is where a newly created thread begins execution. Returning 141 * from this function is equivalent to terminating the thread. 142 */ 143 virtual void RootFunction() = 0; 144 145 PRThread *identity; 146 147 /* Threads are unstarted until started - pretty startling */ 148 enum {ex_unstarted, ex_started} execution; 149 150 /* There is no public default constructor or copy constructor */ 151 RCThread(); 152 RCThread(const RCThread&); 153 154 /* And there is no assignment operator */ 155 void operator=(const RCThread&); 156 157 public: 158 static RCPrimordialThread *WrapPrimordialThread(); 159 160 }; 161 162 /* 163 ** class RCPrimordialThread 164 */ 165 class PR_IMPLEMENT(RCPrimordialThread): public RCThread 166 { 167 public: 168 /* 169 ** The primordial thread can (optionally) wait for all created 170 ** threads to terminate before allowing the process to exit. 171 ** Not calling Cleanup() before returning from main() will cause 172 ** the immediate termination of the entire process, including 173 ** any running threads. 174 */ 175 static PRStatus Cleanup(); 176 177 /* 178 ** Only the primordial thread is allowed to adjust the number of 179 ** virtual processors of the runtime. It's a lame security thing. 180 */ 181 static PRStatus SetVirtualProcessors(PRIntn count=10); 182 183 friend class RCThread; 184 private: 185 /* 186 ** None other than the runtime can create of destruct 187 ** a primordial thread. It is fabricated by the runtime 188 ** to wrap the thread that initiated the application. 189 */ 190 RCPrimordialThread(); 191 ~RCPrimordialThread(); 192 void RootFunction(); 193 }; /* RCPrimordialThread */ 194 195 #endif /* defined(_RCTHREAD_H) */