mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-07 16:22:40 +00:00
error: store the error messages in a reusable 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.
This commit is contained in:
parent
2dfd5eae33
commit
f85fc367e0
50
src/errors.c
50
src/errors.c
@ -18,19 +18,30 @@ static git_error g_git_oom_error = {
|
|||||||
GITERR_NOMEMORY
|
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_error *error = &GIT_GLOBAL->error_t;
|
||||||
|
git_buf *buf = &GIT_GLOBAL->error_buf;
|
||||||
|
|
||||||
if (error->message != string)
|
error->message = buf->ptr;
|
||||||
git__free(error->message);
|
|
||||||
|
|
||||||
error->message = string;
|
|
||||||
error->klass = error_class;
|
error->klass = error_class;
|
||||||
|
|
||||||
GIT_GLOBAL->last_error = error;
|
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)
|
void giterr_set_oom(void)
|
||||||
{
|
{
|
||||||
GIT_GLOBAL->last_error = &g_git_oom_error;
|
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, ...)
|
void giterr_set(int error_class, const char *string, ...)
|
||||||
{
|
{
|
||||||
git_buf buf = GIT_BUF_INIT;
|
|
||||||
va_list arglist;
|
va_list arglist;
|
||||||
#ifdef GIT_WIN32
|
#ifdef GIT_WIN32
|
||||||
DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
|
DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
|
||||||
#endif
|
#endif
|
||||||
int error_code = (error_class == GITERR_OS) ? errno : 0;
|
int error_code = (error_class == GITERR_OS) ? errno : 0;
|
||||||
|
git_buf *buf = &GIT_GLOBAL->error_buf;
|
||||||
|
|
||||||
|
git_buf_clear(buf);
|
||||||
if (string) {
|
if (string) {
|
||||||
va_start(arglist, string);
|
va_start(arglist, string);
|
||||||
git_buf_vprintf(&buf, string, arglist);
|
git_buf_vprintf(buf, string, arglist);
|
||||||
va_end(arglist);
|
va_end(arglist);
|
||||||
|
|
||||||
if (error_class == GITERR_OS)
|
if (error_class == GITERR_OS)
|
||||||
git_buf_PUTS(&buf, ": ");
|
git_buf_PUTS(buf, ": ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error_class == GITERR_OS) {
|
if (error_class == GITERR_OS) {
|
||||||
#ifdef GIT_WIN32
|
#ifdef GIT_WIN32
|
||||||
char * win32_error = git_win32_get_error_message(win32_error_code);
|
char * win32_error = git_win32_get_error_message(win32_error_code);
|
||||||
if (win32_error) {
|
if (win32_error) {
|
||||||
git_buf_puts(&buf, win32_error);
|
git_buf_puts(buf, win32_error);
|
||||||
git__free(win32_error);
|
git__free(win32_error);
|
||||||
|
|
||||||
SetLastError(0);
|
SetLastError(0);
|
||||||
@ -66,26 +78,29 @@ void giterr_set(int error_class, const char *string, ...)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (error_code)
|
if (error_code)
|
||||||
git_buf_puts(&buf, strerror(error_code));
|
git_buf_puts(buf, strerror(error_code));
|
||||||
|
|
||||||
if (error_code)
|
if (error_code)
|
||||||
errno = 0;
|
errno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!git_buf_oom(&buf))
|
if (!git_buf_oom(buf))
|
||||||
set_error(error_class, git_buf_detach(&buf));
|
set_error_from_buffer(error_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
void giterr_set_str(int error_class, const char *string)
|
void giterr_set_str(int error_class, const char *string)
|
||||||
{
|
{
|
||||||
char *message;
|
git_buf *buf = &GIT_GLOBAL->error_buf;
|
||||||
|
|
||||||
assert(string);
|
assert(string);
|
||||||
|
|
||||||
message = git__strdup(string);
|
if (!string)
|
||||||
|
return;
|
||||||
|
|
||||||
if (message)
|
git_buf_clear(buf);
|
||||||
set_error(error_class, message);
|
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)
|
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)
|
int giterr_detach(git_error *cpy)
|
||||||
{
|
{
|
||||||
git_error *error = GIT_GLOBAL->last_error;
|
git_error *error = GIT_GLOBAL->last_error;
|
||||||
|
git_buf *buf = &GIT_GLOBAL->error_buf;
|
||||||
|
|
||||||
assert(cpy);
|
assert(cpy);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cpy->message = error->message;
|
cpy->message = git_buf_detach(buf);
|
||||||
cpy->klass = error->klass;
|
cpy->klass = error->klass;
|
||||||
|
|
||||||
error->message = NULL;
|
error->message = NULL;
|
||||||
|
14
src/global.c
14
src/global.c
@ -279,18 +279,19 @@ int git_libgit2_shutdown(void)
|
|||||||
|
|
||||||
git_global_st *git__global_state(void)
|
git_global_st *git__global_state(void)
|
||||||
{
|
{
|
||||||
void *ptr;
|
git_global_st *ptr;
|
||||||
|
|
||||||
assert(git_atomic_get(&git__n_inits) > 0);
|
assert(git_atomic_get(&git__n_inits) > 0);
|
||||||
|
|
||||||
if ((ptr = TlsGetValue(_tls_index)) != NULL)
|
if ((ptr = TlsGetValue(_tls_index)) != NULL)
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
ptr = git__malloc(sizeof(git_global_st));
|
ptr = git__calloc(1, sizeof(git_global_st));
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(ptr, 0x0, sizeof(git_global_st));
|
git_buf_init(&ptr->error_buf, 0);
|
||||||
|
|
||||||
TlsSetValue(_tls_index, ptr);
|
TlsSetValue(_tls_index, ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -378,18 +379,18 @@ int git_libgit2_shutdown(void)
|
|||||||
|
|
||||||
git_global_st *git__global_state(void)
|
git_global_st *git__global_state(void)
|
||||||
{
|
{
|
||||||
void *ptr;
|
git_global_st *ptr;
|
||||||
|
|
||||||
assert(git_atomic_get(&git__n_inits) > 0);
|
assert(git_atomic_get(&git__n_inits) > 0);
|
||||||
|
|
||||||
if ((ptr = pthread_getspecific(_tls_key)) != NULL)
|
if ((ptr = pthread_getspecific(_tls_key)) != NULL)
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
ptr = git__malloc(sizeof(git_global_st));
|
ptr = git__calloc(1, sizeof(git_global_st));
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(ptr, 0x0, sizeof(git_global_st));
|
git_buf_init(&ptr->error_buf, 0);
|
||||||
pthread_setspecific(_tls_key, ptr);
|
pthread_setspecific(_tls_key, ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -407,6 +408,7 @@ int git_libgit2_init(void)
|
|||||||
ssl_inited = 1;
|
ssl_inited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
git_buf_init(&__state.error_buf, 0);
|
||||||
return git_atomic_inc(&git__n_inits);
|
return git_atomic_inc(&git__n_inits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
git_error *last_error;
|
git_error *last_error;
|
||||||
git_error error_t;
|
git_error error_t;
|
||||||
|
git_buf error_buf;
|
||||||
char oid_fmt[GIT_OID_HEXSZ+1];
|
char oid_fmt[GIT_OID_HEXSZ+1];
|
||||||
} git_global_st;
|
} git_global_st;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user