123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*
- * $Id$
- *
- * Copyright (C) 2009 iptelorg GmbH
- *
- * This file is part of ser, a free SIP server.
- *
- * ser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * For a license to use the ser software under conditions
- * other than those described here, or to purchase support for this
- * software, please contact iptel.org by e-mail at the following addresses:
- * [email protected]
- *
- * ser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * History
- * -------
- * 2009-04-03 Initial version (Miklos)
- * 2010-04-25 Use own struct with locking to work-around libc locking failure
- * on multi-core hw (skeller)
- */
- #include <malloc.h> /* hook prototypes */
- #include "../../mem/shm_mem.h"
- #include "shm_regex.h"
- typedef void *(malloc_hook_t) (size_t, const void *);
- typedef void *(realloc_hook_t) (void *, size_t, const void *);
- typedef void (free_hook_t) (void *, const void *);
- /* The memory hooks are overwritten before calling regcomp(), regfree(),
- * and regexec(), and shared memory function are called
- * from the hooks instead of libc malloc/realloc/free.
- */
- static void *shm_malloc_hook(size_t size, const void *caller)
- {
- return shm_malloc (size);
- }
- static void *shm_realloc_hook(void *p, size_t size, const void *caller)
- {
- return shm_realloc (p, size);
- }
- static void shm_free_hook(void *ptr, const void *caller)
- {
- if (ptr) shm_free (ptr);
- }
- #define replace_malloc_hooks() \
- do { \
- orig_malloc_hook = __malloc_hook; \
- orig_realloc_hook = __realloc_hook; \
- orig_free_hook = __free_hook; \
- __malloc_hook = shm_malloc_hook; \
- __realloc_hook = shm_realloc_hook; \
- __free_hook = shm_free_hook; \
- } while (0)
- #define restore_malloc_hooks() \
- do { \
- __malloc_hook = orig_malloc_hook; \
- __realloc_hook = orig_realloc_hook; \
- __free_hook = orig_free_hook; \
- } while (0)
- int shm_regcomp(shm_regex_t *preg, const char *regex, int cflags)
- {
- malloc_hook_t *orig_malloc_hook;
- realloc_hook_t *orig_realloc_hook;
- free_hook_t *orig_free_hook;
- int ret;
- if(!lock_init(&preg->lock)) {
- return REG_EEND;
- }
- replace_malloc_hooks();
- ret = regcomp(&preg->regexp, regex, cflags);
- restore_malloc_hooks();
- if(ret) lock_destroy(&preg->lock);
- return ret;
- }
- void shm_regfree(shm_regex_t *preg)
- {
- malloc_hook_t *orig_malloc_hook;
- realloc_hook_t *orig_realloc_hook;
- free_hook_t *orig_free_hook;
- lock_destroy(&preg->lock);
- replace_malloc_hooks();
- regfree(&preg->regexp);
- restore_malloc_hooks();
- }
- int shm_regexec(shm_regex_t *preg, const char *string, size_t nmatch,
- regmatch_t pmatch[], int eflags)
- {
- malloc_hook_t *orig_malloc_hook;
- realloc_hook_t *orig_realloc_hook;
- free_hook_t *orig_free_hook;
- int ret;
- /* regexec() allocates some memory for the pattern buffer
- * when it is successfully called for the first time, therefore
- * shared memory is required also here.
- * The drawback is that shared memory allocation is also used
- * needlessly for allocating the temporary space for
- * the elements of pmatch. -- Does not happen if pmatch and
- * nmatch are 0.
- * It is safe to call regexec() concurrently without locking,
- * because regexec() has its own locks.
- * (Miklos)
- *
- * Those locks, however, don't work with shm and multi-core hardware
- * causing a dead-lock. Tested with glibc 2.3.6. (skeller)
- */
- lock_get(&preg->lock);
- replace_malloc_hooks();
- ret = regexec(&preg->regexp, string, nmatch,
- pmatch, eflags);
- restore_malloc_hooks();
- lock_release(&preg->lock);
- return ret;
- }
- size_t shm_regerror(int errcode, const shm_regex_t *preg, char *errbuf,
- size_t errbuf_size)
- {
- return regerror(errcode, &preg->regexp, errbuf, errbuf_size);
- }
|