3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
10 #include <ngx_event.h>
13 static ngx_int_t
ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t
*bl
,
14 ngx_event_busy_lock_ctx_t
*ctx
);
15 static void ngx_event_busy_lock_handler(ngx_event_t
*ev
);
16 static void ngx_event_busy_lock_posted_handler(ngx_event_t
*ev
);
20 * NGX_OK: the busy lock is held
21 * NGX_AGAIN: the all busy locks are held but we will wait the specified time
22 * NGX_BUSY: ctx->timer == 0: there are many the busy locks
23 * ctx->timer != 0: there are many the waiting locks
27 ngx_event_busy_lock(ngx_event_busy_lock_t
*bl
, ngx_event_busy_lock_ctx_t
*ctx
)
31 ngx_mutex_lock(bl
->mutex
);
33 ngx_log_debug2(NGX_LOG_DEBUG_EVENT
, ctx
->event
->log
, 0,
34 "event busy lock: b:%d mb:%d",
35 bl
->busy
, bl
->max_busy
);
37 if (bl
->busy
< bl
->max_busy
) {
42 } else if (ctx
->timer
&& bl
->waiting
< bl
->max_waiting
) {
44 ngx_add_timer(ctx
->event
, ctx
->timer
);
45 ctx
->event
->handler
= ngx_event_busy_lock_handler
;
62 ngx_mutex_unlock(bl
->mutex
);
69 ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t
*bl
,
70 ngx_event_busy_lock_ctx_t
*ctx
)
74 ngx_mutex_lock(bl
->mutex
);
76 rc
= ngx_event_busy_lock_look_cacheable(bl
, ctx
);
78 ngx_log_debug3(NGX_LOG_DEBUG_EVENT
, ctx
->event
->log
, 0,
79 "event busy lock: %d w:%d mw:%d",
80 rc
, bl
->waiting
, bl
->max_waiting
);
83 * NGX_OK: no the same request, there is free slot and we locked it
84 * NGX_BUSY: no the same request and there is no free slot
85 * NGX_AGAIN: the same request is processing
88 if (rc
== NGX_AGAIN
) {
90 if (ctx
->timer
&& bl
->waiting
< bl
->max_waiting
) {
92 ngx_add_timer(ctx
->event
, ctx
->timer
);
93 ctx
->event
->handler
= ngx_event_busy_lock_handler
;
95 if (bl
->events
== NULL
) {
107 ngx_mutex_unlock(bl
->mutex
);
114 ngx_event_busy_unlock(ngx_event_busy_lock_t
*bl
,
115 ngx_event_busy_lock_ctx_t
*ctx
)
118 ngx_event_busy_lock_ctx_t
*wakeup
;
120 ngx_mutex_lock(bl
->mutex
);
124 bl
->events
= bl
->events
->next
;
132 * MP: all ctx's and their queue must be in shared memory,
133 * each ctx has pid to wake up
136 if (wakeup
== NULL
) {
137 ngx_mutex_unlock(bl
->mutex
);
142 for (wakeup
= bl
->events
; wakeup
; wakeup
= wakeup
->next
) {
143 if (wakeup
->md5
== NULL
|| wakeup
->slot
!= ctx
->slot
) {
147 wakeup
->handler
= ngx_event_busy_lock_posted_handler
;
148 wakeup
->cache_updated
= 1;
152 ngx_post_event(ev
, &ngx_posted_events
);
155 ngx_mutex_unlock(bl
->mutex
);
160 ngx_mutex_unlock(bl
->mutex
);
162 wakeup
->handler
= ngx_event_busy_lock_posted_handler
;
171 ngx_post_event(ev
, &ngx_posted_events
);
177 ngx_event_busy_lock_cancel(ngx_event_busy_lock_t
*bl
,
178 ngx_event_busy_lock_ctx_t
*ctx
)
180 ngx_event_busy_lock_ctx_t
*c
, *p
;
182 ngx_mutex_lock(bl
->mutex
);
186 if (ctx
== bl
->events
) {
187 bl
->events
= ctx
->next
;
191 for (c
= bl
->events
->next
; c
; c
= c
->next
) {
200 ngx_mutex_unlock(bl
->mutex
);
205 ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t
*bl
,
206 ngx_event_busy_lock_ctx_t
*ctx
)
209 ngx_uint_t i
, bit
, cacheable
, mask
;
215 #if (NGX_SUPPRESS_WARN)
219 for (i
= 0; i
< bl
->max_busy
; i
++) {
221 if ((bit
& 7) == 0) {
222 mask
= bl
->md5_mask
[i
/ 8];
226 if (ngx_memcmp(&bl
->md5
[i
* 16], ctx
->md5
, 16) == 0) {
233 } else if (free
== -1) {
237 if (cacheable
== bl
->cacheable
) {
238 if (free
== -1 && cacheable
< bl
->max_busy
) {
254 if (bl
->busy
== bl
->max_busy
) {
259 ngx_memcpy(&bl
->md5
[free
* 16], ctx
->md5
, 16);
260 bl
->md5_mask
[free
/ 8] |= 1 << (free
& 7);
271 ngx_event_busy_lock_handler(ngx_event_t
*ev
)
273 ev
->handler
= ngx_event_busy_lock_posted_handler
;
275 ngx_post_event(ev
, &ngx_posted_events
);
280 ngx_event_busy_lock_posted_handler(ngx_event_t
*ev
)
282 ngx_event_busy_lock_ctx_t
*ctx
;