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
* The definitions are used by all code, and is NOT required
31
#ifndef __CSGLOBAL_H__
32
#define __CSGLOBAL_H__
39
/* This is the call context: */
40
#define CS_CONTEXT __FUNC__, __FILE__, __LINE__
43
int cs_assert(const char *func, const char *file, int line, const char *message);
44
int cs_hope(const char *func, const char *file, int line, const char *message);
46
#define ASSERT(x) ((x) ? 1 : cs_assert(CS_CONTEXT, #x))
47
#define HOPE(x) ((x) ? 1 : cs_hope(CS_CONTEXT, #x))
54
#define retain() retain(__FUNC__, __FILE__, __LINE__)
55
#define release() release(__FUNC__, __FILE__, __LINE__)
58
#define new_(v, t) do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
61
* -----------------------------------------------------------------------
66
* This macro must be placed at the start of every function.
67
* It records the current context so that we can
68
* dump a type of stack trace later if necessary.
70
* It also sets up the current thread pointer 'self'.
73
#define STACK_CHECK CSReleasePtr self_reltop = self->relTop
78
#define inner_() int cs_frame = self->callTop++; \
81
if (cs_frame< CS_CALL_STACK_SIZE) { \
82
self->callStack[cs_frame].cs_func = __FUNC__; \
83
self->callStack[cs_frame].cs_file = __FILE__; \
84
self->callStack[cs_frame].cs_line = __LINE__; \
88
#define outer_() self->callTop = cs_frame; \
89
ASSERT(self->relTop == self_reltop);
91
#define enter_() CSThread *self = CSThread::getSelf(); \
95
* On exit to a function, either exit_() or
96
* return_() must be called.
98
#define exit_() do { \
104
#define return_(x) do { \
111
* -----------------------------------------------------------------------
112
* Throwing and catching (the jump stack)
115
int prof_setjmp(void);
117
#define TX_CHK_JMP() if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
119
#define profile_setjmp prof_setjmp()
121
#define profile_setjmp
124
#define throw_() (self)->throwException()
125
#define try_(n) int throw_##n; throw_##n = 0; TX_CHK_JMP(); \
126
(self)->jumpEnv[(self)->jumpDepth].jb_res_top = (self)->relTop; \
127
(self)->jumpEnv[(self)->jumpDepth].jb_call_top = (self)->callTop; \
128
(self)->jumpDepth++; profile_setjmp; \
129
if (setjmp((self)->jumpEnv[(self)->jumpDepth-1].jb_buffer)) goto catch_##n;
130
#define catch_(n) (self)->jumpDepth--; goto cont_##n; catch_##n: (self)->jumpDepth--; self->caught();
131
#define cont_(n) if (throw_##n) throw_(); cont_##n:
132
#define finally_(n) (self)->jumpDepth--; goto final_##n; catch_##n: throw_##n = 1; (self)->jumpDepth--; self->caught(); final_##n: {
133
#define finally_end_block(n) } if (throw_##n) throw_();
134
#define finally_end_block_no_throw(n) }
137
* -----------------------------------------------------------------------
141
#define push_(r) do { \
142
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
143
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
145
(self)->relTop->r_type = CS_RELEASE_OBJECT; \
146
(self)->relTop->x.r_object = (r); \
150
#define push_ptr_(r) do { \
151
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
152
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
154
(self)->relTop->r_type = CS_RELEASE_MEM; \
155
(self)->relTop->x.r_mem = (r); \
159
#define push_ref_(r) do { \
160
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
161
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
163
(self)->relTop->r_type = CS_RELEASE_OBJECT_PTR; \
164
(self)->relTop->x.r_objectPtr = (CSObject **)&(r); \
168
#define pop_(r) do { \
169
ASSERT((self)->relTop > (self)->relStack); \
170
if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
171
ASSERT(((self)->relTop - 1)->x.r_object == ((CSObject *) r)); \
172
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX) {\
173
ASSERT(((self)->relTop - 1)->x.r_mutex == ((CSMutex *) r)); \
174
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_POOLED) {\
175
ASSERT(((self)->relTop - 1)->x.r_pooled == ((CSPooled *) r)); \
176
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
177
ASSERT(((self)->relTop - 1)->x.r_mem == ((void *) r)); \
178
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
179
ASSERT(((self)->relTop - 1)->x.r_objectPtr == ((CSObject **) &(r))); \
186
#define retain_(r) do { \
191
#define release_(r) do { \
192
ASSERT((self)->relTop > (self)->relStack); \
193
if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
194
register CSObject *rp; \
195
rp = ((self)->relTop - 1)->x.r_object; \
196
ASSERT(rp == (CSObject *)(r)); \
199
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
200
register void *mem; \
201
mem = ((self)->relTop - 1)->x.r_mem; \
202
ASSERT(mem == (void *)(r)); \
205
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
206
register CSObject **rp; \
207
rp = ((self)->relTop - 1)->x.r_objectPtr; \
208
ASSERT(rp == (CSObject **)&(r)); \
210
if(*rp) (*rp)->release(); \
216
#define lock_(r) do { \
217
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
218
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
221
(self)->relTop->r_type = CS_RELEASE_MUTEX; \
222
(self)->relTop->x.r_mutex = (r); \
226
#define locked_(r) do { \
227
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) \
228
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
229
(self)->relTop->r_type = CS_RELEASE_MUTEX; \
230
(self)->relTop->x.r_mutex = (r); \
234
#define unlock_(r) do { \
235
register CSMutex *rp; \
236
ASSERT((self)->relTop > (self)->relStack); \
237
ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX); \
238
rp = ((self)->relTop - 1)->x.r_mutex; \
244
#define frompool_(r) do { \
245
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
246
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
248
(self)->relTop->r_type = CS_RELEASE_POOLED; \
249
(self)->relTop->x.r_pooled = (r); \
253
#define backtopool_(r) do { \
254
register CSPooled *rp; \
255
ASSERT((self)->relTop > (self)->relStack); \
256
ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_POOLED); \
257
rp = ((self)->relTop - 1)->x.r_pooled; \
260
rp->returnToPool(); \