1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
3
* PrimeBase Media Stream for MySQL
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* Original author: Paul McCullagh (H&G2JCtL)
20
* Continued development: Barry Leslie
25
* A independently running thread.
30
#ifndef __CSTHREAD_H__
31
#define __CSTHREAD_H__
38
#include "CSException.h"
40
#include "CSStorage.h"
42
#define CS_THREAD_TYPE int
44
/* Types of threads: */
45
#define CS_ANY_THREAD 0
48
typedef struct CSCallStack {
52
} CSCallStack, *CSCallStackPtr;
55
* The release stack contains objects that need to be
56
* released when an exception occurs.
58
#define CS_RELEASE_OBJECT 1
59
#define CS_RELEASE_MUTEX 2
60
#define CS_RELEASE_POOLED 3
61
#define CS_RELEASE_MEM 4
62
#define CS_RELEASE_OBJECT_PTR 5
64
typedef struct CSRelease {
67
CSObject *r_object; /* The object to be released. */
68
CSMutex *r_mutex; /* The mutex to be unlocked! */
71
CSObject **r_objectPtr;
73
} CSReleaseRec, *CSReleasePtr;
75
typedef struct CSJumpBuf {
76
CSReleasePtr jb_res_top;
79
} CSJumpBufRec, *CSJumpBufPtr;
81
class CSThreadList: public CSLinkedList, public CSMutex {
89
virtual ~CSThreadList() {
94
* Send the given signal to all threads, except to self!
96
void signalAllThreads(int sig);
98
void quitAllThreads();
100
void stopAllThreads();
103
typedef void *(*ThreadRunFunc)();
105
class CSThread : public CSRefObject {
107
/* The name of the thread. */
108
CSString *threadName;
109
CSThreadList *myThreadList; /* The thread list that this thread belongs to. */
111
/* If this value is non-zero, this signal is pending and
114
* SIGTERM, SIGQUIT - Means the thread has been terminated.
115
* SIGINT - Means the thread has been interrupted.
117
* When a signal is throw it clears this value. This includes
118
* the case when system calls return error due to interrupt.
123
/* Set to true once the thread is running (never reset!). */
126
/* Set to true when the thread must quit (never reset!): */
129
CSException myException;
130
#if defined(MYSQL_SERVER) || defined(DRIZZLED)
132
/* Set to true when this tread was initialized through the internal PBMS api. */
133
/* When this is the case than it must only be freed via the API as well. */
136
/* Transaction references. */
138
CSSortedList mySavePoints;
140
uint32_t myTID; // Current transaction ID
141
uint32_t myTransRef; // Reference to the current transaction cache index
142
bool myIsAutoCommit; // Is the current transaction in auto commit mode.
143
uint32_t myCacheVersion; // The last transaction cache version checked. Used during overflow.
144
bool myStartTxn; // A flag to indicate the start of a new transaction.
145
uint32_t myStmtCount; // Counts the number of statements in the current transaction.
146
uint32_t myStartStmt; // The myStmtCount at the start of the last logical statement. (An update is 2 statements but only 1 logical statement.)
152
CSCallStack callStack[CS_CALL_STACK_SIZE];
154
/* The long jump stack: */
155
int jumpDepth; /* The current jump depth */
156
CSJumpBufRec jumpEnv[CS_JUMP_STACK_SIZE]; /* The process environment to be restored on exception */
158
/* The release stack */
159
CSReleasePtr relTop; /* The top of the resource stack (reference next free space). */
160
CSReleaseRec relStack[CS_RELEASE_STACK_SIZE]; /* Temporary data to be freed if an exception occurs. */
162
CSThread(CSThreadList *list):
167
ignoreSignals(false),
170
#if defined(MYSQL_SERVER) || defined(DRIZZLED)
171
pbms_api_owner(false),
174
myIsAutoCommit(true),
192
virtual ~CSThread() {
194
threadName->release();
198
* Task to be performed by this thread.
200
* @exception CSSystemException thrown if thread cannot be run.
205
* Start execution of the thread.
207
* @exception CSSystemException thrown if thread is invalid.
209
void start(bool detached = false);
212
* Stop execution of the thread.
217
* Wait for this thread to die.
219
* @exception CSSystemException thrown if thread is invalid.
224
* Signal the thread. Throws CSSystemException
225
* if the thread is invalid.
227
void signal(unsigned int);
229
void setSignalPending(unsigned int);
232
* Check to see if we have been interrupted by a signal
233
* (i.e. there is a signal pending).
234
* This function throws CSSignalException if
235
* there is a signal pending.
237
void interrupted() { if (signalPending) throwSignal(); }
240
/* Log the stack to the specified depth along with the message. */
241
void logStack(int depth, const char *msg);
243
/* Log the exception, and the current stack. */
246
/* Log the exception, and the current stack. */
250
* Return true if this is the main thread.
255
* Throwing exceptions:
257
void releaseObjects(CSReleasePtr top);
258
void throwException();
260
bool isMe(CSThread *me) { return (pthread_equal(me->iThread,iThread) != 0);}
261
/* Make this object linkable: */
262
virtual CSObject *getNextLink() { return iNextLink; }
263
virtual CSObject *getPrevLink() { return iPrevLink; }
264
virtual void setNextLink(CSObject *link) { iNextLink = link; }
265
virtual void setPrevLink(CSObject *link) { iPrevLink = link; }
267
friend class CSDaemon;
273
ThreadRunFunc iRunFunc;
278
void removeFromList();
281
/* Each thread stores is thread object in this key: */
282
static pthread_key_t sThreadKey;
285
* Put the currently executing thread to sleep for a given amount of
288
* @param timeout maximum amount of time (milliseconds) this method could block
290
* @exception TDInterruptedException thrown if the threads sleep is interrupted
291
* before <i>timeout</i> milliseconds expire.
293
static void sleep(unsigned long timeout);
295
/* Do static initialization and de-initialization. */
297
static bool startUp();
298
static void shutDown();
300
/* Attach and detach an already running thread: */
301
static bool attach(CSThread *thread);
302
static void detach(CSThread *thread);
305
* Return the thread object of the current
308
static CSThread *getSelf();
309
static bool setSelf(CSThread *self);
311
static CSThread *newCSThread();
312
static CSThread *newThread(CSString *name, ThreadRunFunc run_func, CSThreadList *list);
314
/* called for a newly created thread. */
315
static void *dispatch(void *arg);
319
class CSDaemon : public CSThread, public CSSync {
321
time_t myWaitTime; /* Wait time in milli-seconds */
323
CSDaemon(time_t wait_time, CSThreadList *list);
324
CSDaemon(CSThreadList *list);
325
virtual ~CSDaemon() { }
329
/* Return false if startup failed, and the thread must quit. */
330
virtual bool initializeWork() { return true; };
332
/* Return true of the thread should sleep before doing more work. */
333
virtual bool doWork();
335
virtual void *completeWork() { return NULL; };
337
/* Return false if the excpetion is not handled and the thread must quit.
338
* Set must_sleep to true of the thread should pause before doing work
341
virtual bool handleException();
349
bool isSuspend() { return (iSuspendCount != 0);} // Don't use iSuspended, we are interested in if suspend() was called.
353
virtual void returnToPool() {
360
void suspendedWait();
362
void suspendedWait(time_t milli_sec);
365
void try_Run(CSThread *self, const bool must_sleep);
367
uint32_t iSuspendCount;