1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/cplus/rcthread.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* RCThread.h */ 1.10 + 1.11 +#if defined(_RCTHREAD_H) 1.12 +#else 1.13 +#define _RCTHREAD_H 1.14 + 1.15 +#include "rcbase.h" 1.16 + 1.17 +#include <prthread.h> 1.18 + 1.19 +class RCInterval; 1.20 + 1.21 +class PR_IMPLEMENT(RCThreadPrivateData) 1.22 +{ 1.23 +public: 1.24 + RCThreadPrivateData(); 1.25 + RCThreadPrivateData(const RCThreadPrivateData&); 1.26 + 1.27 + virtual ~RCThreadPrivateData(); 1.28 + 1.29 + virtual void Release() = 0; 1.30 + 1.31 +}; /* RCThreadPrivateData */ 1.32 + 1.33 +class PR_IMPLEMENT(RCThread): public RCBase 1.34 +{ 1.35 +public: 1.36 + 1.37 + typedef enum 1.38 + { 1.39 + local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD 1.40 + } Scope; 1.41 + 1.42 + typedef enum 1.43 + { 1.44 + joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD 1.45 + } State; 1.46 + 1.47 + typedef enum 1.48 + { 1.49 + first = PR_PRIORITY_FIRST, 1.50 + low = PR_PRIORITY_LOW, 1.51 + normal = PR_PRIORITY_NORMAL, 1.52 + high = PR_PRIORITY_HIGH, 1.53 + urgent = PR_PRIORITY_URGENT, 1.54 + last = PR_PRIORITY_LAST 1.55 + } Priority; 1.56 + 1.57 + /* 1.58 + * Create a new thread, providing scope and joinability state. 1.59 + */ 1.60 + RCThread(Scope scope, State state, PRUint32 stackSize=0); 1.61 + 1.62 + /* 1.63 + * New threads are created in a suspended state. It must be 'started" 1.64 + * before it begins execution in the class' defined 'RootFunction()'. 1.65 + */ 1.66 + virtual PRStatus Start(); 1.67 + 1.68 + /* 1.69 + * If a thread is created joinable, then the thread's object exists 1.70 + * until join is called. The thread that calls join will block until 1.71 + * the target thread returns from it's root function. 1.72 + */ 1.73 + virtual PRStatus Join(); 1.74 + 1.75 + /* 1.76 + * The priority of a newly created thread is the same as the creator. 1.77 + * The priority may be changed either by the new thread itself, by 1.78 + * the creator or any other arbitrary thread. 1.79 + */ 1.80 + virtual void SetPriority(Priority newPriority); 1.81 + 1.82 + 1.83 + /* 1.84 + * Interrupt another thread, causing it to stop what it 1.85 + * is doing and return with a well known error code. 1.86 + */ 1.87 + virtual PRStatus Interrupt(); 1.88 + 1.89 + /* 1.90 + * And in case a thread was interrupted and didn't get a chance 1.91 + * to have the notification delivered, a way to cancel the pending 1.92 + * status. 1.93 + */ 1.94 + static void ClearInterrupt(); 1.95 + 1.96 + /* 1.97 + * Methods to discover the attributes of an existing thread. 1.98 + */ 1.99 + static PRThread *Self(); 1.100 + Scope GetScope() const; 1.101 + State GetState() const; 1.102 + Priority GetPriority() const; 1.103 + 1.104 + /* 1.105 + * Thread private data 1.106 + */ 1.107 + static PRStatus NewPrivateIndex(PRUintn* index); 1.108 + 1.109 + /* 1.110 + * Getting it - if you want to modify, make a copy 1.111 + */ 1.112 + static RCThreadPrivateData* GetPrivateData(PRUintn index); 1.113 + 1.114 + /* 1.115 + * Setting it to <empty> - deletes existing data 1.116 + */ 1.117 + static PRStatus SetPrivateData(PRUintn index); 1.118 + 1.119 + /* 1.120 + * Setting it - runtime will make a copy, freeing old iff necessary 1.121 + */ 1.122 + static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data); 1.123 + 1.124 + /* 1.125 + * Scheduling control 1.126 + */ 1.127 + static PRStatus Sleep(const RCInterval& ticks); 1.128 + 1.129 + friend void nas_Root(void*); 1.130 + friend class RCPrimordialThread; 1.131 +protected: 1.132 + 1.133 + /* 1.134 + * The instantiator of a class must not call the destructor. The base 1.135 + * implementation of Join will, and if the thread is created unjoinable, 1.136 + * then the code that called the RootFunction will call the desctructor. 1.137 + */ 1.138 + virtual ~RCThread(); 1.139 + 1.140 +private: 1.141 + 1.142 + /* 1.143 + * This is where a newly created thread begins execution. Returning 1.144 + * from this function is equivalent to terminating the thread. 1.145 + */ 1.146 + virtual void RootFunction() = 0; 1.147 + 1.148 + PRThread *identity; 1.149 + 1.150 + /* Threads are unstarted until started - pretty startling */ 1.151 + enum {ex_unstarted, ex_started} execution; 1.152 + 1.153 + /* There is no public default constructor or copy constructor */ 1.154 + RCThread(); 1.155 + RCThread(const RCThread&); 1.156 + 1.157 + /* And there is no assignment operator */ 1.158 + void operator=(const RCThread&); 1.159 + 1.160 +public: 1.161 + static RCPrimordialThread *WrapPrimordialThread(); 1.162 + 1.163 + }; 1.164 + 1.165 +/* 1.166 +** class RCPrimordialThread 1.167 +*/ 1.168 +class PR_IMPLEMENT(RCPrimordialThread): public RCThread 1.169 +{ 1.170 +public: 1.171 + /* 1.172 + ** The primordial thread can (optionally) wait for all created 1.173 + ** threads to terminate before allowing the process to exit. 1.174 + ** Not calling Cleanup() before returning from main() will cause 1.175 + ** the immediate termination of the entire process, including 1.176 + ** any running threads. 1.177 + */ 1.178 + static PRStatus Cleanup(); 1.179 + 1.180 + /* 1.181 + ** Only the primordial thread is allowed to adjust the number of 1.182 + ** virtual processors of the runtime. It's a lame security thing. 1.183 + */ 1.184 + static PRStatus SetVirtualProcessors(PRIntn count=10); 1.185 + 1.186 +friend class RCThread; 1.187 +private: 1.188 + /* 1.189 + ** None other than the runtime can create of destruct 1.190 + ** a primordial thread. It is fabricated by the runtime 1.191 + ** to wrap the thread that initiated the application. 1.192 + */ 1.193 + RCPrimordialThread(); 1.194 + ~RCPrimordialThread(); 1.195 + void RootFunction(); 1.196 +}; /* RCPrimordialThread */ 1.197 + 1.198 + #endif /* defined(_RCTHREAD_H) */