Mercurial > hg > nginx-quic
view src/core/ngx_regex.c @ 4311:45272aab5eea
Unlock of shared memory zones on process crash.
If process exited abnormally while holding lock on some shared memory zone -
unlock it. It may be not safe thing to do (as crash with lock held may
result in corrupted shared memory structure, and other processes will
subsequently crash while trying to access shared data), therefore complain
loudly if unlock succeeds.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 23 Nov 2011 14:09:19 +0000 |
parents | 169d84ff4064 |
children | 7423800ef437 |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> static void * ngx_libc_cdecl ngx_regex_malloc(size_t size); static void ngx_libc_cdecl ngx_regex_free(void *p); static ngx_pool_t *ngx_pcre_pool; void ngx_regex_init(void) { pcre_malloc = ngx_regex_malloc; pcre_free = ngx_regex_free; } static ngx_inline void ngx_regex_malloc_init(ngx_pool_t *pool) { #if (NGX_THREADS) ngx_core_tls_t *tls; if (ngx_threaded) { tls = ngx_thread_get_tls(ngx_core_tls_key); tls->pool = pool; return; } #endif ngx_pcre_pool = pool; } static ngx_inline void ngx_regex_malloc_done(void) { #if (NGX_THREADS) ngx_core_tls_t *tls; if (ngx_threaded) { tls = ngx_thread_get_tls(ngx_core_tls_key); tls->pool = NULL; return; } #endif ngx_pcre_pool = NULL; } ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc) { int n, erroff; char *p; const char *errstr; ngx_regex_t *re; ngx_regex_malloc_init(rc->pool); re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, &errstr, &erroff, NULL); /* ensure that there is no current pool */ ngx_regex_malloc_done(); if (re == NULL) { if ((size_t) erroff == rc->pattern.len) { rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, "pcre_compile() failed: %s in \"%V\"", errstr, &rc->pattern) - rc->err.data; } else { rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, "pcre_compile() failed: %s in \"%V\" at \"%s\"", errstr, &rc->pattern, rc->pattern.data + erroff) - rc->err.data; } return NGX_ERROR; } rc->regex = re; n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; goto failed; } if (rc->captures == 0) { return NGX_OK; } n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d"; goto failed; } if (rc->named_captures == 0) { return NGX_OK; } n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d"; goto failed; } n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d"; goto failed; } return NGX_OK; failed: rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) - rc->err.data; return NGX_OK; } ngx_int_t ngx_regex_capture_count(ngx_regex_t *re) { int rc, n; n = 0; rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n); if (rc < 0) { return (ngx_int_t) rc; } return (ngx_int_t) n; } ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log) { ngx_int_t n; ngx_uint_t i; ngx_regex_elt_t *re; re = a->elts; for (i = 0; i < a->nelts; i++) { n = ngx_regex_exec(re[i].regex, s, NULL, 0); if (n == NGX_REGEX_NO_MATCHED) { continue; } if (n < 0) { ngx_log_error(NGX_LOG_ALERT, log, 0, ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"", n, s, re[i].name); return NGX_ERROR; } /* match */ return NGX_OK; } return NGX_DECLINED; } static void * ngx_libc_cdecl ngx_regex_malloc(size_t size) { ngx_pool_t *pool; #if (NGX_THREADS) ngx_core_tls_t *tls; if (ngx_threaded) { tls = ngx_thread_get_tls(ngx_core_tls_key); pool = tls->pool; } else { pool = ngx_pcre_pool; } #else pool = ngx_pcre_pool; #endif if (pool) { return ngx_palloc(pool, size); } return NULL; } static void ngx_libc_cdecl ngx_regex_free(void *p) { return; }