~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSThread.h

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
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.
9
 
 *
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.
14
 
 *
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
18
 
 *
19
 
 * Original author: Paul McCullagh (H&G2JCtL)
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-05-20
23
 
 *
24
 
 * CORE SYSTEM:
25
 
 * A independently running thread.
26
 
 *
27
 
 */
28
 
 
29
 
#pragma once
30
 
#ifndef __CSTHREAD_H__
31
 
#define __CSTHREAD_H__
32
 
 
33
 
#include <pthread.h>
34
 
#include <setjmp.h>
35
 
 
36
 
#include "CSDefs.h"
37
 
#include "CSMutex.h"
38
 
#include "CSException.h"
39
 
#include "CSObject.h"
40
 
#include "CSStorage.h"
41
 
 
42
 
#define CS_THREAD_TYPE                          int
43
 
 
44
 
/* Types of threads: */
45
 
#define CS_ANY_THREAD                           0
46
 
#define CS_THREAD                                       1
47
 
 
48
 
typedef struct CSCallStack {
49
 
        const char*     cs_func;
50
 
        const char*     cs_file;
51
 
        int                     cs_line;
52
 
} CSCallStack, *CSCallStackPtr;
53
 
 
54
 
/* 
55
 
 * The release stack contains objects that need to be
56
 
 * released when an exception occurs.
57
 
 */
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
63
 
 
64
 
typedef struct CSRelease {
65
 
        int                                             r_type;
66
 
        union {
67
 
                CSObject                        *r_object;                                      /* The object to be released. */
68
 
                CSMutex                         *r_mutex;                                       /* The mutex to be unlocked! */
69
 
                CSPooled                        *r_pooled;
70
 
                void                            *r_mem;
71
 
                CSObject                        **r_objectPtr;
72
 
        } x;
73
 
} CSReleaseRec, *CSReleasePtr;
74
 
 
75
 
typedef struct CSJumpBuf {
76
 
        CSReleasePtr                    jb_res_top;
77
 
        int                                             jb_call_top;
78
 
        jmp_buf                                 jb_buffer;
79
 
} CSJumpBufRec, *CSJumpBufPtr;
80
 
 
81
 
class CSThreadList: public CSLinkedList, public CSMutex {
82
 
public:
83
 
        CSThreadList():
84
 
                CSLinkedList(),
85
 
                CSMutex()
86
 
        {
87
 
        }
88
 
 
89
 
        virtual ~CSThreadList() {
90
 
                stopAllThreads();
91
 
        }
92
 
 
93
 
        /**
94
 
         * Send the given signal to all threads, except to self!
95
 
         */
96
 
        void signalAllThreads(int sig);
97
 
 
98
 
        void quitAllThreads();
99
 
 
100
 
        void stopAllThreads();
101
 
};
102
 
 
103
 
typedef void *(*ThreadRunFunc)();
104
 
 
105
 
class CSThread : public CSRefObject {
106
 
public:
107
 
        /* The name of the thread. */
108
 
        CSString                *threadName;
109
 
        CSThreadList    *myThreadList;                          /* The thread list that this thread belongs to. */
110
 
 
111
 
        /* If this value is non-zero, this signal is pending and
112
 
         * must be thrown.
113
 
         *
114
 
         * SIGTERM, SIGQUIT - Means the thread has been terminated.
115
 
         * SIGINT - Means the thread has been interrupted.
116
 
         *
117
 
         * When a signal is throw it clears this value. This includes
118
 
         * the case when system calls return error due to interrupt.
119
 
         */
120
 
        int                             signalPending;
121
 
        bool                    ignoreSignals;
122
 
 
123
 
        /* Set to true once the thread is running (never reset!). */
124
 
        bool                    isRunning;
125
 
 
126
 
        /* Set to true when the thread must quit (never reset!): */
127
 
        bool                    myMustQuit;     
128
 
        
129
 
        CSException             myException;
130
 
#if defined(MYSQL_SERVER) ||  defined(DRIZZLED)
131
 
 
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. */
134
 
        bool                    pbms_api_owner;
135
 
 
136
 
        /* Transaction references. */
137
 
#ifdef DRIZZLED
138
 
        CSSortedList    mySavePoints;
139
 
#endif
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.)
147
 
        void                    *myInfo;
148
 
#endif
149
 
        
150
 
        /* The call stack */
151
 
        int                             callTop;
152
 
        CSCallStack             callStack[CS_CALL_STACK_SIZE];
153
 
 
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 */
157
 
 
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. */
161
 
 
162
 
        CSThread(CSThreadList *list):
163
 
                CSRefObject(),
164
 
                threadName(NULL),
165
 
                myThreadList(list),
166
 
                signalPending(0),
167
 
                ignoreSignals(false),
168
 
                isRunning(false),
169
 
                myMustQuit(false),
170
 
#if defined(MYSQL_SERVER) ||  defined(DRIZZLED)
171
 
                pbms_api_owner(false),
172
 
                myTID(0),
173
 
                myTransRef(0),
174
 
                myIsAutoCommit(true),
175
 
                myCacheVersion(0),
176
 
                myStartTxn(true),
177
 
                myStmtCount(0),
178
 
                myStartStmt(0),
179
 
                myInfo(NULL),
180
 
#endif
181
 
                callTop(0),
182
 
                jumpDepth(0),
183
 
                relTop(relStack),
184
 
                iIsMain(false),
185
 
                isDetached(false),
186
 
                iRunFunc(NULL),
187
 
                iNextLink(NULL),
188
 
                iPrevLink(NULL)
189
 
        {
190
 
        }
