diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2015-02-18 13:48:58 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-02-18 13:48:58 +1100 |
commit | 84c66e709b9ff0d4f993fc231c507034e6e9220a (patch) | |
tree | 2a3294f17619b098efebde251933742c87f8e146 /src | |
parent | 6ad817ec5df8131a642bf79c3bb79a6bc6d0aa8a (diff) | |
parent | d5131a90497c19f13d01384cb050a339ab1753c7 (diff) | |
download | mongo-84c66e709b9ff0d4f993fc231c507034e6e9220a.tar.gz |
Merge pull request #1629 from wiredtiger/session-strerror
WT_SESSION.strerror
Diffstat (limited to 'src')
-rw-r--r-- | src/config/config_def.c | 4 | ||||
-rw-r--r-- | src/conn/api_strerror.c | 39 | ||||
-rw-r--r-- | src/conn/conn_api.c | 2 | ||||
-rw-r--r-- | src/include/config.h | 17 | ||||
-rw-r--r-- | src/include/extern.h | 4 | ||||
-rw-r--r-- | src/include/session.h | 2 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 23 | ||||
-rw-r--r-- | src/include/wiredtiger_ext.h | 11 | ||||
-rw-r--r-- | src/os_posix/os_errno.c | 30 | ||||
-rw-r--r-- | src/os_win/os_errno.c | 30 | ||||
-rw-r--r-- | src/session/session_api.c | 25 | ||||
-rw-r--r-- | src/support/err.c | 14 |
12 files changed, 110 insertions, 91 deletions
diff --git a/src/config/config_def.c b/src/config/config_def.c index b04cd823055..43d87c518e4 100644 --- a/src/config/config_def.c +++ b/src/config/config_def.c @@ -668,6 +668,10 @@ static const WT_CONFIG_ENTRY config_entries[] = { "force=0", confchk_session_salvage }, + { "session.strerror", + "", + NULL + }, { "session.truncate", "", NULL diff --git a/src/conn/api_strerror.c b/src/conn/api_strerror.c index 4b2f6f12f7c..f08d70969dd 100644 --- a/src/conn/api_strerror.c +++ b/src/conn/api_strerror.c @@ -5,7 +5,7 @@ /* * Historically, there was only the wiredtiger_strerror call because the POSIX * port didn't need anything more complex; Windows requires memory allocation - * of error strings, so we added the wiredtiger_strerror_r call. Because we + * of error strings, so we added the WT_SESSION.strerror method. Because we * want wiredtiger_strerror to continue to be as thread-safe as possible, errors * are split into three categories: WiredTiger constant strings, system constant * strings and Everything Else, and we check constant strings before Everything @@ -16,8 +16,8 @@ * __wiredtiger_error -- * Return a constant string for the WiredTiger errors. */ -static const char * -__wiredtiger_error(int error) +const char * +__wt_wiredtiger_error(int error) { switch (error) { case WT_ROLLBACK: @@ -49,34 +49,15 @@ wiredtiger_strerror(int error) const char *p; /* Check for a constant string. */ - if ((p = __wiredtiger_error(error)) != NULL || - (p = __wt_strerror(error)) != NULL) + if ((p = __wt_wiredtiger_error(error)) != NULL) + return (p); + if ((p = __wt_strerror(error)) != NULL) return (p); /* Else, fill in the non-thread-safe static buffer. */ - if (wiredtiger_strerror_r(error, buf, sizeof(buf)) != 0) - (void)snprintf(buf, sizeof(buf), "error return: %d", error); - - return (buf); -} - -/* - * wiredtiger_strerror_r -- - * Return a string for any error value, thread-safe version. - */ -int -wiredtiger_strerror_r(int error, char *buf, size_t buflen) -{ - const char *p; - - /* Require at least 2 bytes, printable character and trailing nul. */ - if (buflen < 2) - return (ENOMEM); - - /* Check for a constant string. */ - if ((p = __wiredtiger_error(error)) != NULL || - (p = __wt_strerror(error)) != NULL) - return (snprintf(buf, buflen, "%s", p) > 0 ? 0 : ENOMEM); + if (snprintf(buf, sizeof(buf), "error return: %d", error) > 0) + return (buf); - return (__wt_strerror_r(error, buf, buflen)); + /* OK, we're done. */ + return ("Unable to return error string"); } diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c index 5be55a77f24..0562f9cfc34 100644 --- a/src/conn/conn_api.c +++ b/src/conn/conn_api.c @@ -117,7 +117,7 @@ __conn_get_extension_api(WT_CONNECTION *wt_conn) conn->extension_api.conn = wt_conn; conn->extension_api.err_printf = __wt_ext_err_printf; conn->extension_api.msg_printf = __wt_ext_msg_printf; - conn->extension_api.strerror = wiredtiger_strerror; + conn->extension_api.strerror = __wt_ext_strerror; conn->extension_api.scr_alloc = __wt_ext_scr_alloc; conn->extension_api.scr_free = __wt_ext_scr_free; conn->extension_api.collator_config = ext_collator_config; diff --git a/src/include/config.h b/src/include/config.h index 65757c2ef6d..046f515188c 100644 --- a/src/include/config.h +++ b/src/include/config.h @@ -73,14 +73,15 @@ struct __wt_config_parser_impl { #define WT_CONFIG_ENTRY_session_rename 24 #define WT_CONFIG_ENTRY_session_rollback_transaction 25 #define WT_CONFIG_ENTRY_session_salvage 26 -#define WT_CONFIG_ENTRY_session_truncate 27 -#define WT_CONFIG_ENTRY_session_upgrade 28 -#define WT_CONFIG_ENTRY_session_verify 29 -#define WT_CONFIG_ENTRY_table_meta 30 -#define WT_CONFIG_ENTRY_wiredtiger_open 31 -#define WT_CONFIG_ENTRY_wiredtiger_open_all 32 -#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 33 -#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 34 +#define WT_CONFIG_ENTRY_session_strerror 27 +#define WT_CONFIG_ENTRY_session_truncate 28 +#define WT_CONFIG_ENTRY_session_upgrade 29 +#define WT_CONFIG_ENTRY_session_verify 30 +#define WT_CONFIG_ENTRY_table_meta 31 +#define WT_CONFIG_ENTRY_wiredtiger_open 32 +#define WT_CONFIG_ENTRY_wiredtiger_open_all 33 +#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 34 +#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 35 /* * configuration section: END * DO NOT EDIT: automatically built by dist/flags.py. diff --git a/src/include/extern.h b/src/include/extern.h index 40493b4aab4..3b08d79e842 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -198,6 +198,7 @@ extern void __wt_conn_config_discard(WT_SESSION_IMPL *session); extern int __wt_ext_config_parser_open(WT_EXTENSION_API *wt_ext, WT_SESSION *wt_session, const char *config, size_t len, WT_CONFIG_PARSER **config_parserp); extern int __wt_ext_config_get(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, WT_CONFIG_ARG *cfg_arg, const char *key, WT_CONFIG_ITEM *cval); extern int __wt_config_upgrade(WT_SESSION_IMPL *session, WT_ITEM *buf); +extern const char *__wt_wiredtiger_error(int error); extern int __wt_collator_config(WT_SESSION_IMPL *session, const char *uri, WT_CONFIG_ITEM *cname, WT_CONFIG_ITEM *metadata, WT_COLLATOR **collatorp, int *ownp); extern int __wt_conn_remove_collator(WT_SESSION_IMPL *session); extern int __wt_conn_remove_compressor(WT_SESSION_IMPL *session); @@ -438,7 +439,7 @@ extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, i extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh); extern int __wt_errno(void); extern const char *__wt_strerror(int error); -extern int __wt_strerror_r(int error, char *buf, size_t buflen); +extern const char *__wt_session_strerror(WT_SESSION_IMPL *session, int error); extern int __wt_exist(WT_SESSION_IMPL *session, const char *filename, int *existp); extern void __wt_fallocate_config(WT_SESSION_IMPL *session, WT_FH *fh); extern int __wt_fallocate( WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, wt_off_t len); @@ -574,6 +575,7 @@ extern void __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUN extern int __wt_ext_err_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); extern int __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); extern int __wt_ext_msg_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); +extern const char *__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, int error); extern int __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v); extern void __wt_assert(WT_SESSION_IMPL *session, int error, const char *file_name, int line_number, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 5, 6))); extern int __wt_panic(WT_SESSION_IMPL *session); diff --git a/src/include/session.h b/src/include/session.h index 909f1daf5a4..36df35a104e 100644 --- a/src/include/session.h +++ b/src/include/session.h @@ -111,6 +111,8 @@ struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) __wt_session_impl { } *scratch_track; #endif + WT_ITEM err; /* Error buffer */ + WT_TXN_ISOLATION isolation; WT_TXN txn; /* Transaction state */ u_int ncursors; /* Count of active file cursors. */ diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in index 772295f7104..d0d0f9eec77 100644 --- a/src/include/wiredtiger.in +++ b/src/include/wiredtiger.in @@ -835,6 +835,17 @@ struct __wt_session { int __F(reconfigure)(WT_SESSION *session, const char *config); /*! + * Return information about an error as a string. + * + * @snippet ex_all.c Display an error thread safe + * + * @param session the session handle + * @param error a return value from a WiredTiger function + * @returns a string representation of the error + */ + const char *__F(strerror)(WT_SESSION *session, int error); + + /*! * @name Cursor handles * @{ */ @@ -2092,18 +2103,6 @@ int wiredtiger_open(const char *home, */ const char *wiredtiger_strerror(int error); -/*! - * Return information about a WiredTiger error as a string, thread-safe version. - * - * @snippet ex_all.c Display an error thread safe - * - * @param error a return value from a WiredTiger call - * @param buf a buffer of at least \c buflen bytes - * @param buflen the length of the buffer - * @returns zero for success, non-zero to indicate an error. - */ -int wiredtiger_strerror_r(int error, char *buf, size_t buflen); - #if !defined(SWIG) /*! * The interface implemented by applications to accept notifications diff --git a/src/include/wiredtiger_ext.h b/src/include/wiredtiger_ext.h index ee27b32ddf7..28fd8e18329 100644 --- a/src/include/wiredtiger_ext.h +++ b/src/include/wiredtiger_ext.h @@ -118,16 +118,17 @@ struct __wt_extension_api { WT_EXTENSION_API *, WT_SESSION *session, const char *fmt, ...); /*! - * Return information about an error as a string; the strerror method - * is a superset of the ISO C99/POSIX 1003.1-2001 function strerror. + * Return information about an error as a string. * * @snippet ex_data_source.c WT_EXTENSION_API strerror * - * @param err a return value from a WiredTiger, C library or POSIX - * function + * @param wt_api the extension handle + * @param session the session handle (or NULL if none available) + * @param error a return value from a WiredTiger function * @returns a string representation of the error */ - const char *(*strerror)(int err); + const char *(*strerror)( + WT_EXTENSION_API *, WT_SESSION *session, int error); /*! * Allocate short-term use scratch memory. diff --git a/src/os_posix/os_errno.c b/src/os_posix/os_errno.c index a58f13583ce..c022cfda6bc 100644 --- a/src/os_posix/os_errno.c +++ b/src/os_posix/os_errno.c @@ -43,27 +43,23 @@ __wt_strerror(int error) } /* - * __wt_strerror_r -- - * POSIX implementation of wiredtiger_strerror_r. + * __wt_session_strerror -- + * POSIX implementation of WT_SESSION.strerror. */ -int -__wt_strerror_r(int error, char *buf, size_t buflen) +const char * +__wt_session_strerror(WT_SESSION_IMPL *session, int error) { const char *p; - /* Require at least 2 bytes, printable character and trailing nul. */ - if (buflen < 2) - return (ENOMEM); + /* Check for POSIX errors. */ + if ((p = __wt_strerror(error)) != NULL) + return (p); - /* - * Check for POSIX errors then fallback to something generic. Copy the - * string into the user's buffer, return success if anything printed. - */ - p = __wt_strerror(error); - if (p != NULL && snprintf(buf, buflen, "%s", p) > 0) - return (0); + /* Fallback to a generic message. */ + if (__wt_buf_fmt( + session, &session->err, "error return: %d", error) == 0) + return (session->err.data); - /* Fallback to a generic message, then guess it's a memory problem. */ - return ( - snprintf(buf, buflen, "error return: %d", error) > 0 ? 0 : ENOMEM); + /* Defeated. */ + return ("Unable to return error string"); } diff --git a/src/os_win/os_errno.c b/src/os_win/os_errno.c index 00ee638fbe3..c81432299a3 100644 --- a/src/os_win/os_errno.c +++ b/src/os_win/os_errno.c @@ -77,27 +77,23 @@ __wt_strerror(int error) } /* - * __wt_strerror_r -- - * Windows implementation of wiredtiger_strerror_r. + * __wt_session_strerror -- + * Windows implementation of WT_SESSION.strerror. */ -int -__wt_strerror_r(int error, char *buf, size_t buflen) +const char * +__wt_session_strerror(WT_SESSION_IMPL *session, int error) { DWORD lasterror; const char *p; - - /* Require at least 2 bytes, printable character and trailing nul. */ - if (buflen < 2) - return (ENOMEM); + char buf[256]; /* * Check for POSIX errors, Windows errors, then fallback to something * generic. Copy the string into the user's buffer, return success if * anything printed. */ - p = __wt_strerror(error); - if (p != NULL && snprintf(buf, buflen, "%s", p) > 0) - return (0); + if ((p = __wt_strerror(error)) != NULL) + return (p); if (error < 0) { error = __wt_map_error_to_windows_error(error); @@ -109,16 +105,16 @@ __wt_strerror_r(int error, char *buf, size_t buflen) error, 0, /* let system choose the correct LANGID */ buf, - buflen, + sizeof(buf), NULL); - if (lasterror != 0) - return (0); + if (lasterror != 0 && + __wt_buf_set(session, &session->err, buf, strlen(buf)) == 0) + return (session->err.data); /* Fall through to the fallback error code */ } - /* Fallback to a generic message, then guess it's a memory problem. */ - return ( - snprintf(buf, buflen, "error return: %d", error) > 0 ? 0 : ENOMEM); + /* Defeated. */ + return ("Unable to return error string"); } diff --git a/src/session/session_api.c b/src/session/session_api.c index 0affc567583..986473ae1cc 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -128,8 +128,9 @@ __session_close(WT_SESSION *wt_session, const char *config) /* Discard metadata tracking. */ __wt_meta_track_discard(session); - /* Discard scratch buffers. */ + /* Discard scratch buffers, error memory. */ __wt_scr_discard(session); + __wt_buf_free(session, &session->err); /* Free transaction information. */ __wt_txn_destroy(session); @@ -902,6 +903,27 @@ err: F_CLR(session, WT_SESSION_CAN_WAIT | WT_SESSION_NO_CACHE_CHECK); } /* + * __session_strerror -- + * WT_SESSION->strerror method. + */ +static const char * +__session_strerror(WT_SESSION *wt_session, int error) +{ + WT_SESSION_IMPL *session; + const char *p; + + session = (WT_SESSION_IMPL *)wt_session; + + /* Check for a constant string. */ + if ((p = __wt_wiredtiger_error(error)) != NULL) + return (p); + if ((p = __wt_strerror(error)) != NULL) + return (p); + + return (__wt_session_strerror(session, error)); +} + +/* * __wt_open_internal_session -- * Allocate a session for WiredTiger's use. */ @@ -963,6 +985,7 @@ __wt_open_session(WT_CONNECTION_IMPL *conn, NULL, __session_close, __session_reconfigure, + __session_strerror, __session_open_cursor, __session_create, __session_compact, diff --git a/src/support/err.c b/src/support/err.c index d766fcba33a..49a3891c58a 100644 --- a/src/support/err.c +++ b/src/support/err.c @@ -409,6 +409,20 @@ __wt_ext_msg_printf( } /* + * __wt_ext_strerror -- + * Extension API call to return an error as a string. + */ +const char * +__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, int error) +{ + if (wt_session == NULL) + wt_session = (WT_SESSION *) + ((WT_CONNECTION_IMPL *)wt_api->conn)->default_session; + + return (wt_session->strerror(wt_session, error)); +} + +/* * __wt_progress -- * Progress message. */ |