Mercurial > hg > nginx-quic
diff src/http/ngx_http_busy_lock.c @ 176:c0552e5ab567
nginx-0.0.1-2003-11-09-23:03:38 import; separate building
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 09 Nov 2003 20:03:38 +0000 |
parents | e92c2c647c57 |
children | a8ff48d26cca |
line wrap: on
line diff
--- 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) +{ + 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 i, b, busy, free; + 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_loc 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; + } - bl->busy_n++; - bl->conn_n++; + ngx_memcpy(&bl->md5[free * 16], bc->md5, 16); + bl->md5_mask[free / 8] |= 1 << (free & 7); + bc->slot = free; + + bl->cachable++; + bl->busy++; + } return NGX_OK; } @@ -64,8 +180,8 @@ char *ngx_http_set_busy_lock_slot(ngx_co { 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_co } *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].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; + if (value[i].data[1] != '=') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid value \"%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; }