OSSP CVS Repository

ossp - Check-in [1682]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1682
Date: 2002-Jan-29 12:05:21 (local)
2002-Jan-29 11:05:21 (UTC)
User:rse
Branch:
Comment: overhaul __ex_ctx and __ex_terminate stuff
Tickets:
Inspections:
Files:
ossp-pkg/ex/ex.c      1.3 -> 1.4     22 inserted, 1 deleted
ossp-pkg/ex/ex.h      1.9 -> 1.10     30 inserted, 45 deleted
ossp-pkg/ex/ex.pod      1.7 -> 1.8     68 inserted, 65 deleted

ossp-pkg/ex/ex.c 1.3 -> 1.4

--- ex.c 2002/01/26 22:35:02     1.3
+++ ex.c 2002/01/29 11:05:21     1.4
@@ -28,7 +28,28 @@
 **  ex.c: exception handling (compiler part)
 */
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #include "ex.h"
 
-ex_ctx_t __ex_ctx_global;
+static ex_ctx_t *ex_ctx_default(void)
+{
+    static ex_ctx_t ctx = EX_CTX_INITIALIZER;
+
+    return &ctx;
+}
+
+static void ex_terminate_default(ex_t *e)
+{ 
+    fprintf(stderr,
+            "**EX: UNCAUGHT EXCEPTION: "
+            "class=0x%lx object=0x%lx value=0x%lx [%s:%d@%s]\n",
+            (long)((e)->ex_class), (long)((e)->ex_object), (long)((e)->ex_value),
+            (e)->ex_file, (e)->ex_line, (e)->ex_func);
+    abort();
+}
+
+ex_ctx_cb_t  __ex_ctx       = &ex_ctx_default;
+ex_term_cb_t __ex_terminate = &ex_terminate_default;
 


ossp-pkg/ex/ex.h 1.9 -> 1.10

--- ex.h 2002/01/27 19:38:49     1.9
+++ ex.h 2002/01/29 11:05:21     1.10
@@ -93,10 +93,10 @@
 
 /* declare the context type (private) */
 typedef struct {
-    __ex_mctx_t  *ctx_mctx;      /* permanent machine context of enclosing try/catch */
-    int           ctx_disabled;  /* permanent flag whether exception handling is disabled */
-    int           ctx_caught;    /* temporary flag whether exception was caught */
-    volatile ex_t ctx_ex;        /* temporary exception storage */
+    __ex_mctx_t  *ctx_mctx;     /* permanent machine context of enclosing try/catch */
+    int           ctx_disabled; /* permanent flag whether exception handling is disabled */
+    int           ctx_caught;   /* temporary flag whether exception was caught */
+    volatile ex_t ctx_ex;       /* temporary exception storage */
 } ex_ctx_t;
 
 /* the static and dynamic initializers for a context structure */
@@ -116,33 +116,17 @@
     } while (0)
 
 /* the exception context */
-#if defined(__EX_CTX_USE_STATIC__)
-static ex_ctx_t __ex_ctx_global;
-#define __ex_ctx (&__ex_ctx_global)
-#elif defined(__EX_CTX_USE_GLOBAL__) || !defined(__EX_CTX_USE_CUSTOM__)
-#define EX_CTX_GLOBAL ex_ctx_t __ex_ctx_global;
-extern ex_ctx_t __ex_ctx_global;
-#define __ex_ctx (&__ex_ctx_global)
-#endif
+typedef ex_ctx_t *(*ex_ctx_cb_t)(void);
+extern ex_ctx_cb_t __ex_ctx;
 
 /* the termination handler */
