~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-11-22 00:16:44 UTC
  • mto: (1945.2.1 quick)
  • mto: This revision was merged to the branch mainline in revision 1947.
  • Revision ID: brian@tangent.org-20101122001644-pi6jv0d65e82xn38
Merge in lock refactor, this just encapsulates.

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
 * The definitions are used by all code, and is NOT required
 
26
 * by any header file!
 
27
 *
 
28
 */
 
29
 
 
30
#ifndef __CSGLOBAL_H__
 
31
#define __CSGLOBAL_H__
 
32
 
 
33
#include "CSDefs.h"
 
34
#include "CSObject.h"
 
35
#include "CSThread.h"
 
36
 
 
37
 
 
38
/* This is the call context: */
 
39
#define CS_CONTEXT                      __FUNC__, __FILE__, __LINE__
 
40
 
 
41
#ifdef DEBUG
 
42
int cs_assert(const char *func, const char *file, int line, const char *message);
 
43
int cs_hope(const char *func, const char *file, int line, const char *message);
 
44
 
 
45
#define ASSERT(x)                       ((x) ? 1 : cs_assert(CS_CONTEXT, #x))
 
46
#define HOPE(x)                         ((x) ? 1 : cs_hope(CS_CONTEXT, #x))
 
47
#else
 
48
#define ASSERT(x)
 
49
#define ASSERT(x)
 
50
#endif
 
51
 
 
52
#ifdef DEBUG
 
53
#define retain()                        retain(__FUNC__, __FILE__, __LINE__)
 
54
#define release()                       release(__FUNC__, __FILE__, __LINE__)
 
55
#endif
 
56
 
 
57
#define new_(v, t)                      do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
 
58
 
 
59
/*
 
60
 * -----------------------------------------------------------------------
 
61
 * Call stack
 
62
 */
 
63
 
 
64
/*
 
65
 * This macro must be placed at the start of every function.
 
66
 * It records the current context so that we can
 
67
 * dump a type of stack trace later if necessary.
 
68
 *
 
69
 * It also sets up the current thread pointer 'self'.
 
70
 */
 
71
#ifdef DEBUG
 
72
#define STACK_CHECK    CSReleasePtr self_reltop = self->relTop
 
73
#else
 
74
#define STACK_CHECK   
 
75
#endif
 
76
 
 
77
#define inner_()                        int                     cs_frame = self->callTop++; \
 
78
                                                        STACK_CHECK ; \
 
79
                                                        do { \
 
80
                                                                if (cs_frame< CS_CALL_STACK_SIZE) { \
 
81
                                                                        self->callStack[cs_frame].cs_func = __FUNC__; \
 
82
                                                                        self->callStack[cs_frame].cs_file = __FILE__; \
 
83
                                                                        self->callStack[cs_frame].cs_line = __LINE__; \
 
84
                                                                } \
 
85
                                                        } while (0)
 
86
 
 
87
#define outer_()                        self->callTop = cs_frame; \
 
88
                                                        ASSERT(self->relTop == self_reltop); 
 
89
 
 
90
#define enter_()                        CSThread        *self = CSThread::getSelf(); \
 
91
                                                        inner_()
 
92
 
 
93
/*
 
94
 * On exit to a function, either exit_() or
 
95
 * return_() must be called.
 
96
 */
 
97
#define exit_()                         do { \
 
98
                                                                outer_(); \
 
99
                                                                return; \
 
100
                                                        } while (0)
 
101
                                        
 
102
 
 
103
#define return_(x)                      do { \
 
104
                                                                outer_(); \
 
105
                                                                return(x); \
 
106
                                                        } while (0)
 
107
 
 
108
 
 
109
/*
 
110
 * -----------------------------------------------------------------------
 
111
 * Throwing and catching (the jump stack)
 
112
 */
 
113
 
 
114
int prof_setjmp(void);
 
115
 
 
116
#define TX_CHK_JMP()            if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
 
117
#ifdef PROFILE
 
118
#define profile_setjmp          prof_setjmp()
 
119
#else
 
120
#define profile_setjmp                  
 
121
#endif
 
122
 
 
123
#define throw_()                        (self)->throwException()
 
124
#define try_(n)                         int throw_##n; throw_##n = 0; TX_CHK_JMP(); \
 
125
                                                        (self)->jumpEnv[(self)->jumpDepth].jb_res_top = (self)->relTop; \
 
126
                                                        (self)->jumpEnv[(self)->jumpDepth].jb_call_top = (self)->callTop; \
 
127
                                                        (self)->jumpDepth++; profile_setjmp; \
 
128
                                                        if (setjmp((self)->jumpEnv[(self)->jumpDepth-1].jb_buffer)) goto catch_##n;
 
129
#define catch_(n)                       (self)->jumpDepth--; goto cont_##n; catch_##n: (self)->jumpDepth--; self->caught();
 
130
#define cont_(n)                        if (throw_##n) throw_(); cont_##n:
 
131
#define finally_(n)                     (self)->jumpDepth--; goto final_##n; catch_##n: throw_##n = 1; (self)->jumpDepth--; self->caught(); final_##n: {
 
132
#define finally_end_block(n) } if (throw_##n) throw_();
 
133
#define finally_end_block_no_throw(n) }
 
134
 
 
135
/*
 
136
 * -----------------------------------------------------------------------
 
137
 * The release stack
 
138
 */
 
139
 
 
140
#define push_(r)                        do { \
 
141
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
 
142
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
 
143
                                                                } \
 
144
                                                                (self)->relTop->r_type = CS_RELEASE_OBJECT; \
 
