Mercurial > hg > nginx
view src/core/ngx_rwlock.c @ 7808:eb54227110f0
Resolver: added missing event handling after reading.
If we need to be notified about further events, ngx_handle_read_event()
needs to be called after a read event is processed. Without this,
an event can be removed from the kernel and won't be reported again,
notably when using oneshot event methods, such as eventport on Solaris.
While here, error handling is also added, similar to one present in
ngx_resolver_tcp_read(). This is not expected to make a difference
and mostly added for consistency.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 28 Mar 2021 17:45:31 +0300 |
parents | d1816a2696de |
children | 7752d8523066 |
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) { (void) ngx_atomic_cmp_set(lock, NGX_RWLOCK_WLOCK, 0); return; } for ( ;; ) { if (ngx_atomic_cmp_set(lock, readers, readers - 1)) { return; } readers = *lock; } } void ngx_rwlock_downgrade(ngx_atomic_t *lock) { if (*lock == NGX_RWLOCK_WLOCK) { *lock = 1; } } #else #if (NGX_HTTP_UPSTREAM_ZONE || NGX_STREAM_UPSTREAM_ZONE) #error ngx_atomic_cmp_set() is not defined! #endif #endif