-#if defined(__EX_TERMINATE_USE_NOOP__)
-#define __ex_terminate(e) \
-    /* noop */
-#elif defined(__EX_TERMINATE_USE_ABORT__) || !defined(__EX_CTX_USE_CUSTOM__)
-#define __ex_terminate(e) \
-    ( fprintf(stderr, \
-              "**EX: UNCAUGHT EXCEPTION: " \
-              "class=0x%lx object=0x%lx value=0x%lx [%s:%d@%s]\n", \
-              (long)((e)->ex_class), (long)((e)->ex_object), (long)((e)->ex_value), \
-              (e)->ex_file, (e)->ex_line, (e)->ex_func), \
-     abort() )
-#endif
+typedef void (*ex_term_cb_t)(ex_t *);
+extern ex_term_cb_t __ex_terminate; 
 
 /* the block for trying execution */
 #define ex_try \
     { \
-        ex_ctx_t *__ex_ctx_ptr = __ex_ctx; \
+        ex_ctx_t *__ex_ctx_ptr = __ex_ctx(); \
         __ex_mctx_t *__ex_mctx_en; \
         __ex_mctx_t __ex_mctx_me; \
         __ex_mctx_en = __ex_ctx_ptr->ctx_mctx; \
@@ -162,41 +146,42 @@
         } \
         __ex_ctx_ptr->ctx_mctx = __ex_mctx_en; \
     } \
