| [1016] | 1 | // **********************************************************************
 | 
|---|
 | 2 | //
 | 
|---|
 | 3 | // Copyright (c) 2000
 | 
|---|
 | 4 | // Object Oriented Concepts, Inc.
 | 
|---|
 | 5 | // Billerica, MA, USA
 | 
|---|
 | 6 | //
 | 
|---|
 | 7 | // All Rights Reserved
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // **********************************************************************
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | #ifndef JTC_THREAD_H
 | 
|---|
 | 12 | #define JTC_THREAD_H
 | 
|---|
 | 13 | 
 | 
|---|
 | 14 | class JTCMonitor;
 | 
|---|
 | 15 | class JTCThreadGroup;
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 18 | typedef void (*JTCAttrHook)(pthread_attr_t*);
 | 
|---|
 | 19 | #endif
 | 
|---|
 | 20 | 
 | 
|---|
 | 21 | //
 | 
|---|
 | 22 | // This class encapsulates the functionality of a thread.
 | 
|---|
 | 23 | //
 | 
|---|
 | 24 | class JTCThread : public virtual JTCRefCount
 | 
|---|
 | 25 | {
 | 
|---|
 | 26 |     //
 | 
|---|
 | 27 |     // Hide copy constructor and assignment operator.
 | 
|---|
 | 28 |     //
 | 
|---|
 | 29 |     JTCThread(const JTCThread&);
 | 
|---|
 | 30 |     void operator=(const JTCThread&);
 | 
|---|
 | 31 | 
 | 
|---|
 | 32 | #ifdef HAVE_JTC_STOP
 | 
|---|
 | 33 |     //
 | 
|---|
 | 34 |     // Check running status of this thread.  This determines whether
 | 
|---|
 | 35 |     // the thread needs to be suspended or terminated.
 | 
|---|
 | 36 |     //
 | 
|---|
 | 37 |     void _checkRunningStatus() const;
 | 
|---|
 | 38 | 
 | 
|---|
 | 39 |     //
 | 
|---|
 | 40 |     // Set the monitor associated with this thread.
 | 
|---|
 | 41 |     //
 | 
|---|
 | 42 |     void setMonitor(JTCMonitor* monitor);
 | 
|---|
 | 43 |     JTCMonitor* getMonitor();
 | 
|---|
 | 44 | #endif
 | 
|---|
 | 45 | 
 | 
|---|
 | 46 |     //
 | 
|---|
 | 47 |     // Spawn a new thread.
 | 
|---|
 | 48 |     //
 | 
|---|
 | 49 |     void spawnThread();
 | 
|---|
 | 50 | 
 | 
|---|
 | 51 |     //
 | 
|---|
 | 52 |     // Helper for the constructor.
 | 
|---|
 | 53 |     //
 | 
|---|
 | 54 |     void init(const JTCThreadGroupHandle& group, JTCRunnableHandle target,
 | 
|---|
 | 55 |               const char* name);
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 |     //
 | 
|---|
 | 58 |     // Private constructor for booting JTC.
 | 
|---|
 | 59 |     //
 | 
|---|
 | 60 |     JTCThread(JTCThreadId tid, bool main);
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 |     JTCThreadId thrId_; // Threads ID.
 | 
|---|
 | 63 |     JTCThreadGroupHandle group_; // Group of this thread.
 | 
|---|
 | 64 | 
 | 
|---|
 | 65 |     //
 | 
|---|
 | 66 |     // Event variable used for waiting until thread data is set.
 | 
|---|
 | 67 |     //
 | 
|---|
 | 68 |     JTCEvent setInitialData_;
 | 
|---|
 | 69 | 
 | 
|---|
 | 70 |     char* name_; // Name of the thread.
 | 
|---|
 | 71 |     JTCRunnableHandle target_; // Target of the thread.
 | 
|---|
 | 72 |     enum
 | 
|---|
 | 73 |     {
 | 
|---|
 | 74 |         NewThread,
 | 
|---|
 | 75 |         Runnable,
 | 
|---|
 | 76 |         NotRunnable,
 | 
|---|
 | 77 |         Dead
 | 
|---|
 | 78 |     } state_; // The thread state.
 | 
|---|
 | 79 | 
 | 
|---|
 | 80 |     JTCEvent startRequest_; // Used for starting the thread.
 | 
|---|
 | 81 | 
 | 
|---|
 | 82 |     //
 | 
|---|
 | 83 |     // State flags.
 | 
|---|
 | 84 |     // Future enhancement could be to convert these
 | 
|---|
 | 85 |     // flags to a bitfield to save space.
 | 
|---|
 | 86 |     //
 | 
|---|
 | 87 |     enum { not_terminated, terminated, throw_termination };
 | 
|---|
 | 88 |     int terminated_; // Has the thread been terminated.
 | 
|---|
 | 89 | 
 | 
|---|
 | 90 |     JTCRecursiveMutex resumeMut_; // Mutex, associated with resumeCond.
 | 
|---|
 | 91 | 
 | 
|---|
 | 92 | #ifdef HAVE_JTC_STOP
 | 
|---|
 | 93 |     bool suspended_; // Has the thread been suspended.
 | 
|---|
 | 94 | 
 | 
|---|
 | 95 |     JTCCond resumeCond_; // Condition variable used for resume.
 | 
|---|
 | 96 | 
 | 
|---|
 | 97 |     JTCMutex monMutex_; // Mutex to protect monitor
 | 
|---|
 | 98 |     JTCMonitor* monitor_; // Threads current monitor.
 | 
|---|
 | 99 | #endif
 | 
|---|
 | 100 | 
 | 
|---|
 | 101 |     JTCCond joinCond_; // Join condition variable.
 | 
|---|
 | 102 |     JTCRecursiveMutex joinMut_; // Join mutex.
 | 
|---|
 | 103 | 
 | 
|---|
 | 104 |     bool adopted_; // Is this thread adopted?
 | 
|---|
 | 105 |     
 | 
|---|
 | 106 |     static JTCThreadKey thrKey_; // TSS key.
 | 
|---|
 | 107 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 108 |     static JTCAttrHook attrHook_;
 | 
|---|
 | 109 | #endif
 | 
|---|
 | 110 | 
 | 
|---|
 | 111 |     friend class JTCInitialize;
 | 
|---|
 | 112 |     friend class JTCAdoptCurrentThread;
 | 
|---|
 | 113 | 
 | 
|---|
 | 114 | public:
 | 
|---|
 | 115 | 
 | 
|---|
 | 116 |     JTCThread (const char* name);
 | 
|---|
 | 117 |     JTCThread (JTCRunnableHandle target = JTCRunnableHandle(),
 | 
|---|
 | 118 |                const char* name = 0);
 | 
|---|
 | 119 |     JTCThread (JTCThreadGroupHandle& group, JTCRunnableHandle target,
 | 
|---|
 | 120 |                const char* name = 0);
 | 
|---|
 | 121 |     JTCThread (JTCThreadGroupHandle& group, const char* name = 0);
 | 
|---|
 | 122 | 
 | 
|---|
 | 123 |     virtual ~JTCThread();
 | 
|---|
 | 124 | 
 | 
|---|
 | 125 |     //
 | 
|---|
 | 126 |     // Get the threads group.
 | 
|---|
 | 127 |     //
 | 
|---|
 | 128 |     JTCThreadGroupHandle getThreadGroup();
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 |     //
 | 
|---|
 | 131 |     // Set the name of this thread.
 | 
|---|
 | 132 |     //
 | 
|---|
 | 133 |     void setName(const char*);
 | 
|---|
 | 134 | 
 | 
|---|
 | 135 |     //
 | 
|---|
 | 136 |     // Get the name of this thread.
 | 
|---|
 | 137 |     //
 | 
|---|
 | 138 |     const char* getName() const;
 | 
|---|
 | 139 | 
 | 
|---|
 | 140 | #ifdef HAVE_JTC_STOP
 | 
|---|
 | 141 |     //
 | 
|---|
 | 142 |     // Suspend the thread.
 | 
|---|
 | 143 |     //
 | 
|---|
 | 144 |     void suspend();
 | 
|---|
 | 145 | 
 | 
|---|
 | 146 |     //
 | 
|---|
 | 147 |     // Resume the thread.
 | 
|---|
 | 148 |     //
 | 
|---|
 | 149 |     void resume();
 | 
|---|
 | 150 | 
 | 
|---|
 | 151 |     //
 | 
|---|
 | 152 |     // Stop the thread.  Subclasses should override this method to
 | 
|---|
 | 153 |     // provide special functionality for stopping.
 | 
|---|
 | 154 |     //
 | 
|---|
 | 155 |     virtual void stop();
 | 
|---|
 | 156 | #endif
 | 
|---|
 | 157 |     
 | 
|---|
 | 158 |     //
 | 
|---|
 | 159 |     // Start the thread.
 | 
|---|
 | 160 |     //
 | 
|---|
 | 161 |     void start();
 | 
|---|
 | 162 | 
 | 
|---|
 | 163 |     //
 | 
|---|
 | 164 |     // Override this method to provide functionality to your thread.
 | 
|---|
 | 165 |     //
 | 
|---|
 | 166 |     virtual void run();
 | 
|---|
 | 167 | 
 | 
|---|
 | 168 |     //
 | 
|---|
 | 169 |     // Determine if the thread is currently running.
 | 
|---|
 | 170 |     //
 | 
|---|
 | 171 |     bool isAlive() const;
 | 
|---|
 | 172 | 
 | 
|---|
 | 173 |     //
 | 
|---|
 | 174 |     // Wait for this thread to terminate.
 | 
|---|
 | 175 |     //
 | 
|---|
 | 176 |     void join();
 | 
|---|
 | 177 | 
 | 
|---|
 | 178 |     //
 | 
|---|
 | 179 |     // Wait at most millis for this thread to terminate.
 | 
|---|
 | 180 |     //
 | 
|---|
 | 181 |     void join(long millis);
 | 
|---|
 | 182 | 
 | 
|---|
 | 183 |     //
 | 
|---|
 | 184 |     // Wait at most millis plus nanos for this thread to terminate.
 | 
|---|
 | 185 |     //
 | 
|---|
 | 186 |     void join(long millis, int nanos);
 | 
|---|
 | 187 |     
 | 
|---|
 | 188 |     //
 | 
|---|
 | 189 |     // Set the priority of this thread.
 | 
|---|
 | 190 |     //
 | 
|---|
 | 191 |     void setPriority(int newPri);
 | 
|---|
 | 192 | 
 | 
|---|
 | 193 |     //
 | 
|---|
 | 194 |     // Get the priority of this thread.
 | 
|---|
 | 195 |     //
 | 
|---|
 | 196 |     int getPriority() const;
 | 
|---|
 | 197 | 
 | 
|---|
 | 198 |     //
 | 
|---|
 | 199 |     // Enumerate all threads in this threads group.
 | 
|---|
 | 200 |     //
 | 
|---|
 | 201 |     static int enumerate(JTCThreadHandle* list, int len);
 | 
|---|
 | 202 | 
 | 
|---|
 | 203 |     enum // Under WIN32 MIN_PRIORITY is already defined in winspool.h
 | 
|---|
 | 204 |     {
 | 
|---|
 | 205 |         JTC_MIN_PRIORITY  = 0,
 | 
|---|
 | 206 |         JTC_NORM_PRIORITY = 1,
 | 
|---|
 | 207 |         JTC_MAX_PRIORITY  = 2
 | 
|---|
 | 208 |     };
 | 
|---|
 | 209 | 
 | 
|---|
 | 210 |     //
 | 
|---|
 | 211 |     // Get a pointer to the current thread object.
 | 
|---|
 | 212 |     //
 | 
|---|
 | 213 |     static JTCThread* currentThread();
 | 
|---|
 | 214 | 
 | 
|---|
 | 215 |     //
 | 
|---|
 | 216 |     // Sleep for millis milliseconds, and nano nanoseconds.
 | 
|---|
 | 217 |     //
 | 
|---|
 | 218 |     static void sleep(long millis, int nano = 0);
 | 
|---|
 | 219 | 
 | 
|---|
 | 220 |     //
 | 
|---|
 | 221 |     // Yield this threads current timeslice.
 | 
|---|
 | 222 |     //
 | 
|---|
 | 223 |     static void yield();
 | 
|---|
 | 224 | 
 | 
|---|
 | 225 |     //
 | 
|---|
 | 226 |     // Determine the number of threads currently running in this
 | 
|---|
 | 227 |     // threads ThreadGroup.
 | 
|---|
 | 228 |     //
 | 
|---|
 | 229 |     static int activeCount();
 | 
|---|
 | 230 | 
 | 
|---|
 | 231 |     //
 | 
|---|
 | 232 |     // Get the id of this thread.
 | 
|---|
 | 233 |     //
 | 
|---|
 | 234 |     JTCThreadId getId() const;
 | 
|---|
 | 235 | 
 | 
|---|
 | 236 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 237 |     //
 | 
|---|
 | 238 |     // This function sets a "hook" that is used to initialize custom
 | 
|---|
 | 239 |     // POSIX thread attributes. This function is called before every
 | 
|---|
 | 240 |     // thread that is created
 | 
|---|
 | 241 |     //
 | 
|---|
 | 242 |     static void setAttrHook(JTCAttrHook);
 | 
|---|
 | 243 | #endif
 | 
|---|
 | 244 | 
 | 
|---|
 | 245 |     //
 | 
|---|
 | 246 |     // These two methods are part of the internal thread interface.
 | 
|---|
 | 247 |     // They shouldnt be directly called by clients of the JTC
 | 
|---|
 | 248 |     // threading package.
 | 
|---|
 | 249 |     //
 | 
|---|
 | 250 |     void _JTC_startThreadHook();
 | 
|---|
 | 251 |     void _JTC_exit();
 | 
|---|
 | 252 | 
 | 
|---|
 | 253 | #ifdef HAVE_JTC_STOP
 | 
|---|
 | 254 |     static void _JTC_checkRunningStatus();
 | 
|---|
 | 255 | 
 | 
|---|
 | 256 |     static void _JTC_setMonitor(JTCMonitor* monitor);
 | 
|---|
 | 257 | #endif
 | 
|---|
 | 258 | };
 | 
