Drizzled Public API Documentation

CSGlobal.h

00001 /* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
00002  *
00003  * PrimeBase Media Stream for MySQL
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  *
00019  * Original author: Paul McCullagh (H&G2JCtL)
00020  * Continued development: Barry Leslie
00021  *
00022  * 2007-05-20
00023  *
00024  * CORE SYSTEM:
00025  * The definitions are used by all code, and is NOT required
00026  * by any header file!
00027  *
00028  */
00029 
00030 #pragma once
00031 #ifndef __CSGLOBAL_H__
00032 #define __CSGLOBAL_H__
00033 
00034 #include "CSDefs.h"
00035 #include "CSObject.h"
00036 #include "CSThread.h"
00037 
00038 
00039 /* This is the call context: */
00040 #define CS_CONTEXT      __FUNC__, __FILE__, __LINE__
00041 
00042 #ifdef DEBUG
00043 int cs_assert(const char *func, const char *file, int line, const char *message);
00044 int cs_hope(const char *func, const char *file, int line, const char *message);
00045 
00046 #define ASSERT(x)     ((x) ? 1 : cs_assert(CS_CONTEXT, #x))
00047 #define HOPE(x)       ((x) ? 1 : cs_hope(CS_CONTEXT, #x))
00048 #else
00049 #define ASSERT(x)
00050 #define ASSERT(x)
00051 #endif
00052 
00053 #ifdef DEBUG
00054 #define retain()      retain(__FUNC__, __FILE__, __LINE__)
00055 #define release()     release(__FUNC__, __FILE__, __LINE__)
00056 #endif
00057 
00058 #define new_(v, t)      do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
00059 
00060 /*
00061  * -----------------------------------------------------------------------
00062  * Call stack
00063  */
00064 
00065 /*
00066  * This macro must be placed at the start of every function.
00067  * It records the current context so that we can
00068  * dump a type of stack trace later if necessary.
00069  *
00070  * It also sets up the current thread pointer 'self'.
00071  */
00072 #ifdef DEBUG
00073 #define STACK_CHECK    CSReleasePtr self_reltop = self->relTop
00074 #else
00075 #define STACK_CHECK   
00076 #endif
00077 
00078 #define inner_()      int     cs_frame = self->callTop++; \
00079               STACK_CHECK ; \
00080               do { \
00081                 if (cs_frame< CS_CALL_STACK_SIZE) { \
00082                   self->callStack[cs_frame].cs_func = __FUNC__; \
00083                   self->callStack[cs_frame].cs_file = __FILE__; \
00084                   self->callStack[cs_frame].cs_line = __LINE__; \
00085                 } \
00086               } while (0)
00087 
00088 #define outer_()      self->callTop = cs_frame; \
00089               ASSERT(self->relTop == self_reltop); 
00090 
00091 #define enter_()      CSThread  *self = CSThread::getSelf(); \
00092               inner_()
00093 
00094 /*
00095  * On exit to a function, either exit_() or
00096  * return_() must be called.
00097  */
00098 #define exit_()       do { \
00099                 outer_(); \
00100                 return; \
00101               } while (0)
00102           
00103 
00104 #define return_(x)      do { \
00105                 outer_(); \
00106                 return(x); \
00107               } while (0)
00108 
00109 
00110 /*
00111  * -----------------------------------------------------------------------
00112  * Throwing and catching (the jump stack)
00113  */
00114 
00115 int prof_setjmp(void);
00116 
00117 #define TX_CHK_JMP()    if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
00118 #ifdef PROFILE
00119 #define profile_setjmp    prof_setjmp()
00120 #else
00121 #define profile_setjmp      
00122 #endif
00123 
00124 #define throw_()      (self)->throwException()
00125 #define try_(n)       int throw_##n; throw_##n = 0; TX_CHK_JMP(); \
00126               (self)->jumpEnv[(self)->jumpDepth].jb_res_top = (self)->relTop; \
00127               (self)->jumpEnv[(self)->jumpDepth].jb_call_top = (self)->callTop; \
00128               (self)->jumpDepth++; profile_setjmp; \
00129               if (setjmp((self)->jumpEnv[(self)->jumpDepth-1].jb_buffer)) goto catch_##n;
00130 #define catch_(n)     (self)->jumpDepth--; goto cont_##n; catch_##n: (self)->jumpDepth--; self->caught();
00131 #define cont_(n)      if (throw_##n) throw_(); cont_##n:
00132 #define finally_(n)     (self)->jumpDepth--; goto final_##n; catch_##n: throw_##n = 1; (self)->jumpDepth--; self->caught(); final_##n: {
00133 #define finally_end_block(n) } if (throw_##n) throw_();
00134 #define finally_end_block_no_throw(n) }
00135 
00136 /*
00137  * -----------------------------------------------------------------------
00138  * The release stack
00139  */
00140 
00141 #define push_(r)      do { \
00142                 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00143                   CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00144                 } \
00145                 (self)->relTop->r_type = CS_RELEASE_OBJECT; \
00146                 (self)->relTop->x.r_object = (r); \
00147                 (self)->relTop++; \
00148               } while (0)
00149 
00150 #define push_ptr_(r)      do { \
00151                 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00152                   CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00153                 } \
00154                 (self)->relTop->r_type = CS_RELEASE_MEM; \
00155                 (self)->relTop->x.r_mem = (r); \
00156                 (self)->relTop++; \
00157               } while (0)
00158 
00159 #define push_ref_(r)      do { \
00160                 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00161                   CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00162                 } \
00163                 (self)->relTop->r_type = CS_RELEASE_OBJECT_PTR; \
00164                 (self)->relTop->x.r_objectPtr = (CSObject **)&(r); \
00165                 (self)->relTop++; \
00166               } while (0)
00167 
00168 #define pop_(r)       do { \
00169                 ASSERT((self)->relTop > (self)->relStack); \
00170                 if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
00171                   ASSERT(((self)->relTop - 1)->x.r_object == ((CSObject *) r)); \
00172                 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX) {\
00173                   ASSERT(((self)->relTop - 1)->x.r_mutex == ((CSMutex *) r)); \
00174                 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_POOLED) {\
00175                   ASSERT(((self)->relTop - 1)->x.r_pooled == ((CSPooled *) r)); \
00176                 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
00177                   ASSERT(((self)->relTop - 1)->x.r_mem == ((void *) r)); \
00178                 }  else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
00179                   ASSERT(((self)->relTop - 1)->x.r_objectPtr == ((CSObject **) &(r))); \
00180                 }  else {\
00181                   ASSERT(false); \
00182                 } \
00183                 (self)->relTop--; \
00184               } while (0)
00185 
00186 #define retain_(r)      do { \
00187                 (r)->retain(); \
00188                 push_(r); \
00189               } while (0)
00190 
00191 #define release_(r)     do {  \
00192                 ASSERT((self)->relTop > (self)->relStack); \
00193                 if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
00194                   register CSObject *rp; \
00195                   rp = ((self)->relTop - 1)->x.r_object; \
00196                   ASSERT(rp == (CSObject *)(r)); \
00197                   (self)->relTop--; \
00198                   rp->release(); \
00199                 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
00200                   register void *mem; \
00201                   mem = ((self)->relTop - 1)->x.r_mem; \
00202                   ASSERT(mem == (void *)(r)); \
00203                   (self)->relTop--; \
00204                   cs_free(mem); \
00205                 }  else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
00206                   register CSObject **rp; \
00207                   rp = ((self)->relTop - 1)->x.r_objectPtr; \
00208                   ASSERT(rp == (CSObject **)&(r)); \
00209                   (self)->relTop--; \
00210                   if(*rp) (*rp)->release(); \
00211                 } else {\
00212                   ASSERT(false); \
00213                 } \
00214               } while (0)
00215 
00216 #define lock_(r)      do { \
00217                 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00218                   CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00219                 } \
00220                 (r)->lock(); \
00221                 (self)->relTop->r_type = CS_RELEASE_MUTEX; \
00222                 (self)->relTop->x.r_mutex = (r); \
00223                 (self)->relTop++; \
00224               } while (0)
00225 
00226 #define locked_(r)      do { \
00227                 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) \
00228                   CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00229                 (self)->relTop->r_type = CS_RELEASE_MUTEX; \
00230                 (self)->relTop->x.r_mutex = (r); \
00231                 (self)->relTop++; \
00232               } while (0)
00233 
00234 #define unlock_(r)      do {  \
00235                 register CSMutex *rp; \
00236                 ASSERT((self)->relTop > (self)->relStack); \
00237                 ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX); \
00238                 rp = ((self)->relTop - 1)->x.r_mutex; \
00239                 ASSERT(rp == (r)); \
00240                 (self)->relTop--; \
00241                 rp->unlock(); \
00242               } while (0)
00243 
00244 #define frompool_(r)    do { \
00245                 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00246                   CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00247                 } \
00248                 (self)->relTop->r_type = CS_RELEASE_POOLED; \
00249                 (self)->relTop->x.r_pooled = (r); \
00250                 (self)->relTop++; \
00251               } while (0)
00252 
00253 #define backtopool_(r)    do {  \
00254                 register CSPooled *rp; \
00255                 ASSERT((self)->relTop > (self)->relStack); \
00256                 ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_POOLED); \
00257                 rp = ((self)->relTop - 1)->x.r_pooled; \
00258                 ASSERT(rp == (r)); \
00259                 (self)->relTop--; \
00260                 rp->returnToPool(); \
00261               } while (0)
00262 
00263 #endif