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"
38
#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
63
typedef struct CSRelease {
66
CSObject *r_object; /* The object to be released. */
67
CSMutex *r_mutex; /* The mutex to be unlocked! */
71
} CSReleaseRec, *CSReleasePtr;
73
typedef struct CSJumpBuf {
74
CSReleasePtr jb_res_top;
77
} CSJumpBufRec, *CSJumpBufPtr;
79
class CSThreadList: public CSLinkedList, public CSMutex {
87
virtual ~CSThreadList() {
92
* Send the given signal to all threads, except to self!
94
void signalAllThreads(int sig);
96
void quitAllThreads();
98
void stopAllThreads();
101
typedef void *(*ThreadRunFunc)();
103
class CSThread : public CSRefObject {
105
/* The name of the thread. */
106
CSString *threadName;
107
CSThreadList *myThreadList; /* The thread list that this thread belongs to. */
109
/* If this value is non-zero, this signal is pending and
112
* SIGTERM, SIGQUIT - Means the thread has been terminated.
113
* SIGINT - Means the thread has been interrupted.
115
* When a signal is throw it clears this value. This includes
116
* the case when system calls return error due to interrupt.
121
/* Set to true once the thread is running (never reset!). */
124
/* Set to true when the thread must quit (never reset!): */
127
/* Set to true when this tread was initialized through the internal PBMS api. */
128
/* When this is the case than it must only be freed via the API as well. */
131
CSException myException;
133
/* Transaction references. */
135
CSSortedList mySavePoints;
137
uint32_t myTID; // Current transaction ID
138
uint32_t myTransRef; // Reference to the current transaction cache index
139
bool myIsAutoCommit; // Is the current transaction in auto commit mode.
140
uint32_t myCacheVersion; // The last transaction cache version checked. Used during overflow.
141
bool myStartTxn; // A flag to indicate the start of a new transaction.
142
uint32_t myStmtCount; // Counts the number of statements in the current transaction.
143
uint32_t myStartStmt; // The myStmtCount at the start of the last logical statement. (An update is 2 statements but only 1 logical statement.)
144
void *myInfo; // A place to hang some info. (Be carefull with this!)
148
CSCallStack callStack[CS_CALL_STACK_SIZE];
150
/* The long jump stack: */
151
int jumpDepth; /* The current jump depth */
152
CSJumpBufRec jumpEnv[CS_JUMP_STACK_SIZE]; /* The process environment to be restored on exception */
154
/* The release stack */
155
CSReleasePtr relTop; /* The top of the resource stack (reference next free space). */
156
CSReleaseRec relStack[CS_RELEASE_STACK_SIZE]; /* Temporary data to be freed if an exception occurs. */
158
CSThread(CSThreadList *list):
163
ignoreSignals(false),
166
pbms_api_owner(false),
169
myIsAutoCommit(true),
185
virtual ~CSThread() {
187
threadName->release();
191
* Task to be performed by this thread.
193
* @exception CSSystemException thrown if thread cannot be run.
198
* Start execution of the thread.
200
* @exception CSSystemException thrown if thread is invalid.
205
* Stop execution of the thread.
210
* Wait for this thread to die.
212
* @exception CSSystemException thrown if thread is invalid.
217
* Signal the thread. Throws CSSystemException
218
* if the thread is invalid.
220
void signal(unsigned int);
222
void setSignalPending(unsigned int);
225
* Check to see if we have been interrupted by a signal
226
* (i.e. there is a signal pending).
227
* This function throws CSSignalException if
228
* there is a signal pending.
230
void interrupted() { if (signalPending) throwSignal(); }
233
/* Log the stack to the specified depth along with the message. */
234
void logStack(int depth, const char *msg);
236
/* Log the exception, and the current stack. */
239
/* Log the exception, and the current stack. */
243
* Return true if this is the main thread.
248
* Throwing exceptions:
250
void releaseObjects(CSReleasePtr top);
251
void throwException();
253
bool isMe(CSThread *me) { return (me->iThread == iThread);}
254
/* Make this object linkable: */
255
virtual CSObject *getNextLink() { return iNextLink; }
256
virtual CSObject *getPrevLink() { return iPrevLink; }
257
virtual void setNextLink(CSObject *link) { iNextLink = link; }
258
virtual void setPrevLink(CSObject *link) { iPrevLink = link; }
260
friend class CSDaemon;
265
ThreadRunFunc iRunFunc;
270
void removeFromList();
273
/* Each thread stores is thread object in this key: */
274
static pthread_key_t sThreadKey;
277
* Put the currently executing thread to sleep for a given amount of
280
* @param timeout maximum amount of time (milliseconds) this method could block
282
* @exception TDInterruptedException thrown if the threads sleep is interrupted
283
* before <i>timeout</i> milliseconds expire.
285
static void sleep(unsigned long timeout);
287
/* Do static initialization and de-initialization. */
289
static bool startUp();
290
static void shutDown();
292
/* Attach and detach an already running thread: */
293
static bool attach(CSThread *thread);
294
static void detach(CSThread *thread);
297
* Return the thread object of the current
300
static CSThread *getSelf();
301
static bool setSelf(CSThread *self);
303
static CSThread *newCSThread();
304
static CSThread *newThread(CSString *name, ThreadRunFunc run_func, CSThreadList *list);
306
/* called for a newly created thread. */
307
static void *dispatch(void *arg);
311
class CSDaemon : public CSThread, public CSSync {
313
time_t myWaitTime; /* Wait time in milli-seconds */
315
CSDaemon(time_t wait_time, CSThreadList *list);
316
CSDaemon(CSThreadList *list);
317
virtual ~CSDaemon() { }
321
virtual bool initializeWork() { return true; };
323
virtual bool doWork();
325
virtual void *completeWork() { return NULL; };
327
virtual bool handleException();
335
bool isSuspend() { return (iSuspendCount != 0);} // Don't use iSuspended, we are interested in if suspend() was called.
339
virtual void returnToPool() {
346
void suspendedWait();
348
void suspendedWait(time_t milli_sec);
352
uint32_t iSuspendCount;