|---|
 | 259 | 
 | 
|---|
 | 260 | //
 | 
|---|
 | 261 | // Insert operator for the iostream library.
 | 
|---|
 | 262 | //
 | 
|---|
 | 263 | JTC_STD(ostream)& operator<<(JTC_STD(ostream)& os, const JTCThread& thr);
 | 
|---|
 | 264 | 
 | 
|---|
 | 265 | //
 | 
|---|
 | 266 | // Forward declaration
 | 
|---|
 | 267 | //
 | 
|---|
 | 268 | class JTCTSSManager;
 | 
|---|
 | 269 | 
 | 
|---|
 | 270 | //
 | 
|---|
 | 271 | // This class is used to initialize the JTC library.
 | 
|---|
 | 272 | //
 | 
|---|
 | 273 | class JTCInitialize
 | 
|---|
 | 274 | {
 | 
|---|
 | 275 |     static int init_; // Number of times the library has been initialized.
 | 
|---|
 | 276 |     
 | 
|---|
 | 277 |     JTCThreadHandle mainThread_; // The JTC main thread.
 | 
|---|
 | 278 |     JTCTSSManager* manager_;
 | 
|---|
 | 279 | 
 | 
|---|
 | 280 |     void initialize();
 | 
|---|
 | 281 |     
 | 
|---|
 | 282 | public:
 | 
|---|
 | 283 | 
 | 
|---|
 | 284 |     JTCInitialize();
 | 
|---|
 | 285 |     JTCInitialize(int&, char**);
 | 
|---|
 | 286 |     ~JTCInitialize();
 | 
|---|
 | 287 | 
 | 
|---|
 | 288 |     //
 | 
|---|
 | 289 |     // Wait for all running threads to terminate.
 | 
|---|
 | 290 |     //
 | 
|---|
 | 291 |     void waitTermination();
 | 
|---|
 | 292 | 
 | 
|---|
 | 293 |     //
 | 
|---|
 | 294 |     // Determine if JTC has been initialized.
 | 
|---|
 | 295 |     //
 | 
|---|
 | 296 |     static bool initialized();
 | 
|---|
 | 297 | };
 | 
