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
30
#ifndef __CSGLOBAL_H__
31
#define __CSGLOBAL_H__
38
/* This is the call context: */
39
#define CS_CONTEXT __FUNC__, __FILE__, __LINE__
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);
45
#define ASSERT(x) ((x) ? 1 : cs_assert(CS_CONTEXT, #x))
46
#define HOPE(x) ((x) ? 1 : cs_hope(CS_CONTEXT, #x))
53
#define retain() retain(__FUNC__, __FILE__, __LINE__)
54
#define release() release(__FUNC__, __FILE__, __LINE__)
57
#define new_(v, t) do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
60
* -----------------------------------------------------------------------
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.
69
* It also sets up the current thread pointer 'self'.
72
#define STACK_CHECK CSReleasePtr self_reltop = self->relTop
77
#define inner_() int cs_frame = self->callTop++; \
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__; \
87
#define outer_() self->callTop = cs_frame; \
88
ASSERT(self->relTop == self_reltop);
90
#define enter_() CSThread *self = CSThread::getSelf(); \
94
* On exit to a function, either exit_() or
95
* return_() must be called.
97
#define exit_() do { \
103
#define return_(x) do { \
110
* -----------------------------------------------------------------------
111
* Throwing and catching (the jump stack)
114
int prof_setjmp(void);
116
#define TX_CHK_JMP() if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
118
#define profile_setjmp prof_setjmp()
120
#define profile_setjmp
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) }
136
* -----------------------------------------------------------------------
140
#define push_(r) do { \
141
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
142
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
144
(self)->relTop->r_type = CS_RELEASE_OBJECT; \
145
(self)->relTop->x.r_object = (r); \
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); \
153
(self)->relTop->r_type = CS_RELEASE_MEM; \
154
(self)->relTop->x.r_mem = (r); \
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); \
162
(self)->relTop->r_type = CS_RELEASE_OBJECT_PTR; \
163
(self)->relTop->x.r_objectPtr = (CSObject **)&(r); \
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))); \
185
#define retain_(r) do { \
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)); \
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)); \
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)); \
209
if(*rp) (*rp)->release(); \
215
#define lock_(r) do { \
216
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
217
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
220
(self)->relTop->r_type = CS_RELEASE_MUTEX; \
221
(self)->relTop->x.r_mutex = (r); \
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); \
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; \
243
#define frompool_(r) do { \
244
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
245
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
247
(self)->relTop->r_type = CS_RELEASE_POOLED; \
248
(self)->relTop->x.r_pooled = (r); \
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; \
259
rp->returnToPool(); \