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
* The definitions are used by all code, and is NOT required
30
#ifndef __CSGLOBAL_H__
31
#define __CSGLOBAL_H__
36
/* Those compilers that support the function
37
* macro (in particular the "pretty" function
38
* macro must be defined here.
41
#define __FUNC__ __FUNCTION__
42
#elif defined(OS_SOLARIS)
43
#define __FUNC__ "__func__"
45
#define __FUNC__ __PRETTY_FUNCTION__
49
/* This is the call context: */
50
#define CS_CONTEXT __FUNC__, __FILE__, __LINE__
53
int cs_assert(const char *func, const char *file, int line, const char *message);
54
int cs_hope(const char *func, const char *file, int line, const char *message);
56
#define ASSERT(x) ((x) ? 1 : cs_assert(CS_CONTEXT, #x))
57
#define HOPE(x) ((x) ? 1 : cs_hope(CS_CONTEXT, #x))
63
#define new_(v, t) do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
66
* -----------------------------------------------------------------------
71
* This macro must be placed at the start of every function.
72
* It records the current context so that we can
73
* dump a type of stack trace later if necessary.
75
* It also sets up the current thread pointer 'self'.
77
#define inner_() int cs_frame = self->callTop++; \
79
if (cs_frame< CS_CALL_STACK_SIZE) { \
80
self->callStack[cs_frame].cs_func = __FUNC__; \
81
self->callStack[cs_frame].cs_file = __FILE__; \
82
self->callStack[cs_frame].cs_line = __LINE__; \
86
#define outer_() self->callTop = cs_frame;
88
#define enter_() CSThread *self = CSThread::getSelf(); \
92
* On exit to a function, either exit_() or
93
* return_() must be called.
95
#define exit_() do { \
101
#define return_(x) do { \
108
* -----------------------------------------------------------------------
109
* Throwing and catching (the jump stack)
113
* Quote from the C99 spec on setjmp:
114
* All accessible objects have values, and all other components of the abstract
115
* machine have state, as of the time the longjmp function was called, except that
116
* the values of objects of automatic storage duration that are local to the function
117
* containing the invocation of the corresponding setjmp macro that do not have
118
* volatile-qualified type and have been changed between the setjmp invocation and
119
* longjmp call are indeterminate.
121
* GCC will not put variables into registers for which the address gets taken do use
122
* CLOBBER_PROTECT() to protect variables from being clobbered.
123
* This came from Jens Thoms Toerring. Thanks!
125
#define CLOBBER_PROTECT(a) do { if ((void *)&(a) == (void*) 1) (a) = (a);} while(0)
127
int prof_setjmp(void);
129
#define TX_CHK_JMP() if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
131
#define profile_setjmp prof_setjmp()
133
#define profile_setjmp
136
#define throw_() (self)->throwException()
137
#define try_(n) int throw_##n; throw_##n = 0; TX_CHK_JMP(); \
138
(self)->jumpEnv[(self)->jumpDepth].jb_res_top = (self)->relTop; \
139
(self)->jumpEnv[(self)->jumpDepth].jb_call_top = (self)->callTop; \
140
(self)->jumpDepth++; profile_setjmp; \
141
if (setjmp((self)->jumpEnv[(self)->jumpDepth-1].jb_buffer)) goto catch_##n;
142
#define catch_(n) (self)->jumpDepth--; goto cont_##n; catch_##n: (self)->jumpDepth--; self->caught();
143
#define cont_(n) if (throw_##n) throw_(); cont_##n:
144
#define finally_(n) (self)->jumpDepth--; goto final_##n; catch_##n: throw_##n = 1; (self)->jumpDepth--; self->caught(); final_##n: {
145
#define finally_end_block(n) } if (throw_##n) throw_();
146
#define finally_end_block_no_throw(n) }
149
* -----------------------------------------------------------------------
153
#define push_(r) do { \
154
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
155
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
157
(self)->relTop->r_type = CS_RELEASE_OBJECT; \
158
(self)->relTop->x.r_object = (r); \
162
#define push_ptr_(r) do { \
163
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
164
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
166
(self)->relTop->r_type = CS_RELEASE_MEM; \
167
(self)->relTop->x.r_mem = (r); \
171
#define pop_(r) do { \
172
ASSERT((self)->relTop > (self)->relStack); \
173
if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
174
ASSERT(((self)->relTop - 1)->x.r_object == ((CSObject *) r)); \
175
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX) {\
176
ASSERT(((self)->relTop - 1)->x.r_mutex == ((CSMutex *) r)); \
177
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_POOLED) {\
178
ASSERT(((self)->relTop - 1)->x.r_pooled == ((CSPooled *) r)); \
179
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
180
ASSERT(((self)->relTop - 1)->x.r_mem == ((CSPooled *) r)); \
187
#define retain_(r) do { \
192
#define release_(r) do { \
193
ASSERT((self)->relTop > (self)->relStack); \
194
if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
195
register CSObject *rp; \
196
rp = ((self)->relTop - 1)->x.r_object; \
197
ASSERT(rp == (CSObject *)(r)); \
200
} else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
201
register void *mem; \
202
mem = ((self)->relTop - 1)->x.r_mem; \
203
ASSERT(mem == (void *)(r)); \
211
#define lock_(r) do { \
212
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
213
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
216
(self)->relTop->r_type = CS_RELEASE_MUTEX; \
217
(self)->relTop->x.r_mutex = (r); \
221
#define unlock_(r) do { \
222
register CSMutex *rp; \
223
ASSERT((self)->relTop > (self)->relStack); \
224
ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX); \
225
rp = ((self)->relTop - 1)->x.r_mutex; \
231
#define frompool_(r) do { \
232
if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
233
CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
235
(self)->relTop->r_type = CS_RELEASE_POOLED; \
236
(self)->relTop->x.r_pooled = (r); \
240
#define backtopool_(r) do { \
241
register CSPooled *rp; \
242
ASSERT((self)->relTop > (self)->relStack); \
243
ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_POOLED); \
244
rp = ((self)->relTop - 1)->x.r_pooled; \
247
rp->returnToPool(); \