Back to index

lightning-sunbird  0.9+nobinonly
rcthread.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* RCThread.h */
00039 
00040 #if defined(_RCTHREAD_H)
00041 #else
00042 #define _RCTHREAD_H
00043 
00044 #include "rcbase.h"
00045 
00046 #include <prthread.h>
00047 
00048 class RCInterval;
00049 
00050 class PR_IMPLEMENT(RCThreadPrivateData)
00051 {
00052 public:
00053     RCThreadPrivateData();
00054     RCThreadPrivateData(const RCThreadPrivateData&);
00055 
00056     virtual ~RCThreadPrivateData();
00057 
00058     virtual void Release() = 0;
00059 
00060 };  /* RCThreadPrivateData */
00061 
00062 class PR_IMPLEMENT(RCThread): public RCBase
00063 {
00064 public:
00065 
00066     typedef enum 
00067     {
00068         local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD
00069     } Scope;
00070 
00071     typedef enum
00072     {
00073         joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD
00074     } State;
00075 
00076     typedef enum
00077     {
00078         first = PR_PRIORITY_FIRST,
00079         low = PR_PRIORITY_LOW,
00080         normal = PR_PRIORITY_NORMAL,
00081         high = PR_PRIORITY_HIGH,
00082         urgent = PR_PRIORITY_URGENT,
00083         last = PR_PRIORITY_LAST
00084     } Priority;
00085 
00086     /*
00087      * Create a new thread, providing scope and joinability state.
00088      */
00089     RCThread(Scope scope, State state, PRUint32 stackSize=0);
00090 
00091     /*
00092      * New threads are created in a suspended state. It must be 'started"
00093      * before it begins execution in the class' defined 'RootFunction()'.
00094      */
00095     virtual PRStatus Start();
00096 
00097     /*
00098      * If a thread is created joinable, then the thread's object exists
00099      * until join is called. The thread that calls join will block until
00100      * the target thread returns from it's root function.
00101      */
00102     virtual PRStatus Join();
00103     
00104     /*
00105      * The priority of a newly created thread is the same as the creator.
00106      * The priority may be changed either by the new thread itself, by
00107      * the creator or any other arbitrary thread.
00108      */   
00109     virtual void SetPriority(Priority newPriority);
00110 
00111 
00112     /*
00113      * Interrupt another thread, causing it to stop what it
00114      * is doing and return with a well known error code.
00115      */
00116     virtual PRStatus Interrupt();
00117     
00118     /*
00119      * And in case a thread was interrupted and didn't get a chance
00120      * to have the notification delivered, a way to cancel the pending
00121      * status.
00122      */
00123     static void ClearInterrupt();
00124     
00125     /*
00126      * Methods to discover the attributes of an existing thread.
00127      */
00128     static PRThread *Self();
00129     Scope GetScope() const;
00130     State GetState() const;
00131     Priority GetPriority() const;
00132 
00133     /*
00134      * Thread private data
00135      */
00136     static PRStatus NewPrivateIndex(PRUintn* index);
00137 
00138     /*
00139      * Getting it - if you want to modify, make a copy
00140      */
00141     static RCThreadPrivateData* GetPrivateData(PRUintn index);
00142 
00143     /*
00144      * Setting it to <empty> - deletes existing data
00145      */
00146     static PRStatus SetPrivateData(PRUintn index);
00147 
00148     /*
00149      * Setting it - runtime will make a copy, freeing old iff necessary
00150      */
00151     static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data);
00152 
00153     /*
00154      * Scheduling control
00155      */
00156     static PRStatus Sleep(const RCInterval& ticks);
00157 
00158     friend void nas_Root(void*);
00159     friend class RCPrimordialThread;
00160 protected:
00161 
00162     /*
00163      * The instantiator of a class must not call the destructor. The base
00164      * implementation of Join will, and if the thread is created unjoinable,
00165      * then the code that called the RootFunction will call the desctructor.
00166      */
00167     virtual ~RCThread();
00168 
00169 private:
00170 
00171     /*
00172      * This is where a newly created thread begins execution. Returning
00173      * from this function is equivalent to terminating the thread.
00174      */
00175     virtual void RootFunction() = 0;
00176 
00177     PRThread *identity;
00178 
00179     /* Threads are unstarted until started - pretty startling */
00180     enum {ex_unstarted, ex_started} execution;
00181 
00182     /* There is no public default constructor or copy constructor */
00183     RCThread();
00184     RCThread(const RCThread&);
00185     
00186     /* And there is no assignment operator */
00187     void operator=(const RCThread&);
00188 
00189 public:
00190     static RCPrimordialThread *WrapPrimordialThread();    
00191 
00192  };
00193  
00194 /*
00195 ** class RCPrimordialThread
00196 */
00197 class PR_IMPLEMENT(RCPrimordialThread): public RCThread
00198 {
00199 public:
00200     /*
00201     ** The primordial thread can (optionally) wait for all created
00202     ** threads to terminate before allowing the process to exit.
00203     ** Not calling Cleanup() before returning from main() will cause
00204     ** the immediate termination of the entire process, including
00205     ** any running threads.
00206     */
00207     static PRStatus Cleanup();
00208 
00209     /*
00210     ** Only the primordial thread is allowed to adjust the number of
00211     ** virtual processors of the runtime. It's a lame security thing.
00212     */
00213     static PRStatus SetVirtualProcessors(PRIntn count=10);
00214 
00215 friend class RCThread;
00216 private:
00217     /*
00218     ** None other than the runtime can create of destruct
00219     ** a primordial thread. It is fabricated by the runtime
00220     ** to wrap the thread that initiated the application.
00221     */
00222     RCPrimordialThread();
00223     ~RCPrimordialThread();
00224     void RootFunction();
00225 };  /* RCPrimordialThread */
00226 
00227  #endif /* defined(_RCTHREAD_H) */