145
                                                                (self)->relTop->x.r_object = (r); \
 
146
                                                                (self)->relTop++; \
 
147
                                                        } while (0)
 
148
 
 
149
#define push_ptr_(r)                    do { \
 
150
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
 
151
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
 
152
                                                                } \
 
153
                                                                (self)->relTop->r_type = CS_RELEASE_MEM; \
 
154
                                                                (self)->relTop->x.r_mem = (r); \
 
155
                                                                (self)->relTop++; \
 
156
                                                        } while (0)
 
157
 
 
158
#define push_ref_(r)                    do { \
 
159
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
 
160
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
 
161
                                                                } \
 
162
                                                                (self)->relTop->r_type = CS_RELEASE_OBJECT_PTR; \
 
163
                                                                (self)->relTop->x.r_objectPtr = (CSObject **)&(r); \
 
164
                                                                (self)->relTop++; \
 
165
                                                        } while (0)
 
166
 
 
167
#define pop_(r)                         do { \
 
168
                                                                ASSERT((self)->relTop > (self)->relStack); \
 
169
                                                                if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
 
170
                                                                        ASSERT(((self)->relTop - 1)->x.r_object == ((CSObject *) r)); \
 
171
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX) {\
 
172
                                                                        ASSERT(((self)->relTop - 1)->x.r_mutex == ((CSMutex *) r)); \
 
173
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_POOLED) {\
 
174
                                                                        ASSERT(((self)->relTop - 1)->x.r_pooled == ((CSPooled *) r)); \
 
175
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
 
176
                                                                        ASSERT(((self)->relTop - 1)->x.r_mem == ((void *) r)); \
 
177
                                                                }  else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
 
178
                                                                        ASSERT(((self)->relTop - 1)->x.r_objectPtr == ((CSObject **) &(r))); \
 
179
                                                                }  else {\
 
180
                                                                        ASSERT(false); \
 
181
                                                                } \
 
182
                                                                (self)->relTop--; \
 
183
                                                        } while (0)
 
184
 
 
185
#define retain_(r)                      do { \
 
186
                                                                (r)->retain(); \
 
187
                                                                push_(r); \
 
188
                                                        } while (0)
 
189
 
 
190
#define release_(r)                     do {  \
 
191
                                                                ASSERT((self)->relTop > (self)->relStack); \
 
192
                                                                if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
 
193
                                                                        register CSObject *rp; \
 
194
                                                                        rp = ((self)->relTop - 1)->x.r_object; \
 
195
                                                                        ASSERT(rp == (CSObject *)(r)); \
 
196
                                                                        (self)->relTop--; \
 
197
                                                                        rp->release(); \
 
198
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
 
199
                                                                        register void *mem; \
 
200
                                                                        mem = ((self)->relTop - 1)->x.r_mem; \
 
201
                                                                        ASSERT(mem == (void *)(r)); \
 
202
                                                                        (self)->relTop--; \
 
203
                                                                        cs_free(mem); \
 
204
                                                                }  else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
 
205
                                                                        register CSObject **rp; \
 
206
                                                                        rp = ((self)->relTop - 1)->x.r_objectPtr; \
 
207
                                                                        ASSERT(rp == (CSObject **)&(r)); \
 
208
                                                                        (self)->relTop--; \
 
209
                                                                        if(*rp) (*rp)->release(); \
 
210
                                                                } else {\
 
211
                                                                        ASSERT(false); \
 
212
                                                                } \
 
213
                                                        } while (0)
 
214
 
 
215
#define lock_(r)                        do { \
 
216
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
 
217
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
 
218
                                                                } \
 
219
                                                                (r)->lock(); \
 
220
                                                                (self)->relTop->r_type = CS_RELEASE_MUTEX; \
 
221
                                                                (self)->relTop->x.r_mutex = (r); \
 
222
                                                                (self)->relTop++; \
 
223
                                                        } while (0)
 
224
 
 
225
#define locked_(r)                      do { \
 
226
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) \
 
227
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
 
228
                                                                (self)->relTop->r_type = CS_RELEASE_MUTEX; \
 
229
                                                                (self)->relTop->x.r_mutex = (r); \
 
230
                                                                (self)->relTop++; \
 
231
                                                        } while (0)
 
232
 
 
233
#define unlock_(r)                      do {  \
 
234
                                                                register CSMutex *rp; \
 
235
                                                                ASSERT((self)->relTop > (self)->relStack); \
 
236
                                                                ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX); \
 
237
                                                                rp = ((self)->relTop - 1)->x.r_mutex; \
 
238
                                                                ASSERT(rp == (r)); \
 
239
                                                                (self)->relTop--; \
 
240
                                                                rp->unlock(); \
 
241
                                                        } while (0)
 
242
 
 
243
#define frompool_(r)            do { \
 
244
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
 
245
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
 
246
                                                                } \
 
247
                                                                (self)->relTop->r_type = CS_RELEASE_POOLED; \
 
248
                                                                (self)->relTop->x.r_pooled = (r); \
 
249
                                                                (self)->relTop++; \
 
250
                                                        } while (0)
 
251
 
 
252
#define backtopool_(r)          do {  \
 
253
                                                                register CSPooled *rp; \
 
254
                                                                ASSERT((self)->relTop > (self)->relStack); \
 
255
                                                                ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_POOLED); \
 
256
                                                                rp = ((self)->relTop - 1)->x.r_pooled; \
 
257
                                                                ASSERT(rp == (r)); \
 
258
                                                                (self)->relTop--; \
 
259
                                                                rp->returnToPool(); \
 
260
                                                        } while (0)
 
261
 
 
262
#endif