Mercurial > hg > nginx
view src/core/ngx_rwlock.c @ 6870:0a08a8babf53
Stream: fixed handling of non-ssl sessions.
A missing check could cause ngx_stream_ssl_handler() to be applied
to a non-ssl session, which resulted in a null pointer dereference
if ssl_verify_client is enabled.
The bug had appeared in 1.11.8 (41cb1b64561d).
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 19 Jan 2017 16:17:05 +0300 |
parents | e769cc88f996 |
children | 12efcdcb8a4b |
line wrap: on
line source
/* * Copyright (C) Ruslan Ermilov * Copyright (C) Nginx, Inc. */ #include <ngx_config.h> #include <ngx_core.h> #if (NGX_HAVE_ATOMIC_OPS) #define NGX_RWLOCK_SPIN 2048 #define NGX_RWLOCK_WLOCK ((ngx_atomic_uint_t) -1) void ngx_rwlock_wlock(ngx_atomic_t *lock) { ngx_uint_t i, n; for ( ;; ) { if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) { return; } if (ngx_ncpu > 1) { for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) { for (i = 0; i < n; i++) { ngx_cpu_pause(); } if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) { return; } } } ngx_sched_yield(); } } void ngx_rwlock_rlock(ngx_atomic_t *lock) { ngx_uint_t i, n; ngx_atomic_uint_t readers; for ( ;; ) { readers = *lock; if (readers != NGX_RWLOCK_WLOCK && ngx_atomic_cmp_set(lock, readers, readers + 1)) { return; } if (ngx_ncpu > 1) { for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) { for (i = 0; i < n; i++) { ngx_cpu_pause(); } readers = *lock; if (readers != NGX_RWLOCK_WLOCK && ngx_atomic_cmp_set(lock, readers, readers + 1)) { return; } } } ngx_sched_yield(); } } void ngx_rwlock_unlock(ngx_atomic_t *lock) { ngx_atomic_uint_t readers; readers = *lock; if (readers == NGX_RWLOCK_WLOCK) { *lock = 0; return; } for ( ;; ) { if (ngx_atomic_cmp_set(lock, readers, readers - 1)) { return; } readers = *lock; } } #else #if (NGX_HTTP_UPSTREAM_ZONE || NGX_STREAM_UPSTREAM_ZONE) #error ngx_atomic_cmp_set() is not defined! #endif #endif