|---|
 | 298 | 
 | 
|---|
 | 299 | //
 | 
|---|
 | 300 | // This class is used to incorporate a non-JTC thread into the
 | 
|---|
 | 301 | // JThreads/C++ family. If an application wants to use a non-JTC
 | 
|---|
 | 302 | // thread with JTC primitives (for instance, if an ORBacus method is
 | 
|---|
 | 303 | // called from a non-JTC thread) an instance of this class must be
 | 
|---|
 | 304 | // instantiated before using any JTC primitive.
 | 
|---|
 | 305 | //
 | 
|---|
 | 306 | // What this class actually does is setup a fake
 | 
|---|
 | 307 | // JTCThread::currentThread() object, and create another root
 | 
|---|
 | 308 | // ThreadGroup.
 | 
|---|
 | 309 | //
 | 
|---|
 | 310 | class JTCAdoptCurrentThread
 | 
|---|
 | 311 | {
 | 
|---|
 | 312 |     JTCThreadHandle adoptedThread_; // The JTC adopted thread
 | 
|---|
 | 313 | 
 | 
|---|
 | 314 | public:
 | 
|---|
 | 315 | 
 | 
|---|
 | 316 |     JTCAdoptCurrentThread();
 | 
|---|
 | 317 |     ~JTCAdoptCurrentThread();
 | 
|---|
 | 318 | };
 | 
|---|
 | 319 | 
 | 
|---|
 | 320 | #endif
 | 
|---|