191
 
 
192
 
        virtual ~CSThread() {
193
 
                if (threadName)
194
 
                        threadName->release();
195
 
        }
196
 
 
197
 
    /**
198
 
     * Task to be performed by this thread.
199
 
         *
200
 
     * @exception CSSystemException thrown if thread cannot be run.
201
 
         */
202
 
        virtual void *run();
203
 
 
204
 
        /**
205
 
         * Start execution of the thread.
206
 
         *
207
 
     * @exception CSSystemException thrown if thread is invalid.
208
 
         */
209
 
        void start(bool detached = false);
210
 
 
211
 
        /*
212
 
         * Stop execution of the thread.
213
 
         */
214
 
        virtual void stop();
215
 
 
216
 
        /**
217
 
         * Wait for this thread to die.
218
 
         *
219
 
     * @exception CSSystemException thrown if thread is invalid.
220
 
         */
221
 
        void *join();
222
 
 
223
 
        /**
224
 
         * Signal the thread. Throws CSSystemException 
225
 
     * if the thread is invalid.
226
 
         */
227
 
        void signal(unsigned int);
228
 
 
229
 
        void setSignalPending(unsigned int);
230
 
 
231
 
        /**
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.
236
 
         */
237
 
        void interrupted() { if (signalPending) throwSignal(); }
238
 
        void throwSignal();
239
 
 
240
 
        /* Log the stack to the specified depth along with the message. */
241
 
        void logStack(int depth, const char *msg);
242
 
 
243
 
        /* Log the exception, and the current stack. */
244
 
        void logException();
245
 
        
246
 
        /* Log the exception, and the current stack. */
247
 
        void logMessage();
248
 
        
249
 
        /*
250
 
         * Return true if this is the main thread.
251
 
         */
252
 
        bool isMain();
253
 
 
254
 
        /*
255
 
         * Throwing exceptions:
256
 
         */
257
 
        void releaseObjects(CSReleasePtr top);
258
 
        void throwException();
259
 
        void caught();
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; }
266
 
 
267
 
        friend class CSDaemon;
268
 
 
269
 
private:
270
 
        pthread_t               iThread;
271
 
        bool                    iIsMain;
272
 
        bool                    isDetached;
273
 
        ThreadRunFunc   iRunFunc;
274
 
        CSObject                *iNextLink;
275
 
        CSObject                *iPrevLink;
276
 
 
277
 
        void addToList();
278
 
        void removeFromList();
279
 
 
280
 
public:
281
 
        /* Each thread stores is thread object in this key: */
282
 
        static pthread_key_t sThreadKey;
283
 
 
284
 
   /**
285
 
     * Put the currently executing thread to sleep for a given amount of
286
 
     * time.
287
 
     *
288
 
     * @param timeout maximum amount of time (milliseconds) this method could block
289
 
     *
290
 
     * @exception TDInterruptedException thrown if the threads sleep is interrupted
291
 
     *            before <i>timeout</i> milliseconds expire.
292
 
     */
293
 
        static void sleep(unsigned long timeout);
294
 
 
295
 
        /* Do static initialization and de-initialization. */
296
 
        static bool isUp;
297
 
        static bool startUp();
298
 
        static void shutDown();
299
 
 
300
 
        /* Attach and detach an already running thread: */
301
 
        static bool attach(CSThread *thread);
302
 
        static void detach(CSThread *thread);
303
 
 
304
 
        /**
305
 
         * Return the thread object of the current
306
 
         * thread.
307
 
         */
308
 
        static CSThread *getSelf();
309
 
        static bool setSelf(CSThread *self);
310
 
 
311
 
        static CSThread *newCSThread();
312
 
        static CSThread *newThread(CSString *name, ThreadRunFunc run_func, CSThreadList *list);
313
 
 
314
 
        /* called for a newly created thread. */
315
 
        static void *dispatch(void *arg);
316
 
 
317
 
};
318
 
 
319
 
class CSDaemon : public CSThread, public CSSync {
320
 
public:
321
 
        time_t                  myWaitTime;                                     /* Wait time in milli-seconds */
322
 
 
323
 
        CSDaemon(time_t wait_time, CSThreadList *list);
324
 
        CSDaemon(CSThreadList *list);
325
 
        virtual ~CSDaemon() { }
326
 
 
327
 
        virtual void *run();
328
 
 
329
 
        /* Return false if startup failed, and the thread must quit. */
330
 
        virtual bool initializeWork() { return true; };
331
 
 
332
 
        /* Return true of the thread should sleep before doing more work. */
333
 
        virtual bool doWork();
334
 
 
335
 
        virtual void *completeWork() { return NULL; };
336
 
 
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
339
 
         * again.
340
 
         */
341
 
        virtual bool handleException();
342
 
 
343
 
        virtual void stop();
344
 
 
345
 
        void wakeup();
346
 
 
347
 
        void suspend();
348
 
 
349
 
        bool isSuspend() { return (iSuspendCount != 0);} // Don't use iSuspended, we are interested in if suspend() was called.
350
 
 
351
 
        void resume();
352
 
 
353
 
        virtual void returnToPool() {
354
 
                resume();
355
 
                release();
356
 
        }
357
 
 
358
 
        void suspended();
359
 
 
360
 
        void suspendedWait();
361
 
 
362
 
        void suspendedWait(time_t milli_sec);
363
 
 
364
 
private:
365
 
        void            try_Run(CSThread *self, const bool must_sleep);
366
 
        bool            iSuspended;
367
 
        uint32_t        iSuspendCount;
368
 
};
369
 
 
370
 
#endif