00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #pragma once
00030 #ifndef __CSTHREAD_H__
00031 #define __CSTHREAD_H__
00032
00033 #include <pthread.h>
00034 #include <setjmp.h>
00035
00036 #include "CSDefs.h"
00037 #include "CSMutex.h"
00038 #include "CSException.h"
00039 #include "CSObject.h"
00040 #include "CSStorage.h"
00041
00042 #define CS_THREAD_TYPE int
00043
00044
00045 #define CS_ANY_THREAD 0
00046 #define CS_THREAD 1
00047
00048 typedef struct CSCallStack {
00049 const char* cs_func;
00050 const char* cs_file;
00051 int cs_line;
00052 } CSCallStack, *CSCallStackPtr;
00053
00054
00055
00056
00057
00058 #define CS_RELEASE_OBJECT 1
00059 #define CS_RELEASE_MUTEX 2
00060 #define CS_RELEASE_POOLED 3
00061 #define CS_RELEASE_MEM 4
00062 #define CS_RELEASE_OBJECT_PTR 5
00063
00064 typedef struct CSRelease {
00065 int r_type;
00066 union {
00067 CSObject *r_object;
00068 CSMutex *r_mutex;
00069 CSPooled *r_pooled;
00070 void *r_mem;
00071 CSObject **r_objectPtr;
00072 } x;
00073 } CSReleaseRec, *CSReleasePtr;
00074
00075 typedef struct CSJumpBuf {
00076 CSReleasePtr jb_res_top;
00077 int jb_call_top;
00078 jmp_buf jb_buffer;
00079 } CSJumpBufRec, *CSJumpBufPtr;
00080
00081 class CSThreadList: public CSLinkedList, public CSMutex {
00082 public:
00083 CSThreadList():
00084 CSLinkedList(),
00085 CSMutex()
00086 {
00087 }
00088
00089 virtual ~CSThreadList() {
00090 stopAllThreads();
00091 }
00092
00096 void signalAllThreads(int sig);
00097
00098 void quitAllThreads();
00099
00100 void stopAllThreads();
00101 };
00102
00103 typedef void *(*ThreadRunFunc)();
00104
00105 class CSThread : public CSRefObject {
00106 public:
00107
00108 CSString *threadName;
00109 CSThreadList *myThreadList;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 int signalPending;
00121 bool ignoreSignals;
00122
00123
00124 bool isRunning;
00125
00126
00127 bool myMustQuit;
00128
00129 CSException myException;
00130 #if defined(MYSQL_SERVER) || defined(DRIZZLED)
00131
00132
00133
00134 bool pbms_api_owner;
00135
00136
00137 #ifdef DRIZZLED
00138 CSSortedList mySavePoints;
00139 #endif
00140 uint32_t myTID;
00141 uint32_t myTransRef;
00142 bool myIsAutoCommit;
00143 uint32_t myCacheVersion;
00144 bool myStartTxn;
00145 uint32_t myStmtCount;
00146 uint32_t myStartStmt;
00147 void *myInfo;
00148 #endif
00149
00150
00151 int callTop;
00152 CSCallStack callStack[CS_CALL_STACK_SIZE];
00153
00154
00155 int jumpDepth;
00156 CSJumpBufRec jumpEnv[CS_JUMP_STACK_SIZE];
00157
00158
00159 CSReleasePtr relTop;
00160 CSReleaseRec relStack[CS_RELEASE_STACK_SIZE];
00161
00162 CSThread(CSThreadList *list):
00163 CSRefObject(),
00164 threadName(NULL),
00165 myThreadList(list),
00166 signalPending(0),
00167 ignoreSignals(false),
00168 isRunning(false),
00169 myMustQuit(false),
00170 #if defined(MYSQL_SERVER) || defined(DRIZZLED)
00171 pbms_api_owner(false),
00172 myTID(0),
00173 myTransRef(0),
00174 myIsAutoCommit(true),
00175 myCacheVersion(0),
00176 myStartTxn(true),
00177 myStmtCount(0),
00178 myStartStmt(0),
00179 myInfo(NULL),
00180 #endif
00181 callTop(0),
00182 jumpDepth(0),
00183 relTop(relStack),
00184 iIsMain(false),
00185 isDetached(false),
00186 iRunFunc(NULL),
00187 iNextLink(NULL),
00188 iPrevLink(NULL)
00189 {
00190 }
00191
00192 virtual ~CSThread() {
00193 if (threadName)
00194 threadName->release();
00195 }
00196
00202 virtual void *run();
00203
00209 void start(bool detached = false);
00210
00211
00212
00213
00214 virtual void stop();
00215
00221 void *join();
00222
00227 void signal(unsigned int);
00228
00229 void setSignalPending(unsigned int);
00230
00237 void interrupted() { if (signalPending) throwSignal(); }
00238 void throwSignal();
00239
00240
00241 void logStack(int depth, const char *msg);
00242
00243
00244 void logException();
00245
00246
00247 void logMessage();
00248
00249
00250
00251
00252 bool isMain();
00253
00254
00255
00256
00257 void releaseObjects(CSReleasePtr top);
00258 void throwException();
00259 void caught();
00260 bool isMe(CSThread *me) { return (pthread_equal(me->iThread,iThread) != 0);}
00261
00262 virtual CSObject *getNextLink() { return iNextLink; }
00263 virtual CSObject *getPrevLink() { return iPrevLink; }
00264 virtual void setNextLink(CSObject *link) { iNextLink = link; }
00265 virtual void setPrevLink(CSObject *link) { iPrevLink = link; }
00266
00267 friend class CSDaemon;
00268
00269 private:
00270 pthread_t iThread;
00271 bool iIsMain;
00272 bool isDetached;
00273 ThreadRunFunc iRunFunc;
00274 CSObject *iNextLink;
00275 CSObject *iPrevLink;
00276
00277 void addToList();
00278 void removeFromList();
00279
00280 public:
00281
00282 static pthread_key_t sThreadKey;
00283
00293 static void sleep(unsigned long timeout);
00294
00295
00296 static bool isUp;
00297 static bool startUp();
00298 static void shutDown();
00299
00300
00301 static bool attach(CSThread *thread);
00302 static void detach(CSThread *thread);
00303
00308 static CSThread *getSelf();
00309 static bool setSelf(CSThread *self);
00310
00311 static CSThread *newCSThread();
00312 static CSThread *newThread(CSString *name, ThreadRunFunc run_func, CSThreadList *list);
00313
00314
00315 static void *dispatch(void *arg);
00316
00317 };
00318
00319 class CSDaemon : public CSThread, public CSSync {
00320 public:
00321 time_t myWaitTime;
00322
00323 CSDaemon(time_t wait_time, CSThreadList *list);
00324 CSDaemon(CSThreadList *list);
00325 virtual ~CSDaemon() { }
00326
00327 virtual void *run();
00328
00329
00330 virtual bool initializeWork() { return true; };
00331
00332
00333 virtual bool doWork();
00334
00335 virtual void *completeWork() { return NULL; };
00336
00337
00338
00339
00340
00341 virtual bool handleException();
00342
00343 virtual void stop();
00344
00345 void wakeup();
00346
00347 void suspend();
00348
00349 bool isSuspend() { return (iSuspendCount != 0);}
00350
00351 void resume();
00352
00353 virtual void returnToPool() {
00354 resume();
00355 release();
00356 }
00357
00358 void suspended();
00359
00360 void suspendedWait();
00361
00362 void suspendedWait(time_t milli_sec);
00363
00364 private:
00365 void try_Run(CSThread *self, const bool must_sleep);
00366 bool iSuspended;
00367 uint32_t iSuspendCount;
00368 };
00369
00370 #endif