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.
29
#ifndef __CSTHREAD_H__
30
#define __CSTHREAD_H__
37
#include "CSException.h"
39
#include "CSStorage.h"
41
#define CS_THREAD_TYPE int
43
/* Types of threads: */
44
#define CS_ANY_THREAD 0
47
typedef struct CSCallStack {
51
} CSCallStack, *CSCallStackPtr;
54
* The release stack contains objects that need to be
55
* released when an exception occurs.
57
#define CS_RELEASE_OBJECT 1
58
#define CS_RELEASE_MUTEX 2
59
#define CS_RELEASE_POOLED 3
60
#define CS_RELEASE_MEM 4
61
#define CS_RELEASE_OBJECT_PTR 5
63
typedef struct CSRelease {
66
CSObject *r_object; /* The object to be released. */
67
CSMutex *r_mutex; /* The mutex to be unlocked! */
70
CSObject **r_objectPtr;
72
} CSReleaseRec, *CSReleasePtr;
74
typedef struct CSJumpBuf {
75
CSReleasePtr jb_res_top;
78
} CSJumpBufRec, *CSJumpBufPtr;
80
class CSThreadList: public CSLinkedList, public CSMutex {
88
virtual ~CSThreadList() {
93
* Send the given signal to all threads, except to self!
95
void signalAllThreads(int sig);
97
void quitAllThreads();
99
void stopAllThreads();
102
typedef void *(*ThreadRunFunc)();
104
class CSThread : public CSRefObject {
106
/* The name of the thread. */
107
CSString *threadName;
108
CSThreadList *myThreadList; /* The thread list that this thread belongs to. */
110
/* If this value is non-zero, this signal is pending and
113
* SIGTERM, SIGQUIT - Means the thread has been terminated.
114
* SIGINT - Means the thread has been interrupted.
116
* When a signal is throw it clears this value. This includes
117
* the case when system calls return error due to interrupt.
122
/* Set to true once the thread is running (never reset!). */
125
/* Set to true when the thread must quit (never reset!): */
128
CSException myException;
129
#if defined(MYSQL_SERVER) || defined(DRIZZLED)
131
/* Set to true when this tread was initialized through the internal PBMS api. */
132
/* When this is the case than it must only be freed via the API as well. */
135
/* Transaction references. */
137
CSSortedList mySavePoints;
139
uint32_t myTID; // Current transaction ID
140
uint32_t myTransRef; // Reference to the current transaction cache index
141
bool myIsAutoCommit; // Is the current transaction in auto commit mode.
142
uint32_t myCacheVersion; // The last transaction cache version checked. Used during overflow.
143
bool myStartTxn; // A flag to indicate the start of a new transaction.
144
uint32_t myStmtCount; // Counts the number of statements in the current transaction.
145
uint32_t myStartStmt; // The myStmtCount at the start of the last logical statement. (An update is 2 statements but only 1 logical statement.)
151
CSCallStack callStack[CS_CALL_STACK_SIZE];
153
/* The long jump stack: */
154
int jumpDepth; /* The current jump depth */
155
CSJumpBufRec jumpEnv[CS_JUMP_STACK_SIZE]; /* The process environment to be restored on exception */
157
/* The release stack */
158
CSReleasePtr relTop; /* The top of the resource stack (reference next free space). */
159
CSReleaseRec relStack[CS_RELEASE_STACK_SIZE]; /* Temporary data to be freed if an exception occurs. */
161
CSThread(CSThreadList *list):
166
ignoreSignals(false),
169
#if defined(MYSQL_SERVER) || defined(DRIZZLED)
170
pbms_api_owner(false),
173
myIsAutoCommit(true),
191
virtual ~CSThread() {
193
threadName->release();
197
* Task to be performed by this thread.
199
* @exception CSSystemException thrown if thread cannot be run.
204
* Start execution of the thread.
206
* @exception CSSystemException thrown if thread is invalid.
208
void start(bool detached = false);
211
* Stop execution of the thread.
216
* Wait for this thread to die.
218
* @exception CSSystemException thrown if thread is invalid.
223
* Signal the thread. Throws CSSystemException
224
* if the thread is invalid.
226
void signal(unsigned int);
228
void setSignalPending(unsigned int);
231
* Check to see if we have been interrupted by a signal
232
* (i.e. there is a signal pending).
233
* This function throws CSSignalException if
234
* there is a signal pending.
236
void interrupted() { if (signalPending) throwSignal(); }
239
/* Log the stack to the specified depth along with the message. */
240
void logStack(int depth, const char *msg);
242
/* Log the exception, and the current stack. */
245
/* Log the exception, and the current stack. */
249
* Return true if this is the main thread.
254
* Throwing exceptions:
256
void releaseObjects(CSReleasePtr top);
257
void throwException();
259
bool isMe(CSThread *me) { return (pthread_equal(me->iThread,iThread) != 0);}
260
/* Make this object linkable: */
261
virtual CSObject *getNextLink() { return iNextLink; }
262
virtual CSObject *getPrevLink() { return iPrevLink; }
263
virtual void setNextLink(CSObject *link) { iNextLink = link; }
264
virtual void setPrevLink(CSObject *link) { iPrevLink = link; }
266
friend class CSDaemon;
272
ThreadRunFunc iRunFunc;
277
void removeFromList();
280
/* Each thread stores is thread object in this key: */
281
static pthread_key_t sThreadKey;
284
* Put the currently executing thread to sleep for a given amount of
287
* @param timeout maximum amount of time (milliseconds) this method could block
289
* @exception TDInterruptedException thrown if the threads sleep is interrupted
290
* before <i>timeout</i> milliseconds expire.
292
static void sleep(unsigned long timeout);
294
/* Do static initialization and de-initialization. */
296
static bool startUp();
297
static void shutDown();
299
/* Attach and detach an already running thread: */
300
static bool attach(CSThread *thread);
301
static void detach(CSThread *thread);
304
* Return the thread object of the current
307
static CSThread *getSelf();
308
static bool setSelf(CSThread *self);
310
static CSThread *newCSThread();
311
static CSThread *newThread(CSString *name, ThreadRunFunc run_func, CSThreadList *list);
313
/* called for a newly created thread. */
314
static void *dispatch(void *arg);
318
class CSDaemon : public CSThread, public CSSync {
320
time_t myWaitTime; /* Wait time in milli-seconds */
322
CSDaemon(time_t wait_time, CSThreadList *list);
323
CSDaemon(CSThreadList *list);
324
virtual ~CSDaemon() { }
328
/* Return false if startup failed, and the thread must quit. */
329
virtual bool initializeWork() { return true; };
331
/* Return true of the thread should sleep before doing more work. */
332
virtual bool doWork();
334
virtual void *completeWork() { return NULL; };
336
/* Return false if the excpetion is not handled and the thread must quit.
337
* Set must_sleep to true of the thread should pause before doing work
340
virtual bool handleException();
348
bool isSuspend() { return (iSuspendCount != 0);} // Don't use iSuspended, we are interested in if suspend() was called.
352
virtual void returnToPool() {
359
void suspendedWait();
361
void suspendedWait(time_t milli_sec);
364
void try_Run(CSThread *self, const bool must_sleep);
366
uint32_t iSuspendCount;