-    if (   !(__ex_ctx->ctx_caught) \
-        || ((e) = __ex_ctx->ctx_ex, 0)) { \
+    if (   !(__ex_ctx()->ctx_caught) \
+        || ((e) = __ex_ctx()->ctx_ex, 0)) { \
     } \
     else
 
 /* the throwing of a new exception */
 #define ex_throw(c,o,v) \
-    (__ex_ctx->ctx_disabled ? 0 : \
-     (__ex_ctx->ctx_ex.ex_class  = (void *)(c), \
-      __ex_ctx->ctx_ex.ex_object = (void *)(o), \
-      __ex_ctx->ctx_ex.ex_value  = (void *)(v), \
-      __ex_ctx->ctx_ex.ex_file   = __FILE__, \
-      __ex_ctx->ctx_ex.ex_line   = __LINE__, \
-      __ex_ctx->ctx_ex.ex_func   = __EX_FUNC__, \
-      (  __ex_ctx->ctx_mctx == NULL \
-       ? (__ex_terminate(&(__ex_ctx->ctx_ex)), -1) \
-       : (__ex_mctx_restore(__ex_ctx->ctx_mctx), 1) )))
+    (__ex_ctx()->ctx_disabled ? 0 : \
+     (__ex_ctx()->ctx_ex.ex_class  = (void *)(c), \
+      __ex_ctx()->ctx_ex.ex_object = (void *)(o), \
+      __ex_ctx()->ctx_ex.ex_value  = (void *)(v), \
+      __ex_ctx()->ctx_ex.ex_file   = __FILE__, \
+      __ex_ctx()->ctx_ex.ex_line   = __LINE__, \
+      __ex_ctx()->ctx_ex.ex_func   = __EX_FUNC__, \
+      (  __ex_ctx()->ctx_mctx == NULL \
+       ? (__ex_terminate((ex_t *)&(__ex_ctx()->ctx_ex)), -1) \
+       : (__ex_mctx_restore(__ex_ctx()->ctx_mctx), 1) )))
 
 /* the re-throwing of an already caught exception */
 #define ex_rethrow \
-    (__ex_ctx->ctx_disabled ? 0 : \
-      (__ex_ctx->ctx_mctx == NULL ? (__ex_terminate(&(__ex_ctx->ctx_ex)), -1) : \
-        (__ex_mctx_restore(__ex_ctx->ctx_mctx), 1) ))
+    (__ex_ctx()->ctx_disabled ? 0 : \
+      (  __ex_ctx()->ctx_mctx == NULL \
+       ? (__ex_terminate((ex_t *)&(__ex_ctx()->ctx_ex)), -1) \
+       : (__ex_mctx_restore(__ex_ctx()->ctx_mctx), 1) ))
 
 /* shield an operation from exception handling */
 #define ex_shield \
-    for (__ex_ctx->ctx_disabled = 1; \
-         __ex_ctx->ctx_disabled == 1; \
-         __ex_ctx->ctx_disabled = 0)
+    for (__ex_ctx()->ctx_disabled = 1; \
+         __ex_ctx()->ctx_disabled == 1; \
+         __ex_ctx()->ctx_disabled = 0)
 
 /* exception handling tests */
 #define ex_catching \
-    (__ex_ctx->ctx_mctx != NULL)
+    (__ex_ctx()->ctx_mctx != NULL)
 #define ex_shielding \
-    (__ex_ctx->ctx_disabled)
+    (__ex_ctx()->ctx_disabled)
 
 /* optional namespace mapping */
 #if defined(__EX_NS_USE_UCCXX__)


ossp-pkg/ex/ex.pod 1.7 -> 1.8

--- ex.pod       2002/01/26 22:43:54     1.7
+++ ex.pod       2002/01/29 11:05:21     1.8
@@ -258,22 +258,13 @@
 =head2 Exception Context
 
 In order to maintain the exception catching stack and for passing the
-exception between the throw point and the catch point, B<OSSP ex> uses
-a global exception context macro B<__ex_ctx> holding a pointer to a
-structure of type B<ex_ctx_t>. This is a private data structure and
-should be treated as opaque by the user. 
-
-By default (define C<__EX_CTX_USE_GLOBAL__> or as long as
-C<__EX_CTX_USE_CUSTOM__> is not defined) this references a global
-variable C<__ex_ctx_global>. This variable is either defined by the user
-by placing the directive "C<EX_CTX_GLOBAL>" macro somewhere outside of
-any functions in the application or alternatively link the F<libex>
-library to the application.
-
-Alternatively one can define C<__EX_CTX_USE_STATIC__> to get a static
-declaration directly inside the header file (for small environments
-where F<ex.h> is included once only) or define C<__EX_CTX_USE_CUSTOM__>
-and provide an own macro definition for B<__ex_ctx>.
+exception between the throw and the catch point, B<OSSP ex> uses a
+global exception context, returned on-the-fly by the callback "ex_ctx_t
+*(*B<__ex_ctx>)(void)".
+
+The default B<__ex_ctx> (as provided by F<libex>) returns a pointer to
+a static B<ex_ctx_t> context. For use in multi-threading environments,
+this should be overwritten with a per-thread context structure.
 
 To initialize an exception context structure there are two macros
 defined: B<EX_CTX_INITIALIZER> for static initialization and
@@ -281,20 +272,17 @@
 
 =head2 Termination Handler
 
-In case there is an exception thrown which is not caught by
-any B<ex_try>/B<ex_catch> clauses, B<OSSP ex> calls the macro
-B<__ex_terminate>(C<ex_t *>). It receives a pointer to the exception
+In case there is an exception thrown which is not caught by any
+B<ex_try>/B<ex_catch> clauses, B<OSSP ex> calls the callback "void
+(*B<__ex_terminate>)(C<ex_t *>)". It receives a pointer to the exception
 object which should have been thrown.
 
-By default (define C<__EX_TERMINATE_USE_ABORT__> or as long as
-C<__EX_TERMINATE_USE_CUSTOM__> is not defined) this prints a message of
-the form "C<**EX: UNCAUGHT EXCEPTION: class=0xXXXXXXXX object=0xXXXXXXXX
-value=0xXXXXXXX [file:123:func]>" to F<stderr> and then calls abort(3)
-in order to terminate the application.
-
-Alternatively one can define C<__EX_TERMINATE_USE_NOOP__> to ignore the
-exception or or define C<__EX_TERMINATE_USE_CUSTOM__> and provide an own
-macro definition for B<__ex_terminate>.
+The default B<__ex_terminate> (as provided by F<libex>) this prints
+a message of the form "C<**EX: UNCAUGHT EXCEPTION: class=0xXXXXXXXX
+object=0xXXXXXXXX value=0xXXXXXXX [file:123:func]>" to F<stderr> and
+then calls abort(3) in order to terminate the application. For use in
+multi-threading environments, this should be overwritten with a callback
+function which terminates only the current thread.
 
 =head2 Namespace Mapping
 
@@ -307,10 +295,10 @@
 
 For this B<OSSP ex> optionally provides the ability to provide
 additional namespace mappings for those API macros. By default (define
-C<__EX_NS_USE_CXX__> o or as long as C<__EX_CTX_USE_CUSTOM__> and
-C<__cplusplus> is not defined) you can additional C++ style macros named
-B<catch>, B<throw>, B<rethrow> and B<shield>. As an alternative you
-can define C<__EX_NS_USE_UCCXX__> to get the same but with an (more
+C<__EX_NS_USE_CXX__> or as long as C<__EX_NS_USE_CUSTOM__> and
+C<__cplusplus> is not defined) you can additional C++ style macros
+named B<catch>, B<throw>, B<rethrow> and B<shield>. As an alternative
+you can define C<__EX_NS_USE_UCCXX__> to get the same but with an (more
 namespace safe) upper case first letter.
 
 =head1 MULTITHREADING ENVIRONMENTS
@@ -337,83 +325,98 @@
 
  #ifndef __PTH_EX_H__
  #define __PTH_EX_H__
-
- /* include GNU pth API */
+ 
  #include "pth.h"
  
- /* configure and include OSSP ex API */
- #define __EX_CTX_USE_CUSTOM__
- #define __ex_ctx \
-     (ex_ctx_t *)pth_getkey(ex_ctx_key)
- #define __ex_terminate(e) \
-     pth_exit(e->ex_value)
- #include "ex.h"
-
- int pth_init_ex(void);
- pth_t pth_spawn_ex(pth_attr_t attr, void *(*entry)(void *), void *arg);
-
- #ifndef PTH_EX_C
+ int   pth_init_ex  (void);
+ pth_t pth_spawn_ex (pth_attr_t attr, void *(*entry)(void *), void *arg);
+ 
+ #ifndef PTH_EX_INTERNAL
  #define pth_init  pth_ex_init
  #define pth_spawn pth_ex_spawn
  #endif
-
+ 
  #endif /* __PTH_EX_H__ */
 
 =item F<pth_ex.c>
 
- #define PTH_EX_C
+ #include <stdlib.h>
+ 
+ #define PTH_EX_INTERNAL
  #include "pth_ex.h"
-
+ #include "pth.h"
+ #include "ex.h"
+ 
  /* context storage key */
- static pth_key_t ex_ctx_key;
-
+ static pth_key_t pth_ex_ctx_key;
+ 
  /* context destructor */
- void ex_ctx_destroy(void *data)
+ static void pth_ex_ctx_destroy(void *data)
  {
      if (data != NULL)
          free(data);
      return;
  }
-
+ 
+ /* callback: context fetching */
+ static ex_ctx_t *pth_ex_ctx(void)
+ {
+     return (ex_ctx_t *)pth_key_getdata(pth_ex_ctx_key);
+ }
+ 
+ /* callback: termination */
+ static void pth_ex_terminate(ex_t *e)
+ {
+     pth_exit(e->ex_value);
+ }
+ 
  /* pth_init() wrapper */
  int pth_init_ex(void)
  {
      int rc;
-
+ 
+     /* perform original operation */
      rc = pth_init();
-     pth_key_create(&ex_ctx_key, ex_ctx_destroy);
+ 
+     /* additionally create thread data key and override OSSP ex callbacks */
+     pth_key_create(&pth_ex_ctx_key, pth_ex_ctx_destroy);
+     __ex_ctx       = pth_ex_ctx;
+     __ex_terminate = pth_ex_terminate;
+ 
      return rc;
  }
-
+ 
  /* internal thread entry wrapper information */
  typedef struct {
      void *(*entry)(void *);
      void *arg;
  } pth_spawn_ex_t;
-
+ 
  /* internal thread entry wrapper */
  static void *pth_spawn_wrapper(void *arg)
  {
      pth_spawn_ex_t *wrapper;
      ex_ctx_t *ex_ctx;
-
+ 
+     /* create per-thread exception context */
      wrapper = (pth_spawn_ex_t *)arg;
      ex_ctx = (ex_ctx_t *)malloc(sizeof(ex_ctx_t));
      EX_CTX_INITIALIZE(ex_ctx);
-     pth_key_setdata(ex_ctx_key, ex_ctx);
-     return wrapper.entry(wrapper.arg);
+     pth_key_setdata(pth_ex_ctx_key, ex_ctx);
+ 
+     /* perform original operation */
+     return wrapper->entry(wrapper->arg);
  }
-
+ 
  /* pth_spawn() wrapper */
  pth_t pth_spawn_ex(pth_attr_t attr, void *(*entry)(void *), void *arg)
  {
-     pth_t tid;
      pth_spawn_ex_t wrapper;
-
+ 
+     /* spawn thread but execute start function through wrapper */
      wrapper.entry = entry;
      wrapper.arg   = arg;
-     tid = pth_spawn(attr, pth_spawn_wrapper, &wrapper);
-     return tid;
+     return pth_spawn(attr, pth_spawn_wrapper, &wrapper);
  }
 
 =back

CVSTrac 2.0.1