On Friday 28 November 2014 14:44:30 Richard W.M. Jones wrote:
[NOTE: this is not the complete patch. Once ACKed, I will make the same mechanical change to all the other places in the library that use this pattern.] --- src/guestfs-internal.h | 24 ++++++++ src/inspect-fs-unix.c | 164 +++++++++++-------------------------------------- 2 files changed, 59 insertions(+), 129 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index fd0c4a1..33d28f5 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -667,6 +667,30 @@ extern int guestfs___match6 (guestfs_h *g, const char *str, const pcre *re, char #define match4 guestfs___match4 #define match6 guestfs___match6
+/* Macro which compiles the regexp once when the library is loaded, + * and frees it when the library is unloaded. + */ +#define COMPILE_REGEXP(name,pattern,options) \ + static void compile_regexp_##name (void) __attribute__((constructor)); \ + static void free_regexp_##name (void) __attribute__((destructor)); \ + static pcre *name; \ + static void \ + compile_regexp_##name (void) \ + { \ + const char *err; \ + int offset; \ + name = pcre_compile ((pattern), (options), &err, &offset, NULL); \ + if (name == NULL) { \ + ignore_value (write (2, err, strlen (err))); \ + abort (); \ + } \ + } \ + static void \ + free_regexp_##name (void) \ + { \ + pcre_free (name); \ + }
Sounds okay, I guess it shouldn't introduce much overhead in the library loading? I also wonder whether we can delay the creation of those regexps (i.e. not just the ones mentioned in this patch) when just needed; something like the (untested): #define COMPILE_REGEXP(name,pattern,options) \ static void free_regexp_##name (void) __attribute__((destructor)); \ static pcre *_internal_##name; \ static void \ ##name (void) \ { \ if (_internal_##name == NULL) { \ const char *err; \ int offset; \ _internal_##name = pcre_compile ((pattern), (options), \ &err, &offset, NULL); \ if (_internal_##name == NULL) { \ ignore_value (write (2, err, strlen (err))); \ abort (); \ } \ } \ return _internal_##name; \ } \ static void \ free_regexp_##name (void) \ { \ if (_internal_##name) \ pcre_free (_internal_##name); \ } using it e.g.: match (re_major_minor (), ...) The only issue I could see is that the above is not thread-safe. -- Pino Toscano