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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
62
typedef struct CSRelease {
65
CSObject *r_object; /* The object to be released. */
66
CSMutex *r_mutex; /* The mutex to be unlocked! */
69
} CSReleaseRec, *CSReleasePtr;
71
typedef struct CSJumpBuf {
72
CSReleasePtr jb_res_top;
75
} CSJumpBufRec, *CSJumpBufPtr;
77
class CSThreadList: public CSLinkedList, public CSMutex {
85
virtual ~CSThreadList() {
90
* Send the given signal to all threads, except to self!
92
void signalAllThreads(int sig);
94
void quitAllThreads();
96
void stopAllThreads();
99
typedef void *(*ThreadRunFunc)();
101
class CSThread : public CSRefObject {
103
/* The name of the thread. */
104
CSString *threadName;
105
CSThreadList *myThreadList; /* The thread list that this thread belongs to. */
107
/* If this value is non-zero, this signal is pending and
110
* SIGTERM, SIGQUIT - Means the thread has been terminated.
111
* SIGINT - Means the thread has been interrupted.
113
* When a signal is throw it clears this value. This includes
114
* the case when system calls return error due to interrupt.
119
/* Set to true once the thread is running (never reset!). */
122
/* Set to true when the thread must quit (never reset!): */
125
/* Set to true when this tread was initialized through the internal PBMS api. */
126
/* When this is the case than it must only be freed via the API as well. */
129
CSException myException;
131
/* Transaction references. */
132
uint32_t myTID; // Current transaction ID
133
uint32_t myTransRef; // Reference to the current transaction cache index
134
bool myIsAutoCommit; // Is the current transaction in auto commit mode.
135
uint32_t myCacheVersion; // The last transaction cache version checked. Used during overflow.
136
bool myStartTxn; // A flag to indicate the start of a new transaction.
137
uint32_t myStmtCount; // Counts the number of statements in the current transaction.
138
uint32_t myStartStmt; // The myStmtCount at the start of the last logical statement. (An update is 2 statements but only 1 logical statement.)
139
void *myInfo; // A place to hang some info. (Be carefull with this!)
143
CSCallStack callStack[CS_CALL_STACK_SIZE];
145
/* The long jump stack: */
146
int jumpDepth; /* The current jump depth */
147
CSJumpBufRec jumpEnv[CS_JUMP_STACK_SIZE]; /* The process environment to be restored on exception */
149
/* The release stack */
150
CSReleasePtr relTop; /* The top of the resource stack (reference next free space). */
151
CSReleaseRec relStack[CS_RELEASE_STACK_SIZE]; /* Temporary data to be freed if an exception occurs. */
153
CSThread(CSThreadList *list):
158
ignoreSignals(false),
175
pbms_api_owner(false)
179
virtual ~CSThread() {
181
threadName->release();
185
* Task to be performed by this thread.
187
* @exception CSSystemException thrown if thread cannot be run.
192
* Start execution of the thread.
194
* @exception CSSystemException thrown if thread is invalid.
199
* Stop execution of the thread.
204
* Wait for this thread to die.
206
* @exception CSSystemException thrown if thread is invalid.
211
* Signal the thread. Throws CSSystemException
212
* if the thread is invalid.
214
void signal(unsigned int);
216
void setSignalPending(unsigned int);
219
* Check to see if we have been interrupted by a signal
220
* (i.e. there is a signal pending).
221
* This function throws CSSignalException if
222
* there is a signal pending.
224
void interrupted() { if (signalPending) throwSignal(); }
227
/* Log the stack to the specified depth along with the message. */
228
void logStack(int depth, const char *msg);
230
/* Log the exception, and the current stack. */
233
/* Log the exception, and the current stack. */
237
* Return true if this is the main thread.
242
* Throwing exceptions:
244
void releaseObjects(CSReleasePtr top);
245
void throwException();
247
bool isMe(CSThread *me) { return (me->iThread == iThread);}
248
/* Make this object linkable: */
249
virtual CSObject *getNextLink() { return iNextLink; }
250
virtual CSObject *getPrevLink() { return iPrevLink; }
251
virtual void setNextLink(CSObject *link) { iNextLink = link; }
252
virtual void setPrevLink(CSObject *link) { iPrevLink = link; }
254
friend class CSDaemon;
256
friend void *td_dispatch(void *arg);
261
ThreadRunFunc iRunFunc;
266
void removeFromList();
269
/* Each thread stores is thread object in this key: */
270
static pthread_key_t sThreadKey;
273
* Put the currently executing thread to sleep for a given amount of
276
* @param timeout maximum amount of time (milliseconds) this method could block
278
* @exception TDInterruptedException thrown if the threads sleep is interrupted
279
* before <i>timeout</i> milliseconds expire.
281
static void sleep(unsigned long timeout);
283
/* Do static initialization and de-initialization. */
284
static bool startUp();
285
static void shutDown();
287
/* Attach and detach an already running thread: */
288
static bool attach(CSThread *thread);
289
static void detach(CSThread *thread);
292
* Return the thread object of the current
295
static CSThread *getSelf();
296
static bool setSelf(CSThread *self);
298
static CSThread *newCSThread();
299
static CSThread *newThread(CSString *name, ThreadRunFunc run_func, CSThreadList *list);
302
class CSDaemon : public CSThread, public CSSync {
304
time_t myWaitTime; /* Wait time in milli-seconds */
306
CSDaemon(time_t wait_time, CSThreadList *list);
307
CSDaemon(CSThreadList *list);
308
virtual ~CSDaemon() { }
312
virtual bool initialize() { return true; };
314
virtual bool doWork();
316
virtual void *finalize() { return NULL; };
318
virtual bool handleException();
326
bool isSuspend() { return (iSuspendCount != 0);} // Don't use iSuspended, we are interested in if suspend() was called.
330
virtual void returnToPool() {
337
void suspendedWait();
339
void suspendedWait(time_t milli_sec);