summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2003-07-14 20:08:27 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2003-07-14 20:08:27 (GMT)
commit8a98abf66f4d672e6f0fbfa4719d0100b54ff2e0 (patch)
treef9a8424c7945ce64a3ef88ac17d9855cb89a37f0 /src
parent49dc44366672eada497939f80b2dd044ce627054 (diff)
downloadhdf5-8a98abf66f4d672e6f0fbfa4719d0100b54ff2e0.zip
hdf5-8a98abf66f4d672e6f0fbfa4719d0100b54ff2e0.tar.gz
hdf5-8a98abf66f4d672e6f0fbfa4719d0100b54ff2e0.tar.bz2
[svn-r7225] Purpose: error API gradual checkin
Platforms tested: RH 8; c and c++
Diffstat (limited to 'src')
-rw-r--r--src/H5E.c416
-rw-r--r--src/H5Eprivate.h32
-rw-r--r--src/H5Epublic.h36
-rw-r--r--src/H5Iprivate.h6
-rw-r--r--src/H5Ipublic.h4
5 files changed, 459 insertions, 35 deletions
diff --git a/src/H5E.c b/src/H5E.c
index 15657c0..efe937a 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -206,8 +206,33 @@ static int interface_initialize_g = 0;
* types to reset in H5E_term_interface().
*/
hid_t H5E_ERR_CLS_g = FAIL;
+
#endif /* NEW_ERR */
+#ifndef NEW_ERR
+#ifdef H5_HAVE_THREADSAFE
+/*
+ * The per-thread error stack. pthread_once() initializes a special
+ * key that will be used by all threads to create a stack specific to
+ * each thread individually. The association of stacks to threads will
+ * be handled by the pthread library.
+ *
+ * In order for this macro to work, H5E_get_my_stack() must be preceeded
+ * by "H5E_t *estack =".
+ */
+H5E_t_new *H5E_get_stack_new(void);
+#define H5E_get_my_stack_new() H5E_get_stack_new()
+#else
+/*
+ * The error stack. Eventually we'll have some sort of global table so each
+ * thread has it's own stack. The stacks will be created on demand when the
+ * thread first calls H5E_push(). */
+H5E_t_new H5E_stack_g_new[1];
+#define H5E_get_my_stack_new() (H5E_stack_g_new+0)
+#endif
+
+#endif
+
#ifdef H5_HAVE_THREADSAFE
/*
* The per-thread error stack. pthread_once() initializes a special
@@ -249,9 +274,7 @@ void *H5E_auto_data_g = NULL;
/* Static function declarations */
static herr_t H5E_init_interface (void);
#ifndef NEW_ERR
-static hid_t H5E_register_class(const char *cls_name, const char *lib_name,
- const char *version);
-static hid_t H5E_unregister_class(H5E_cls_t *cls);
+static int H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key);
#endif /* NEW_ERR */
static herr_t H5E_walk_cb (int n, H5E_error_t *err_desc, void *client_data);
@@ -318,10 +341,15 @@ H5E_init_interface(void)
FUNC_ENTER_NOINIT(H5E_init_interface);
- /* Initialize the atom group for the dataset IDs */
- if(H5I_init_group(H5I_ERROR_CLASS, H5I_ERRORCLS_HASHSIZE, H5E_ERRCLS_RESERVED_ATOMS,
- (H5I_free_t)H5E_unregister_class)<0)
- HGOTO_ERROR (H5E_ERROR, H5E_CANTINIT, FAIL, "unable to initialize interface");
+ /* Initialize the atom group for the error class IDs */
+ H5I_init_group(H5I_ERROR_CLASS, H5I_ERRCLS_HASHSIZE, H5E_RESERVED_ATOMS,
+ (H5I_free_t)H5E_unregister_class);
+ /* Initialize the atom group for the major error IDs */
+ H5I_init_group(H5I_ERROR_MSG, H5I_ERRMSG_HASHSIZE, H5E_RESERVED_ATOMS,
+ (H5I_free_t)H5E_close_msg);
+ /* Initialize the atom group for the error stacks */
+ H5I_init_group(H5I_ERROR_STACK, H5I_ERRSTK_HASHSIZE, H5E_RESERVED_ATOMS,
+ (H5I_free_t)H5E_close_stack);
/* From the old function; take out later */
H5E_auto_data_g = stderr;
@@ -407,7 +435,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static hid_t
+hid_t
H5E_register_class(const char *cls_name, const char *lib_name, const char *version)
{
hid_t ret_value; /* Return value */
@@ -488,21 +516,383 @@ done:
*
*-------------------------------------------------------------------------
*/
-static hid_t
+herr_t
H5E_unregister_class(H5E_cls_t *cls)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5E_unregister_class, FAIL);
+
+ H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls);
+
+ if(cls) {
+ if(cls->cls_name)
+ H5MM_xfree(cls->cls_name);
+ if(cls->lib_name)
+ H5MM_xfree(cls->lib_name);
+ if(cls->lib_vers)
+ H5MM_xfree(cls->lib_vers);
+ H5MM_xfree(cls);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_close_msg_cb
+ *
+ * Purpose: H5I_search callback function to close error messages in the
+ * error class.
+ *
+ * Programmer: Raymond Lu
+ * July 14, 2003
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5E_msg_t *err_msg = (H5E_msg_t*)obj_ptr;
+ H5E_cls_t *cls = (H5E_cls_t*)key;
+
+ FUNC_ENTER_NOAPI(H5_close_msg_cb, FAIL);
+
+ assert(obj_ptr);
+
+ if(err_msg->cls == cls)
+ H5E_close_msg(err_msg);
+
+ done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Eclose_msg
+ *
+ * Purpose: Closes a major or minor error.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 11, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Eclose_msg(hid_t err_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5E_msg_t *err;
+
+ FUNC_ENTER_API(H5Eclose_msg, FAIL);
+ H5TRACE1("e","i",err_id);
+
+ /* Need to check for errors */
+ err = H5I_object_verify(err_id, H5I_ERROR_MSG);
+
+ /* Decrement the counter. It will be freed if the count reaches zero. */
+ H5I_dec_ref(err_id);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_close_msg
+ *
+ * Purpose: Private function to close an error messge.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 11, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_close_msg(H5E_msg_t *err)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5E_close_msg, FAIL);
+
+ /* Doesn't free err->cls here */
+ if(err) {
+ if(err->msg)
+ H5MM_xfree(err->msg);
+ H5MM_xfree(err);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ecreate_msg
+ *
+ * Purpose: Creates a major or minor error, returns an ID.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 11, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Ecreate_msg(hid_t cls, H5E_type_t msg_type, const char *msg)
+{
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Ecreate_msg, FAIL);
+
+ ret_value = H5E_create_msg(cls, msg_type, msg);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_create_msg
+ *
+ * Purpose: Private function to create a major or minor error.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 11, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5E_create_msg(hid_t cls_id, H5E_type_t msg_type, const char *msg)
+{
+ hid_t ret_value; /* Return value */
+ H5E_msg_t *msg_ptr;
+
+ FUNC_ENTER_NOAPI(H5E_create_msg, FAIL);
+
+ /* Check arguments */
+ assert(msg);
+
+ /* Need to check for failures from malloc & strdup */
+ msg_ptr = H5MM_malloc(sizeof(H5E_msg_t));
+
+ msg_ptr->cls = H5I_object_verify(cls_id, H5I_ERROR_CLASS);
+ msg_ptr->type = msg_type;
+ msg_ptr->msg = HDstrdup(msg);
+
+ /* Register the new error message to get an ID for it */
+ /* Need to check for error */
+ ret_value = H5I_register(H5I_ERROR_MSG, msg_ptr);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+#ifdef H5_HAVE_THREADSAFE
+/*-------------------------------------------------------------------------
+ * Function: H5E_get_stack_new
+ *
+ * Purpose: Support function for H5E_get_my_stack() to initialize and
+ * acquire per-thread error stack.
+ *
+ * Return: Success: error stack (H5E_t *)
+ *
+ * Failure: NULL
+ *
+ * Programmer: Chee Wai LEE
+ * April 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5E_t_new *
+H5E_get_stack_new(void)
+{
+ H5E_t_new *estack;
+ H5E_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5E_get_stack_new,NULL);
+
+ estack = pthread_getspecific(H5TS_errstk_key_g);
+ if (!estack) {
+ /* no associated value with current thread - create one */
+ estack = (H5E_t_new *)H5MM_malloc(sizeof(H5E_t_new));
+ pthread_setspecific(H5TS_errstk_key_g, (void *)estack);
+ }
+
+ /* Set return value */
+ ret_value=estack;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+#endif /* H5_HAVE_THREADSAFE */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Eget_current_stack
+ *
+ * Purpose: Registers current error stack, returns object handle for it,
+ * clears it.
+ *
+ * Return: Non-negative value as stack ID on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 14, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Eget_current_stack(void)
+{
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Eget_current_stack, FAIL);
+ H5TRACE0("i","");
+
+ /* Add HGOTO_ERROR later */
+ ret_value=H5E_get_current_stack();
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_get_current_stack
+ *
+ * Purpose: Private function to register an error stack.
+ *
+ * Return: Non-negative value as class ID on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 11, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5E_get_current_stack(void)
+{
+ hid_t ret_value; /* Return value */
+ H5E_t_new *estack = H5E_get_my_stack_new ();
- H5MM_xfree(cls->cls_name);
- H5MM_xfree(cls->lib_name);
- H5MM_xfree(cls->lib_vers);
- H5MM_xfree(cls);
+ FUNC_ENTER_NOAPI(H5E_get_current_stack, FAIL);
+
+ /* Register the error stack to get an ID for it */
+ /* Need to check for error */
+ ret_value = H5I_register(H5I_ERROR_STACK, estack);
done:
FUNC_LEAVE_NOAPI(ret_value);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Eclose_stack
+ *
+ * Purpose: Closes an error stack.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 14, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Eclose_stack(hid_t stack_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5E_t_new *err_stack;
+
+ FUNC_ENTER_API(H5Eclose_stack, FAIL);
+ H5TRACE1("e","i",stack_id);
+
+ /* Add HGOTO_ERROR later */
+ if(H5E_DEFAULT == stack_id)
+ ;
+
+ /* Need to check for errors */
+ err_stack = H5I_object_verify(stack_id, H5I_ERROR_STACK);
+
+ /*
+ * Decrement the counter on the dataset. It will be freed if the count
+ * reaches zero.
+ */
+ /* Need to check for errors */
+ H5I_dec_ref(stack_id);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_close_stack
+ *
+ * Purpose: Private function to close an error stack.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 14, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_close_stack(H5E_t_new *err_stack)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5E_error_t_new *error;
+ int i;
+
+ FUNC_ENTER_NOAPI(H5E_close_stack, FAIL);
+
+ if(err_stack) {
+ for(i=0; i<err_stack->nused; i++) {
+ error = &(err_stack->slot[i]);
+ if(error->func_name)
+ H5MM_xfree(error->func_name);
+ if(error->file_name)
+ H5MM_xfree(error->file_name);
+ if(error->desc)
+ H5MM_xfree(error->desc);
+ }
+ H5MM_xfree(err_stack);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
#endif /* NEW_ERR */
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index 58a7acf..56ed9d5 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -27,7 +27,7 @@
#ifndef NEW_ERR
-#define H5E_ERRCLS_RESERVED_ATOMS 0
+#define H5E_RESERVED_ATOMS 0
typedef struct H5E_cls_t {
char *cls_name;
@@ -35,15 +35,17 @@ typedef struct H5E_cls_t {
char *lib_vers;
} H5E_cls_t;
-typedef struct H5E_maj_t {
- char *mesg;
- H5E_cls_t *cls;
-} H5E_maj_t;
+typedef struct H5E_msg_t {
+ char *msg;
+ H5E_type_t type;
+ H5E_cls_t *cls;
+} H5E_msg_t;
-typedef struct H5E_min_t {
- char *mesg;
- H5E_cls_t *cls;
-} H5E_min_t;
+/* An error stack */
+typedef struct H5E_t_new {
+ int nused; /*num slots currently used in stack */
+ H5E_error_t_new slot[H5E_NSLOTS]; /*array of error records */
+} H5E_t_new;
#ifdef TMP
/* HDF5 error class */
@@ -277,6 +279,18 @@ H5_DLL herr_t H5E_clear (void);
H5_DLL herr_t H5E_walk (H5E_direction_t dir, H5E_walk_t func,
void *client_data);
+#ifndef NEW_ERR
+/* New error API */
+H5_DLL hid_t H5E_register_class(const char *cls_name, const char *lib_name,
+ const char *version);
+H5_DLL herr_t H5E_unregister_class(H5E_cls_t *cls);
+H5_DLL herr_t H5E_close_msg(H5E_msg_t *err);
+H5_DLL hid_t H5E_create_msg(hid_t cls_id, H5E_type_t msg_type, const char *msg);
+H5_DLL hid_t H5E_get_current_stack(void);
+H5_DLL herr_t H5E_close_stack(H5E_t_new *err_stack);
+
+#endif /* NEW_ERR */
+
#ifdef H5_HAVE_PARALLEL
/*
* MPI error handling macros.
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 9a46f1f..792c637 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -26,12 +26,26 @@
#ifndef NEW_ERR
-typedef enum H5E_msg_t {
- H5E_MSG_ERROR =-1,
- H5E_MSG_MAJOR,
- H5E_MSG_MINOR,
- H5E_MSG_LIMIT
-} H5E_msg_t;
+#define H5E_DEFAULT 0
+
+/* Take out _new later */
+typedef enum H5E_type_t {
+ H5E_ERROR_new =-1,
+ H5E_MAJOR_new,
+ H5E_MINOR_new,
+ H5E_LIMIT_new
+} H5E_type_t;
+
+/* Information about an error; element of error stack */
+typedef struct H5E_error_t_new {
+ hid_t cls_id; /*class ID */
+ hid_t maj_id; /*major error ID */
+ hid_t min_id; /*minor error number */
+ const char *func_name; /*function in which error occurred */
+ const char *file_name; /*file in which error occurred */
+ unsigned line; /*line in file where error occurs */
+ const char *desc; /*optional supplied description */
+} H5E_error_t_new;
/* When this header is included from H5Eprivate.h, don't make calls to H5open() */
#undef H5OPEN
@@ -417,8 +431,6 @@ extern "C" {
typedef herr_t (*H5E_walk_t)(int n, H5E_error_t *err_desc, void *client_data);
typedef herr_t (*H5E_auto_t)(void *client_data);
-H5_DLL hid_t H5Eregister_class(const char *cls_name, const char *lib_name, const char *version);
-H5_DLL herr_t H5Eunregister_class(hid_t class_id);
H5_DLL herr_t H5Eset_auto (H5E_auto_t func, void *client_data);
H5_DLL herr_t H5Eget_auto (H5E_auto_t *func, void **client_data);
H5_DLL herr_t H5Eclear (void);
@@ -430,6 +442,14 @@ H5_DLL const char *H5Eget_minor (H5E_minor_t minor_number);
H5_DLL herr_t H5Epush(const char *file, const char *func,
unsigned line, H5E_major_t maj, H5E_minor_t min, const char *str);
+/* New error API */
+H5_DLL hid_t H5Eregister_class(const char *cls_name, const char *lib_name, const char *version);
+H5_DLL herr_t H5Eunregister_class(hid_t class_id);
+H5_DLL herr_t H5Eclose_msg(hid_t err_id);
+H5_DLL hid_t H5Ecreate_msg(hid_t cls, H5E_type_t msg_type, const char *msg);
+H5_DLL hid_t H5Eget_current_stack(void);
+H5_DLL herr_t H5Eclose_stack(hid_t stack_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 1174e5b..3b67ba1 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -42,9 +42,9 @@
#define H5I_VFL_HASHSIZE 64
#define H5I_GENPROPCLS_HASHSIZE 64
#define H5I_GENPROPOBJ_HASHSIZE 128
-#define H5I_ERRORCLS_HASHSIZE 64
-#define H5I_MAJORERR_HASHSIZE 64
-#define H5I_MINORERR_HASHSIZE 64
+#define H5I_ERRCLS_HASHSIZE 64
+#define H5I_ERRMSG_HASHSIZE 64
+#define H5I_ERRSTK_HASHSIZE 64
/*
* Function for freeing objects. This function will be called with an object
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index acf64af..3087ce9 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -43,8 +43,8 @@ typedef enum {
H5I_GENPROP_CLS, /*group ID for generic property list classes */
H5I_GENPROP_LST, /*group ID for generic property lists */
H5I_ERROR_CLASS, /*group ID for error classes */
- H5I_ERROR_MAJOR, /*group ID for major errors */
- H5I_ERROR_MINOR, /*group ID for minor errors */
+ H5I_ERROR_MSG, /*group ID for error messages */
+ H5I_ERROR_STACK, /*group ID for error stacks */
H5I_NGROUPS /*number of valid groups, MUST BE LAST! */
} H5I_type_t;