aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_busy_lock.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-11-09 20:03:38 +0000
committerIgor Sysoev <igor@sysoev.ru>2003-11-09 20:03:38 +0000
commit74e95c224ad84c6b84b5a834f49c014a441916b5 (patch)
treefea6b4e7b2706f089e462d201e90ec95f5a98fa2 /src/http/ngx_http_busy_lock.c
parente8732b06b94ea5f8a25fa3e71cece7d93f5ac0b8 (diff)
downloadnginx-74e95c224ad84c6b84b5a834f49c014a441916b5.tar.gz
nginx-74e95c224ad84c6b84b5a834f49c014a441916b5.zip
nginx-0.0.1-2003-11-09-23:03:38 import; separate building
Diffstat (limited to 'src/http/ngx_http_busy_lock.c')
-rw-r--r--src/http/ngx_http_busy_lock.c223
1 files changed, 184 insertions, 39 deletions
diff --git a/src/http/ngx_http_busy_lock.c b/src/http/ngx_http_busy_lock.c
index 9431a3876..2ed66dc0b 100644
--- a/src/http/ngx_http_busy_lock.c
+++ b/src/http/ngx_http_busy_lock.c
@@ -4,42 +4,151 @@
#include <ngx_http.h>
-int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, u_char *md5)
+
+static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
+ ngx_http_busy_lock_ctx_t *bc,
+ int lock);
+
+
+int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
{
- int i, b, busy, free;
+ if (bl->busy < bl->max_busy) {
+ bl->busy++;
+
+ if (bc->time) {
+ bc->time = 0;
+ bl->waiting--;
+ }
+
+ return NGX_OK;
+ }
+
+ if (bc->time) {
+ if (bc->time < bl->timeout) {
+ ngx_add_timer(bc->event, 1000);
+ return NGX_AGAIN;
+ }
+
+ bl->waiting--;
+ return NGX_DONE;
+
+ }
+
+ if (bl->timeout == 0) {
+ return NGX_DONE;
+ }
+
+ if (bl->waiting < bl->max_waiting) {
+ bl->waiting++;
+ ngx_add_timer(bc->event, 1000);
+ bc->event->event_handler = bc->event_handler;
+
+ /* TODO: ngx_handle_level_read_event() */
+
+ return NGX_AGAIN;
+ }
+
+ return NGX_ERROR;
+}
+
+
+int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
+ ngx_http_busy_lock_ctx_t *bc, int lock)
+{
+ int rc;
+
+ rc = ngx_http_busy_lock_look_cachable(bl, bc, lock);
+
+ngx_log_debug(bc->event->log, "BUSYLOCK: %d" _ rc);
+
+ if (rc == NGX_OK) { /* no the same request, there's free slot */
+ return NGX_OK;
+ }
+
+ if (rc == NGX_ERROR && !lock) { /* no the same request, no free slot */
+ return NGX_OK;
+ }
+
+ /* rc == NGX_AGAIN: the same request */
+
+ if (bc->time) {
+ if (bc->time < bl->timeout) {
+ ngx_add_timer(bc->event, 1000);
+ return NGX_AGAIN;
+ }
+
+ bl->waiting--;
+ return NGX_DONE;
+
+ }
+
+ if (bl->timeout == 0) {
+ return NGX_DONE;
+ }
+
+ if (bl->waiting < bl->max_waiting) {
+ bl->waiting++;
+ ngx_add_timer(bc->event, 1000);
+ bc->event->event_handler = bc->event_handler;
+
+ /* TODO: ngx_handle_level_read_event() */
+
+ return NGX_AGAIN;
+ }
+
+ return NGX_ERROR;
+}
+
+
+void ngx_http_busy_unlock_cachable(ngx_http_busy_lock_t *bl,
+ ngx_http_busy_lock_ctx_t *bc)
+{
+ bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
+ bl->cachable--;
+ bl->busy--;
+}
+
+
+static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
+ ngx_http_busy_lock_ctx_t *bc,
+ int lock)
+{
+ int i, b, cachable, free;
u_int mask;
b = 0;
- busy = 0;
+ cachable = 0;
free = -1;
#if (NGX_SUPPRESS_WARN)
mask = 0;
#endif
- for (i = 0; i < bl->max_conn; i++) {
+ for (i = 0; i < bl->max_busy; i++) {
if ((b & 7) == 0) {
- mask = bl->busy_mask[i / 8];
+ mask = bl->md5_mask[i / 8];
}
if (mask & 1) {
- if (ngx_memcmp(&bl->busy[i * 16], md5, 16) == 0) {
+ if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
return NGX_AGAIN;
}
- busy++;
+ cachable++;
} else if (free == -1) {
free = i;
}
- if (busy == bl->busy_n) {
- if (busy < bl->max_conn) {
+#if 1
+ if (cachable == bl->cachable) {
+ if (free == -1 && cachable < bl->max_busy) {
free = i + 1;
}
break;
}
+#endif
mask >>= 1;
b++;
@@ -49,11 +158,18 @@ int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, u_char *md5)
return NGX_ERROR;
}
- ngx_memcpy(&bl->busy[free * 16], md5, 16);
- bl->busy_mask[free / 8] |= free % 8;
+ if (lock) {
+ if (bl->busy == bl->max_busy) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(&bl->md5[free * 16], bc->md5, 16);
+ bl->md5_mask[free / 8] |= 1 << (free & 7);
+ bc->slot = free;
- bl->busy_n++;
- bl->conn_n++;
+ bl->cachable++;
+ bl->busy++;
+ }
return NGX_OK;
}
@@ -64,8 +180,8 @@ char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
{
char *p = conf;
- int i;
- ngx_str_t *value;
+ int i, dup, invalid;
+ ngx_str_t *value, line;
ngx_http_busy_lock_t *bl, **blp;
blp = (ngx_http_busy_lock_t **) (p + cmd->offset);
@@ -79,57 +195,86 @@ char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
}
*blp = bl;
+ dup = 0;
+ invalid = 0;
value = (ngx_str_t *) cf->args->elts;
- for (i = 1; i < 4; i++) {
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (value[i].data[1] != '=') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid value \"%s\"", value[i].data);
+ return NGX_CONF_ERROR;
+ }
- if (value[i].len > 2 && ngx_strncasecmp(value[i].data, "c:", 2) == 0) {
- if (bl->max_conn) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
+ switch (value[i].data[0]) {
+
+ case 'b':
+ if (bl->max_busy) {
+ dup = 1;
+ break;
}
- bl->max_conn = ngx_atoi(value[i].data + 2, value[i].len - 2);
- if (bl->max_conn == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
+ bl->max_busy = ngx_atoi(value[i].data + 2, value[i].len - 2);
+ if (bl->max_busy == NGX_ERROR) {
+ invalid = 1;
+ break;
}
continue;
- }
- if (value[i].len > 2 && ngx_strncasecmp(value[i].data, "w:", 2) == 0) {
+ case 'w':
if (bl->max_waiting) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
+ dup = 1;
+ break;
}
bl->max_waiting = ngx_atoi(value[i].data + 2, value[i].len - 2);
if (bl->max_waiting == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
+ invalid = 1;
+ break;
+ }
+
+ continue;
+
+ case 't':
+ if (bl->timeout) {
+ dup = 1;
+ break;
+ }
+
+ line.len = value[i].len - 2;
+ line.data = value[i].data + 2;
+
+ bl->timeout = ngx_parse_time(&line, 1);
+ if (bl->timeout == NGX_ERROR) {
+ invalid = 1;
+ break;
}
continue;
+
+ default:
+ invalid = 1;
}
- if (bl->timeout) {
+ if (dup) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate timeout \"%s\"", value[i].data);
+ "duplicate value \"%s\"", value[i].data);
return NGX_CONF_ERROR;
}
- bl->timeout = ngx_parse_time(&value[1], 1);
- if (bl->timeout == NGX_ERROR) {
+ if (invalid) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid timeout \"%s\"", value[i].data);
+ "invalid value \"%s\"", value[i].data);
return NGX_CONF_ERROR;
}
}
+ if (bl->timeout == 0 && bl->max_waiting) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "busy lock waiting is useless with zero timeout");
+ }
+
return NGX_CONF_OK;
}