3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
12 static ngx_int_t ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
13 ngx_event_busy_lock_ctx_t *ctx);
14 static void ngx_event_busy_lock_handler(ngx_event_t *ev);
15 static void ngx_event_busy_lock_posted_handler(ngx_event_t *ev);
19 * NGX_OK: the busy lock is held
20 * NGX_AGAIN: the all busy locks are held but we will wait the specified time
21 * NGX_BUSY: ctx->timer == 0: there are many the busy locks
22 * ctx->timer != 0: there are many the waiting locks
26 ngx_event_busy_lock(ngx_event_busy_lock_t *bl, ngx_event_busy_lock_ctx_t *ctx)
30 ngx_mutex_lock(bl->mutex);
32 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
33 "event busy lock: b:%d mb:%d",
34 bl->busy, bl->max_busy);
36 if (bl->busy < bl->max_busy) {
41 } else if (ctx->timer && bl->waiting < bl->max_waiting) {
43 ngx_add_timer(ctx->event, ctx->timer);
44 ctx->event->handler = ngx_event_busy_lock_handler;
61 ngx_mutex_unlock(bl->mutex);
68 ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
69 ngx_event_busy_lock_ctx_t *ctx)
73 ngx_mutex_lock(bl->mutex);
75 rc = ngx_event_busy_lock_look_cacheable(bl, ctx);
77 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
78 "event busy lock: %d w:%d mw:%d",
79 rc, bl->waiting, bl->max_waiting);
82 * NGX_OK: no the same request, there is free slot and we locked it
83 * NGX_BUSY: no the same request and there is no free slot
84 * NGX_AGAIN: the same request is processing
87 if (rc == NGX_AGAIN) {
89 if (ctx->timer && bl->waiting < bl->max_waiting) {
91 ngx_add_timer(ctx->event, ctx->timer);
92 ctx->event->handler = ngx_event_busy_lock_handler;
94 if (bl->events == NULL) {
106 ngx_mutex_unlock(bl->mutex);
113 ngx_event_busy_unlock(ngx_event_busy_lock_t *bl,
114 ngx_event_busy_lock_ctx_t *ctx)
117 ngx_event_busy_lock_ctx_t *wakeup;
119 ngx_mutex_lock(bl->mutex);
123 bl->events = bl->events->next;
131 * MP: all ctx's and their queue must be in shared memory,
132 * each ctx has pid to wake up
135 if (wakeup == NULL) {
136 ngx_mutex_unlock(bl->mutex);
141 for (wakeup = bl->events; wakeup; wakeup = wakeup->next) {
142 if (wakeup->md5 == NULL || wakeup->slot != ctx->slot) {
146 wakeup->handler = ngx_event_busy_lock_posted_handler;
147 wakeup->cache_updated = 1;
151 ngx_post_event(ev, &ngx_posted_events);
154 ngx_mutex_unlock(bl->mutex);
159 ngx_mutex_unlock(bl->mutex);
161 wakeup->handler = ngx_event_busy_lock_posted_handler;
170 ngx_post_event(ev, &ngx_posted_events);
176 ngx_event_busy_lock_cancel(ngx_event_busy_lock_t *bl,
177 ngx_event_busy_lock_ctx_t *ctx)
179 ngx_event_busy_lock_ctx_t *c, *p;
181 ngx_mutex_lock(bl->mutex);
185 if (ctx == bl->events) {
186 bl->events = ctx->next;
190 for (c = bl->events->next; c; c = c->next) {
199 ngx_mutex_unlock(bl->mutex);
204 ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
205 ngx_event_busy_lock_ctx_t *ctx)
208 ngx_uint_t i, bit, cacheable, mask;
214 #if (NGX_SUPPRESS_WARN)
218 for (i = 0; i < bl->max_busy; i++) {
220 if ((bit & 7) == 0) {
221 mask = bl->md5_mask[i / 8];
225 if (ngx_memcmp(&bl->md5[i * 16], ctx->md5, 16) == 0) {
232 } else if (free == -1) {
236 if (cacheable == bl->cacheable) {
237 if (free == -1 && cacheable < bl->max_busy) {
253 if (bl->busy == bl->max_busy) {
258 ngx_memcpy(&bl->md5[free * 16], ctx->md5, 16);
259 bl->md5_mask[free / 8] |= 1 << (free & 7);
270 ngx_event_busy_lock_handler(ngx_event_t *ev)
272 ev->handler = ngx_event_busy_lock_posted_handler;
274 ngx_post_event(ev, &ngx_posted_events);
279 ngx_event_busy_lock_posted_handler(ngx_event_t *ev)
281 ngx_event_busy_lock_ctx_t *ctx;