summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-07-26 21:12:00 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-07-28 09:31:00 +0200
commitf85fc367e01eb0f5918263b1fcdfc8b7d16065c1 (patch)
tree3c78c3f0d4720b186a56f79c55cd3f31dc530fe5
parent2dfd5eae33e079bc92a15ccfd561901ea7b69e45 (diff)
downloadlibgit2-cmn/error-buffer.tar.gz
error: store the error messages in a reusable buffercmn/error-buffer
Instead of allocating a brand new buffer for each error string we want to store, we can use a per-thread buffer to store the error string and re-use the underlying storage. We already use the buffer to format the string, so this mostly makes that more direct.
-rw-r--r--src/errors.c50
-rw-r--r--src/global.c14
-rw-r--r--src/global.h1
3 files changed, 42 insertions, 23 deletions
diff --git a/src/errors.c b/src/errors.c
index 7a2600586..56fad009f 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -18,19 +18,30 @@ static git_error g_git_oom_error = {
GITERR_NOMEMORY
};
-static void set_error(int error_class, char *string)
+static void set_error_from_buffer(int error_class)
{
git_error *error = &GIT_GLOBAL->error_t;
+ git_buf *buf = &GIT_GLOBAL->error_buf;
- if (error->message != string)
- git__free(error->message);
-
- error->message = string;
+ error->message = buf->ptr;
error->klass = error_class;
GIT_GLOBAL->last_error = error;
}
+static void set_error(int error_class, char *string)
+{
+ git_buf *buf = &GIT_GLOBAL->error_buf;
+
+ git_buf_clear(buf);
+ if (string) {
+ git_buf_puts(buf, string);
+ git__free(string);
+ }
+
+ set_error_from_buffer(error_class);
+}
+
void giterr_set_oom(void)
{
GIT_GLOBAL->last_error = &g_git_oom_error;
@@ -38,27 +49,28 @@ void giterr_set_oom(void)
void giterr_set(int error_class, const char *string, ...)
{
- git_buf buf = GIT_BUF_INIT;
va_list arglist;
#ifdef GIT_WIN32
DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
#endif
int error_code = (error_class == GITERR_OS) ? errno : 0;
+ git_buf *buf = &GIT_GLOBAL->error_buf;
+ git_buf_clear(buf);
if (string) {
va_start(arglist, string);
- git_buf_vprintf(&buf, string, arglist);
+ git_buf_vprintf(buf, string, arglist);
va_end(arglist);
if (error_class == GITERR_OS)
- git_buf_PUTS(&buf, ": ");
+ git_buf_PUTS(buf, ": ");
}
if (error_class == GITERR_OS) {
#ifdef GIT_WIN32
char * win32_error = git_win32_get_error_message(win32_error_code);
if (win32_error) {
- git_buf_puts(&buf, win32_error);
+ git_buf_puts(buf, win32_error);
git__free(win32_error);
SetLastError(0);
@@ -66,26 +78,29 @@ void giterr_set(int error_class, const char *string, ...)
else
#endif
if (error_code)
- git_buf_puts(&buf, strerror(error_code));
+ git_buf_puts(buf, strerror(error_code));
if (error_code)
errno = 0;
}
- if (!git_buf_oom(&buf))
- set_error(error_class, git_buf_detach(&buf));
+ if (!git_buf_oom(buf))
+ set_error_from_buffer(error_class);
}
void giterr_set_str(int error_class, const char *string)
{
- char *message;
+ git_buf *buf = &GIT_GLOBAL->error_buf;
assert(string);
- message = git__strdup(string);
+ if (!string)
+ return;
- if (message)
- set_error(error_class, message);
+ git_buf_clear(buf);
+ git_buf_puts(buf, string);
+ if (!git_buf_oom(buf))
+ set_error_from_buffer(error_class);
}
int giterr_set_regex(const regex_t *regex, int error_code)
@@ -119,13 +134,14 @@ void giterr_clear(void)
int giterr_detach(git_error *cpy)
{
git_error *error = GIT_GLOBAL->last_error;
+ git_buf *buf = &GIT_GLOBAL->error_buf;
assert(cpy);
if (!error)
return -1;
- cpy->message = error->message;
+ cpy->message = git_buf_detach(buf);
cpy->klass = error->klass;
error->message = NULL;
diff --git a/src/global.c b/src/global.c
index 37a47bd27..3d37ee4de 100644
--- a/src/global.c
+++ b/src/global.c
@@ -279,18 +279,19 @@ int git_libgit2_shutdown(void)
git_global_st *git__global_state(void)
{
- void *ptr;
+ git_global_st *ptr;
assert(git_atomic_get(&git__n_inits) > 0);
if ((ptr = TlsGetValue(_tls_index)) != NULL)
return ptr;
- ptr = git__malloc(sizeof(git_global_st));
+ ptr = git__calloc(1, sizeof(git_global_st));
if (!ptr)
return NULL;
- memset(ptr, 0x0, sizeof(git_global_st));
+ git_buf_init(&ptr->error_buf, 0);
+
TlsSetValue(_tls_index, ptr);
return ptr;
}
@@ -378,18 +379,18 @@ int git_libgit2_shutdown(void)
git_global_st *git__global_state(void)
{
- void *ptr;
+ git_global_st *ptr;
assert(git_atomic_get(&git__n_inits) > 0);
if ((ptr = pthread_getspecific(_tls_key)) != NULL)
return ptr;
- ptr = git__malloc(sizeof(git_global_st));
+ ptr = git__calloc(1, sizeof(git_global_st));
if (!ptr)
return NULL;
- memset(ptr, 0x0, sizeof(git_global_st));
+ git_buf_init(&ptr->error_buf, 0);
pthread_setspecific(_tls_key, ptr);
return ptr;
}
@@ -407,6 +408,7 @@ int git_libgit2_init(void)
ssl_inited = 1;
}
+ git_buf_init(&__state.error_buf, 0);
return git_atomic_inc(&git__n_inits);
}
diff --git a/src/global.h b/src/global.h
index fdad6ba89..37e909ac6 100644
--- a/src/global.h
+++ b/src/global.h
@@ -14,6 +14,7 @@
typedef struct {
git_error *last_error;
git_error error_t;
+ git_buf error_buf;
char oid_fmt[GIT_OID_HEXSZ+1];
} git_global_st;