diff options
author | Igor Sysoev <igor@sysoev.ru> | 2005-10-12 17:50:36 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2005-10-12 17:50:36 +0400 |
commit | 784522377ec160bc148ff3bb40fb87ede7506d5d (patch) | |
tree | 0c76a9c51a1c2ffa35ad3eb05e3b80f6cc19c60a /src | |
parent | bbfe3033bc82427b15ccf73767e786cbb12a7627 (diff) |
nginx-0.3.2-RELEASE importrelease-0.3.2
*) Feature: the Sun Studio 10 C compiler support.
*) Feature: the "proxy_upstream_max_fails",
"proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails", and
"fastcgi_upstream_fail_timeout" directives.
Diffstat (limited to 'src')
41 files changed, 914 insertions, 616 deletions
diff --git a/src/core/nginx.h b/src/core/nginx.h index 22c632ff3..67e8e6b02 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.1" +#define NGINX_VER "nginx/0.3.2" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c index 110c9e2b7..0e671ef3a 100644 --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -660,7 +660,7 @@ ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name) name->len = cycle->root.len + old.len; - if (cycle->connections0) { + if (cycle->connections) { name->data = ngx_palloc(cycle->pool, name->len + 1); if (name->data == NULL) { return NGX_ERROR; diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h index 4045e7a82..7c5687e1b 100644 --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -106,7 +106,7 @@ typedef long ngx_flag_t; /* TODO: auto_conf: ngx_inline inline __inline __inline__ */ #ifndef ngx_inline -#define ngx_inline __inline +#define ngx_inline inline #endif #define NGX_ACCEPT_THRESHOLD 100 diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index a7371bf89..3f36d3155 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -372,7 +372,9 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle) ngx_connection_t * ngx_get_connection(ngx_socket_t s, ngx_log_t *log) { - ngx_connection_t *c; + ngx_uint_t instance; + ngx_event_t *rev, *wev; + ngx_connection_t *c; /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ @@ -407,6 +409,32 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log) ngx_cycle->files[s] = c; } + rev = c->read; + wev = c->write; + + ngx_memzero(c, sizeof(ngx_connection_t)); + + c->read = rev; + c->write = wev; + c->fd = s; + c->log = log; + + instance = rev->instance; + + ngx_memzero(rev, sizeof(ngx_event_t)); + ngx_memzero(wev, sizeof(ngx_event_t)); + + rev->instance = !instance; + wev->instance = !instance; + + rev->index = NGX_INVALID_INDEX; + wev->index = NGX_INVALID_INDEX; + + rev->data = c; + wev->data = c; + + wev->write = 1; + return c; } diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index 839843f2b..d8f95fa4d 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -627,7 +627,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle) } } - if (old_cycle->connections0 == NULL) { + if (old_cycle->connections == NULL) { /* an old cycle is an init cycle */ ngx_destroy_pool(old_cycle->pool); return cycle; @@ -959,7 +959,7 @@ static void ngx_clean_old_cycles(ngx_event_t *ev) found = 0; for (n = 0; n < cycle[i]->connection_n; n++) { - if (cycle[i]->connections0[n].fd != (ngx_socket_t) -1) { + if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) { found = 1; ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%d", n); diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h index bf1d43092..a94444a91 100644 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -39,9 +39,9 @@ struct ngx_cycle_s { ngx_uint_t connection_n; ngx_uint_t files_n; - ngx_connection_t *connections0; - ngx_event_t *read_events0; - ngx_event_t *write_events0; + ngx_connection_t *connections; + ngx_event_t *read_events; + ngx_event_t *write_events; ngx_cycle_t *old_cycle; diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c index efabd39b8..76e71c748 100644 --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -36,7 +36,7 @@ ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain) ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, - int persistent) + ngx_uint_t persistent) { ngx_err_t err; ngx_atomic_uint_t n; diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h index 1efee294e..52c1ae22d 100644 --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -55,7 +55,7 @@ typedef struct { ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain); ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, - ngx_pool_t *pool, int persistent); + ngx_pool_t *pool, ngx_uint_t persistent); void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path); ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path); ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot); diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 376aaaefa..60a40eca4 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -343,10 +343,6 @@ ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) peers->peer[i].name.len = len + u->port_text.len; peers->peer[i].uri_separator = ""; - - peers->peer[i].weight = 1; - peers->peer[i].max_fails = 1; - peers->peer[i].fail_timeout = 10; } } else { diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c index 93449abcc..1164cc445 100644 --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -115,6 +115,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args) uint32_t ui32; int64_t i64; uint64_t ui64; + ngx_msec_t ms; ngx_str_t *s; ngx_uint_t width, sign, hexadecimal, max_width; static u_char hex[] = "0123456789abcdef"; @@ -221,8 +222,14 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args) break; case 'M': - ui64 = (uint64_t) va_arg(args, ngx_msec_t); - sign = 0; + ms = (ngx_msec_t) va_arg(args, ngx_msec_t); + if ((ngx_msec_int_t) ms == -1) { + sign = 1; + i64 = -1; + } else { + sign = 0; + ui64 = (uint64_t) ms; + } break; case 'z': diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index 99342ab1f..e80e1aba0 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -511,7 +511,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle) } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "kevent timer: %d, changes: %d", timer, n); + "kevent timer: %M, changes: %d", timer, n); events = kevent(ngx_kqueue, change_list, n, event_list, nevents, tp); diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index eaca46746..2e2a06518 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -40,7 +40,7 @@ ngx_uint_t ngx_event_flags; ngx_event_actions_t ngx_event_actions; -ngx_atomic_t connection_counter; +ngx_atomic_t connection_counter = 1; ngx_atomic_t *ngx_connection_counter = &connection_counter; @@ -49,6 +49,7 @@ ngx_atomic_t *ngx_accept_mutex; ngx_uint_t ngx_accept_mutex_held; ngx_msec_t ngx_accept_mutex_delay; ngx_int_t ngx_accept_disabled; +ngx_file_t ngx_accept_mutex_lock_file; #if (NGX_STAT_STUB) @@ -349,7 +350,7 @@ ngx_event_module_init(ngx_cycle_t *cycle) ecf = (*cf)[ngx_event_core_module.ctx_index]; - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, + ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "using the \"%s\" event method", ecf->name); #if !(NGX_WIN32) @@ -501,21 +502,21 @@ ngx_event_process_init(ngx_cycle_t *cycle) #endif - cycle->connections0 = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections, + cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections, cycle->log); - if (cycle->connections0 == NULL) { + if (cycle->connections == NULL) { return NGX_ERROR; } - c = cycle->connections0; + c = cycle->connections; - cycle->read_events0 = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, + cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->log); - if (cycle->read_events0 == NULL) { + if (cycle->read_events == NULL) { return NGX_ERROR; } - rev = cycle->read_events0; + rev = cycle->read_events; for (i = 0; i < cycle->connection_n; i++) { rev[i].closed = 1; rev[i].instance = 1; @@ -525,13 +526,13 @@ ngx_event_process_init(ngx_cycle_t *cycle) #endif } - cycle->write_events0 = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, + cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->log); - if (cycle->write_events0 == NULL) { + if (cycle->write_events == NULL) { return NGX_ERROR; } - wev = cycle->write_events0; + wev = cycle->write_events; for (i = 0; i < cycle->connection_n; i++) { wev[i].closed = 1; #if (NGX_THREADS) @@ -547,8 +548,8 @@ ngx_event_process_init(ngx_cycle_t *cycle) i--; c[i].data = next; - c[i].read = &cycle->read_events0[i]; - c[i].write = &cycle->write_events0[i]; + c[i].read = &cycle->read_events[i]; + c[i].write = &cycle->write_events[i]; c[i].fd = (ngx_socket_t) -1; next = &c[i]; @@ -572,14 +573,6 @@ ngx_event_process_init(ngx_cycle_t *cycle) return NGX_ERROR; } - rev = c->read; - wev = c->write; - - ngx_memzero(c, sizeof(ngx_connection_t)); - - c->read = rev; - c->write = wev; - c->fd = ls[i].fd; c->log = &ls[i].log; c->listening = &ls[i]; @@ -588,18 +581,9 @@ ngx_event_process_init(ngx_cycle_t *cycle) c->ctx = ls[i].ctx; c->servers = ls[i].servers; - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - - /* required by poll */ - wev->index = NGX_INVALID_INDEX; + rev = c->read; rev->log = c->log; - rev->data = c; - rev->index = NGX_INVALID_INDEX; - - rev->available = 0; - rev->accept = 1; #if (NGX_HAVE_DEFERRED_ACCEPT) diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 4df9dc611..238a49415 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -22,7 +22,6 @@ ngx_event_accept(ngx_event_t *ev) socklen_t sl; ngx_err_t err; ngx_log_t *log; - ngx_uint_t instance; ngx_socket_t s; ngx_event_t *rev, *wev; ngx_listening_t *ls; @@ -76,8 +75,8 @@ ngx_event_accept(ngx_event_t *ev) } #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_accepted); - ngx_atomic_inc(ngx_stat_active); + ngx_atomic_fetch_add(ngx_stat_accepted, 1); + ngx_atomic_fetch_add(ngx_stat_active, 1); #endif ngx_accept_disabled = NGX_ACCEPT_THRESHOLD @@ -94,16 +93,6 @@ ngx_event_accept(ngx_event_t *ev) return; } - rev = c->read; - wev = c->write; - - ngx_memzero(c, sizeof(ngx_connection_t)); - - c->read = rev; - c->write = wev; - c->fd = s; - c->log = ev->log; - c->pool = ngx_create_pool(ls->pool_size, ev->log); if (c->pool == NULL) { ngx_close_accepted_connection(c); @@ -164,21 +153,9 @@ ngx_event_accept(ngx_event_t *ev) c->ctx = lc->ctx; c->servers = lc->servers; - instance = rev->instance; - - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - - rev->instance = !instance; - wev->instance = !instance; - - rev->index = NGX_INVALID_INDEX; - wev->index = NGX_INVALID_INDEX; - - rev->data = c; - wev->data = c; + rev = c->read; + wev = c->write; - wev->write = 1; wev->ready = 1; if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT)) { @@ -197,18 +174,18 @@ ngx_event_accept(ngx_event_t *ev) wev->log = log; /* - * TODO: MT: - atomic increment (x86: lock xadd) + * TODO: MT: - ngx_atomic_fetch_add() * or protection by critical section or light mutex * * TODO: MP: - allocated in a shared memory - * - atomic increment (x86: lock xadd) + * - ngx_atomic_fetch_add() * or protection by critical section or light mutex */ - c->number = ngx_atomic_inc(ngx_connection_counter); + c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_handled); + ngx_atomic_fetch_add(ngx_stat_handled, 1); #endif #if (NGX_THREADS) @@ -391,7 +368,7 @@ ngx_close_accepted_connection(ngx_connection_t *c) } #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_active); + ngx_atomic_fetch_add(ngx_stat_active, -1); #endif } diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c index 961971424..f26984492 100644 --- a/src/event/ngx_event_acceptex.c +++ b/src/event/ngx_event_acceptex.c @@ -75,7 +75,7 @@ ngx_event_acceptex(ngx_event_t *rev) ngx_event_post_acceptex(c->listening, 1); - c->number = ngx_atomic_inc(ngx_connection_counter); + c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); c->listening->handler(c); @@ -117,16 +117,6 @@ ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n) return NGX_ERROR; } - rev = c->read; - wev = c->write; - - ngx_memzero(c, sizeof(ngx_connection_t)); - - c->read = rev; - c->write = wev; - c->fd = s; - c->log = &ls->log; - c->pool = ngx_create_pool(ls->pool_size, &ls->log); if (c->pool == NULL) { ngx_close_posted_connection(c); @@ -172,21 +162,14 @@ ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n) c->listening = ls; - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - - rev->data = c; - wev->data = c; - - rev->index = NGX_INVALID_INDEX; - wev->index = NGX_INVALID_INDEX; + rev = c->read; + wev = c->write; rev->ovlp.event = rev; wev->ovlp.event = wev; rev->handler = ngx_event_acceptex; rev->ready = 1; - wev->write = 1; wev->ready = 1; rev->log = c->log; diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index 804226f78..6182ef08b 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -14,7 +14,7 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { int rc; - ngx_uint_t instance, level, i; + ngx_uint_t level, i; u_int event; time_t now; ngx_err_t err; @@ -81,7 +81,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) for ( ;; ) { peer = &pc->peers->peer[pc->cur_peer]; - if (peer->fails <= peer->max_fails) { + if (peer->max_fails == 0 || peer->fails <= peer->max_fails) { break; } @@ -139,16 +139,6 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) return NGX_ERROR; } - rev = c->read; - wev = c->write; - - ngx_memzero(c, sizeof(ngx_connection_t)); - - c->read = rev; - c->write = wev; - c->fd = s; - c->log = pc->log; - if (pc->rcvbuf) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const void *) &pc->rcvbuf, sizeof(int)) == -1) { @@ -191,21 +181,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; } - instance = rev->instance; - - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - - rev->instance = !instance; - wev->instance = !instance; - - rev->index = NGX_INVALID_INDEX; - wev->index = NGX_INVALID_INDEX; - - rev->data = c; - wev->data = c; - - wev->write = 1; + rev = c->read; + wev = c->write; rev->log = pc->log; wev->log = pc->log; @@ -213,15 +190,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) pc->connection = c; /* - * TODO: MT: - atomic increment (x86: lock xadd) + * TODO: MT: - ngx_atomic_fetch_add() * or protection by critical section or mutex * * TODO: MP: - allocated in a shared memory - * - atomic increment (x86: lock xadd) + * - ngx_atomic_fetch_add() * or protection by critical section or mutex */ - c->number = ngx_atomic_inc(ngx_connection_counter); + c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); #if (NGX_THREADS) rev->lock = pc->lock; diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c index 656f62b15..174cc65b8 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -45,8 +45,8 @@ ngx_event_timer_init(ngx_log_t *log) ngx_msec_t ngx_event_find_timer(void) { - ngx_rbtree_key_int_t timer; - ngx_rbtree_node_t *node, *root, *sentinel; + ngx_msec_int_t timer; + ngx_rbtree_node_t *node, *root, *sentinel; if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) { return NGX_TIMER_INFINITE; @@ -63,8 +63,7 @@ ngx_event_find_timer(void) ngx_mutex_unlock(ngx_event_timer_mutex); - timer = (ngx_rbtree_key_int_t) node->key - - (ngx_rbtree_key_int_t) ngx_current_time; + timer = (ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_time; return (ngx_msec_t) (timer > 0 ? timer : 0); } @@ -94,9 +93,7 @@ ngx_event_expire_timers(void) /* node->key <= ngx_current_time */ - if ((ngx_rbtree_key_int_t) node->key - - (ngx_rbtree_key_int_t) ngx_current_time - <= 0) + if ((ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_time <= 0) { ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h index 13b5c0a39..f98023447 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -60,8 +60,8 @@ ngx_event_del_timer(ngx_event_t *ev) static ngx_inline void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer) { - ngx_rbtree_key_t key; - ngx_rbtree_key_int_t diff; + ngx_msec_t key; + ngx_msec_int_t diff; key = ngx_current_time + timer; @@ -73,7 +73,7 @@ ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer) * the rbtree operations for the fast connections. */ - diff = (ngx_rbtree_key_int_t) (key - ev->timer.key); + diff = (ngx_msec_int_t) (key - ev->timer.key); if (ngx_abs(diff) < NGX_TIMER_LAZY_DELAY) { ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0, diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index c5418070b..d58c7c664 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -151,10 +151,6 @@ static ngx_str_t ngx_http_fastcgi_script_name = static ngx_conf_post_t ngx_http_fastcgi_lowat_post = { ngx_http_fastcgi_lowat_check }; -static ngx_conf_enum_t ngx_http_fastcgi_set_methods[] = { - { ngx_string("get"), NGX_HTTP_GET }, - { ngx_null_string, 0 } -}; static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = { { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, @@ -210,13 +206,6 @@ static ngx_command_t ngx_http_fastcgi_commands[] = { offsetof(ngx_http_fastcgi_loc_conf_t, upstream.header_buffer_size), NULL }, - { ngx_string("fastcgi_method"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_fastcgi_loc_conf_t, upstream.method), - ngx_http_fastcgi_set_methods }, - { ngx_string("fastcgi_pass_request_headers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -294,6 +283,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = { offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream), &ngx_http_fastcgi_next_upstream_masks }, + { ngx_string("fastcgi_upstream_max_fails"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.max_fails), + NULL }, + + { ngx_string("fastcgi_upstream_fail_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_sec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.fail_timeout), + NULL }, + { ngx_string("fastcgi_param"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, ngx_conf_set_table_elt_slot, @@ -1443,7 +1446,9 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf) conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; - conf->upstream.method = NGX_CONF_UNSET_UINT; + conf->upstream.max_fails = NGX_CONF_UNSET_UINT; + conf->upstream.fail_timeout = NGX_CONF_UNSET; + conf->upstream.pass_request_headers = NGX_CONF_UNSET; conf->upstream.pass_request_body = NGX_CONF_UNSET; @@ -1591,15 +1596,25 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |NGX_HTTP_UPSTREAM_FT_ERROR |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); + ngx_conf_merge_unsigned_value(conf->upstream.max_fails, + prev->upstream.max_fails, 1); + + ngx_conf_merge_sec_value(conf->upstream.fail_timeout, + prev->upstream.fail_timeout, 10); + + if (conf->peers && conf->peers->number > 1) { + for (i = 0; i < conf->peers->number; i++) { + conf->peers->peer[i].weight = 1; + conf->peers->peer[i].max_fails = conf->upstream.max_fails; + conf->peers->peer[i].fail_timeout = conf->upstream.fail_timeout; + } + } + ngx_conf_merge_path_value(conf->upstream.temp_path, prev->upstream.temp_path, NGX_HTTP_FASTCGI_TEMP_PATH, 1, 2, 0, ngx_garbage_collector_temp_handler, cf); - if (conf->upstream.method == NGX_CONF_UNSET_UINT) { - conf->upstream.method = prev->upstream.method; - } - ngx_conf_merge_value(conf->upstream.pass_request_headers, prev->upstream.pass_request_headers, 1); ngx_conf_merge_value(conf->upstream.pass_request_body, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index e1ee7b4e9..8c4231a53 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -46,6 +46,7 @@ typedef struct { ngx_array_t *redirects; + ngx_str_t method; ngx_str_t host_header; ngx_str_t port_text; @@ -100,10 +101,6 @@ static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); static ngx_conf_post_t ngx_http_proxy_lowat_post = { ngx_http_proxy_lowat_check }; -static ngx_conf_enum_t ngx_http_proxy_set_methods[] = { - { ngx_string("get"), NGX_HTTP_GET }, - { ngx_null_string, 0 } -}; static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = { { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, @@ -168,10 +165,10 @@ static ngx_command_t ngx_http_proxy_commands[] = { { ngx_string("proxy_method"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, + ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, upstream.method), - ngx_http_proxy_set_methods }, + offsetof(ngx_http_proxy_loc_conf_t, method), + NULL }, { ngx_string("proxy_pass_request_headers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, @@ -243,6 +240,20 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream), &ngx_http_proxy_next_upstream_masks }, + { ngx_string("proxy_upstream_max_fails"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.max_fails), + NULL }, + + { ngx_string("proxy_upstream_fail_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_sec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.fail_timeout), + NULL }, + { ngx_string("proxy_pass_x_powered_by"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -299,13 +310,6 @@ ngx_module_t ngx_http_proxy_module = { }; -static ngx_str_t ngx_http_proxy_methods[] = { - ngx_string("GET "), - ngx_string("HEAD "), - ngx_string("POST ") -}; - - static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF; @@ -394,7 +398,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) ngx_uint_t i, key; uintptr_t escape; ngx_buf_t *b; - ngx_str_t *hh; + ngx_str_t *hh, method; ngx_chain_t *cl, *body; ngx_list_part_t *part; ngx_table_elt_t *header; @@ -410,12 +414,21 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) len = sizeof(ngx_http_proxy_version) - 1 + sizeof(CRLF) - 1; - if (u->method) { - len += ngx_http_proxy_methods[u->method - 1].len + u->conf->uri.len; + if (u->method.len) { + /* HEAD was changed to GET to cache response */ + method = u->method; + method.len++; + + } else if (plcf->method.len) { + method = plcf->method; + } else { - len += r->method_name.len + 1 + u->conf->uri.len; + method = r->method_name; + method.len++; } + len += method.len + u->conf->uri.len; + escape = 0; loc_len = r->valid_location ? u->conf->location->len : 0; @@ -493,14 +506,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) /* the request line */ - if (u->method) { - b->last = ngx_cpymem(b->last, - ngx_http_proxy_methods[u->method - 1].data, - ngx_http_proxy_methods[u->method - 1].len); - } else { - b->last = ngx_cpymem(b->last, r->method_name.data, - r->method_name.len + 1); - } + b->last = ngx_cpymem(b->last, method.data, method.len); u->uri.data = b->last; @@ -1288,6 +1294,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) * conf->upstream.uri = { 0, NULL }; * conf->upstream.location = NULL; * + * conf->method = NULL; * conf->headers_source = NULL; * conf->headers_set_len = NULL; * conf->headers_set = NULL; @@ -1306,10 +1313,12 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; - conf->upstream.method = NGX_CONF_UNSET_UINT; + conf->upstream.max_fails = NGX_CONF_UNSET_UINT; + conf->upstream.fail_timeout = NGX_CONF_UNSET; + conf->upstream.pass_request_headers = NGX_CONF_UNSET; conf->upstream.pass_request_body = NGX_CONF_UNSET; - + conf->upstream.redirect_errors = NGX_CONF_UNSET; /* "proxy_cyclic_temp_file" is disabled */ @@ -1440,10 +1449,10 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) && conf->upstream.max_temp_file_size < size) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"fastcgi_max_temp_file_size\" must be equal to zero to disable " + "\"proxy_max_temp_file_size\" must be equal to zero to disable " "the temporary files usage or must be equal or bigger than " - "maximum of the value of \"fastcgi_header_buffer_size\" and " - "one of the \"fastcgi_buffers\""); + "maximum of the value of \"proxy_header_buffer_size\" and " + "one of the \"proxy_buffers\""); return NGX_CONF_ERROR; } @@ -1455,13 +1464,31 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |NGX_HTTP_UPSTREAM_FT_ERROR |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); + ngx_conf_merge_unsigned_value(conf->upstream.max_fails, + prev->upstream.max_fails, 1); + + ngx_conf_merge_sec_value(conf->upstream.fail_timeout, + prev->upstream.fail_timeout, 10); + + if (conf->peers && conf->peers->number > 1) { + for (i = 0; i < conf->peers->number; i++) { + conf->peers->peer[i].weight = 1; + conf->peers->peer[i].max_fails = conf->upstream.max_fails; + conf->peers->peer[i].fail_timeout = conf->upstream.fail_timeout; + } + } + ngx_conf_merge_path_value(conf->upstream.temp_path, prev->upstream.temp_path, NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0, ngx_garbage_collector_temp_handler, cf); - if (conf->upstream.method == NGX_CONF_UNSET_UINT) { - conf->upstream.method = prev->upstream.method; + if (conf->method.len == 0) { + conf->method = prev->method; + + } else { + conf->method.data[conf->method.len] = ' '; + conf->method.len++; } ngx_conf_merge_value(conf->upstream.pass_request_headers, diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 54702cc90..dcb3956e1 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -721,10 +721,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } } -#if (NGX_DEBUG) +#if (NGX_DEBUG0) { u_char address[20]; - ngx_uint_t p, a, n; + ngx_uint_t p, a, nn; in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 19bc23980..2fb1764c8 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -174,13 +174,13 @@ ngx_http_init_connection(ngx_connection_t *c) ngx_mutex_unlock(ngx_posted_events_mutex); #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, 1); #endif return; } #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, 1); #endif ngx_http_init_request(rev); @@ -195,7 +195,7 @@ ngx_http_init_connection(ngx_connection_t *c) } #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, 1); #endif } @@ -226,7 +226,7 @@ void ngx_http_init_request(ngx_event_t *rev) ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); #endif ngx_http_close_connection(c); @@ -238,7 +238,7 @@ void ngx_http_init_request(ngx_event_t *rev) if (hc) { #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, 1); #endif } else { @@ -246,7 +246,7 @@ void ngx_http_init_request(ngx_event_t *rev) if (hc == NULL) { #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); #endif ngx_http_close_connection(c); @@ -270,7 +270,7 @@ void ngx_http_init_request(ngx_event_t *rev) if (r == NULL) { #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); #endif ngx_http_close_connection(c); @@ -281,7 +281,7 @@ void ngx_http_init_request(ngx_event_t *rev) } #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); #endif c->data = r; @@ -439,9 +439,9 @@ void ngx_http_init_request(ngx_event_t *rev) r->log_handler = ngx_http_log_error_handler; #if (NGX_STAT_STUB) - ngx_atomic_inc(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, 1); r->stat_reading = 1; - ngx_atomic_inc(ngx_stat_requests); + ngx_atomic_fetch_add(ngx_stat_requests, 1); #endif rev->handler(rev); @@ -669,9 +669,9 @@ ngx_http_process_request_line(ngx_event_t *rev) } #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); r->stat_reading = 0; - ngx_atomic_inc(ngx_stat_writing); + ngx_atomic_fetch_add(ngx_stat_writing, 1); r->stat_writing = 1; #endif @@ -899,9 +899,9 @@ ngx_http_process_request_headers(ngx_event_t *rev) } #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); r->stat_reading = 0; - ngx_atomic_inc(ngx_stat_writing); + ngx_atomic_fetch_add(ngx_stat_writing, 1); r->stat_writing = 1; #endif @@ -2396,11 +2396,11 @@ ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error) #if (NGX_STAT_STUB) if (r->stat_reading) { - ngx_atomic_dec(ngx_stat_reading); + ngx_atomic_fetch_add(ngx_stat_reading, -1); } if (r->stat_writing) { - ngx_atomic_dec(ngx_stat_writing); + ngx_atomic_fetch_add(ngx_stat_writing, -1); } #endif @@ -2457,7 +2457,7 @@ ngx_http_close_connection(ngx_connection_t *c) #endif #if (NGX_STAT_STUB) - ngx_atomic_dec(ngx_stat_active); + ngx_atomic_fetch_add(ngx_stat_active, -1); #endif pool = c->pool; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index dd32f639c..a1c6a2e98 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -251,13 +251,6 @@ ngx_http_upstream_init(ngx_http_request_t *r) u->request_bufs = r->request_body->bufs; } - if (u->conf->method == NGX_CONF_UNSET_UINT) { - u->method = r->method; - - } else { - u->method = u->conf->method; - } - if (u->create_request(r) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 6d96737e8..dd7b3c177 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -62,7 +62,9 @@ typedef struct { size_t temp_file_write_size_conf; ngx_uint_t next_upstream; - ngx_uint_t method; + ngx_uint_t max_fails; + + time_t fail_timeout; ngx_bufs_t bufs; @@ -156,7 +158,7 @@ struct ngx_http_upstream_s { ngx_msec_t timeout; - ngx_uint_t method; + ngx_str_t method; ngx_http_log_handler_pt saved_log_handler; diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 7b0d231b7..7e4a79f1b 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -33,6 +33,8 @@ static ngx_http_variable_value_t * static ngx_http_variable_value_t * ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data); static ngx_http_variable_value_t * + ngx_http_variable_request_method(ngx_http_request_t *r, uintptr_t data); +static ngx_http_variable_value_t * ngx_http_variable_remote_user(ngx_http_request_t *r, uintptr_t data); @@ -107,8 +109,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = { { ngx_string("server_name"), ngx_http_variable_request, offsetof(ngx_http_request_t, server_name), 0, 0 }, - { ngx_string("request_method"), ngx_http_variable_request, - offsetof(ngx_http_request_t, method_name), 0, 0 }, + { ngx_string("request_method"), ngx_http_variable_request_method, 0, 0, 0 }, { ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 }, @@ -641,6 +642,33 @@ ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data) static ngx_http_variable_value_t * +ngx_http_variable_request_method(ngx_http_request_t *r, uintptr_t data) +{ + ngx_http_variable_value_t *vv; + + if (r->method_name.data == NULL) { + return NGX_HTTP_VAR_NOT_FOUND; + } + + vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); + if (vv == NULL) { + return NULL; + } + + vv->value = 0; + + if (r->upstream && r->upstream->method.len) { + vv->text = r->upstream->method; + + } else { + vv->text = r->method_name; + } + + return vv; +} + + +static ngx_http_variable_value_t * ngx_http_variable_remote_user(ngx_http_request_t *r, uintptr_t data) { ngx_int_t rc; diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h index b3d300314..5856103c6 100644 --- a/src/os/unix/ngx_atomic.h +++ b/src/os/unix/ngx_atomic.h @@ -14,275 +14,99 @@ #if ( __i386__ || __i386 ) -#define NGX_HAVE_ATOMIC_OPS 1 - -typedef int32_t ngx_atomic_int_t; -typedef uint32_t ngx_atomic_uint_t; +typedef int32_t ngx_atomic_int_t; +typedef uint32_t ngx_atomic_uint_t; typedef volatile ngx_atomic_uint_t ngx_atomic_t; -#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 - - -#if (NGX_SMP) -#define NGX_SMP_LOCK "lock;" -#else -#define NGX_SMP_LOCK -#endif - -/* - * the "=q" is any of the %eax, %ebx, %ecx, or %edx registers. - * the '"0" (1)' parameter preloads 1 into %0. - * the "cc" means that flags were changed. - * - * "xadd r, [m]": - * - * temp = [m]; - * [m] += r; - * r = temp; - */ - -static ngx_inline ngx_atomic_uint_t -ngx_atomic_inc(ngx_atomic_t *value) -{ - ngx_atomic_uint_t old; - - __asm__ volatile ( - - NGX_SMP_LOCK - " xaddl %0, %2; " - " incl %0; " - - : "=q" (old) : "0" (1), "m" (*value) : "cc", "memory"); - - return old; -} - - -static ngx_inline ngx_atomic_uint_t -ngx_atomic_dec(ngx_atomic_t *value) -{ - ngx_atomic_uint_t old; - - __asm__ volatile ( - - NGX_SMP_LOCK - " xaddl %0, %2; " - " decl %0; " - - : "=q" (old) : "0" (-1), "m" (*value) : "cc", "memory"); +#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 - return old; -} +#if ( __SUNPRO_C ) -/* - * the "q" is any of the %eax, %ebx, %ecx, or %edx registers. - * the "=a" and "a" are the %eax register. Although we can return result - * in any register, we use %eax because it is used in cmpxchg anyway. - * - * "cmpxchg r, [m]": - * - * if (eax == [m]) { - * zf = 1; - * [m] = r; - * } else { - * zf = 0; - * eax = [m]; - * } - */ +#define NGX_HAVE_ATOMIC_OPS 1 -static ngx_inline ngx_atomic_uint_t +ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, - ngx_atomic_uint_t set) -{ - ngx_atomic_uint_t res; + ngx_atomic_uint_t set); - __asm__ volatile ( +ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add); - NGX_SMP_LOCK - " cmpxchgl %3, %1; " - " setz %b0; " - " movzbl %b0, %0; " +/* the code in src/os/unix/ngx_sunpro_x86.il */ - : "=a" (res) : "m" (*lock), "a" (old), "q" (set) : "cc", "memory"); - - return res; -} - -#elif ( __amd64__ || __amd64 ) +#else /* ( __GNUC__ || __INTEL_COMPILER ) */ #define NGX_HAVE_ATOMIC_OPS 1 -typedef int64_t ngx_atomic_int_t; -typedef uint64_t ngx_atomic_uint_t; -typedef volatile ngx_atomic_uint_t ngx_atomic_t; -#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 - +#include "ngx_gcc_atomic_x86.h" -#if (NGX_SMP) -#define NGX_SMP_LOCK "lock;" -#else -#define NGX_SMP_LOCK #endif -static ngx_inline ngx_atomic_uint_t -ngx_atomic_inc(ngx_atomic_t *value) -{ - ngx_atomic_uint_t old; - - __asm__ volatile ( - - NGX_SMP_LOCK - " xaddq %0, %2; " - " incq %0; " - - : "=r" (old) : "0" (1), "m" (*value) : "cc", "memory"); - - return old; -} - - -/* the '"0" (-1LL)' parameter preloads -1 into the 64-bit %0 register */ - -static ngx_inline ngx_atomic_uint_t -ngx_atomic_dec(ngx_atomic_t *value) -{ - ngx_atomic_uint_t old; - - __asm__ volatile ( - - NGX_SMP_LOCK - " xaddq %0, %2; " - " decq %0; " +#elif ( __amd64__ || __amd64 ) - : "=r" (old) : "0" (-1LL), "m" (*value) : "cc", "memory"); +typedef int64_t ngx_atomic_int_t; +typedef uint64_t ngx_atomic_uint_t; +typedef volatile ngx_atomic_uint_t ngx_atomic_t; +#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 - return old; -} +#if ( __SUNPRO_C ) -/* the "=a" and "a" are the %rax register. */ +#define NGX_HAVE_ATOMIC_OPS 1 -static ngx_inline ngx_atomic_uint_t +ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, - ngx_atomic_uint_t set) -{ - ngx_atomic_uint_t res; - - __asm__ volatile ( + ngx_atomic_uint_t set); - NGX_SMP_LOCK - " cmpxchgq %3, %1; " - " setz %b0; " - " movzbq %b0, %0; " +ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add); - : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory"); +/* the code in src/os/unix/ngx_sunpro_amd64.il */ - return res; -} - -#elif ( __sparc__ || __sparcv9 ) +#else /* ( __GNUC__ || __INTEL_COMPILER ) */ #define NGX_HAVE_ATOMIC_OPS 1 -#if (NGX_PTR_SIZE == 8) -typedef int64_t ngx_atomic_int_t; -typedef uint64_t ngx_atomic_uint_t; -#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 -#define NGX_CASXA "casxa" -#else -typedef int32_t ngx_atomic_int_t; -typedef uint32_t ngx_atomic_uint_t; -#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 -#define NGX_CASXA "casa" -#endif - -typedef volatile ngx_atomic_uint_t ngx_atomic_t; - - -/* - * the "+r" means the general register used for both input and output. - * - * "casa [r1] 0x80, r2, r0" and - * "casxa [r1] 0x80, r2, r0" do the following: - * - * if ([r1] == r2) { - * swap(r0, [r1]); - * } else { - * r0 = [r1]; - * } - * - * so "r0 == r2" means that the operation was successfull. - */ - -static ngx_inline ngx_atomic_uint_t -ngx_atomic_inc(ngx_atomic_t *value) -{ - ngx_atomic_uint_t old, new, res; - - old = *value; - - for ( ;; ) { +#include "ngx_gcc_atomic_amd64.h" - new = old + 1; - res = new; - - __asm__ volatile ( - - NGX_CASXA " [%1] 0x80, %2, %0" - - : "+r" (res) : "r" (value), "r" (old) : "memory"); +#endif - if (res == old) { - return new; - } - old = res; - } -} +#elif ( __sparc__ || __sparcv9 ) +#if (NGX_PTR_SIZE == 8) -static ngx_inline ngx_atomic_uint_t -ngx_atomic_dec(ngx_atomic_t *value) -{ - ngx_atomic_uint_t old, new, res; +typedef int64_t ngx_atomic_int_t; +typedef uint64_t ngx_atomic_uint_t; +#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 - old = *value; +#else - for ( ;; ) { +typedef int32_t ngx_atomic_int_t; +typedef uint32_t ngx_atomic_uint_t; +#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 - new = old - 1; - res = new; +#endif - __asm__ volatile ( +typedef volatile ngx_atomic_uint_t ngx_atomic_t; - NGX_CASXA " [%1] 0x80, %2, %0" - : "+r" (res) : "r" (value), "r" (old) : "memory"); +#if ( __SUNPRO_C ) - if (res == old) { - return new; - } +#define NGX_HAVE_ATOMIC_OPS 1 - old = res; - } -} +#include "ngx_sunpro_atomic_sparc64.h" -static ngx_inline ngx_atomic_uint_t -ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, - ngx_atomic_uint_t set) -{ - __asm__ volatile ( +#else /* ( __GNUC__ || __INTEL_COMPILER ) */ - NGX_CASXA " [%1] 0x80, %2, %0" +#define NGX_HAVE_ATOMIC_OPS 1 - : "+r" (set) : "r" (lock), "r" (old) : "memory"); +#include "ngx_gcc_atomic_sparc64.h" - return (set == old); -} +#endif #elif ( __ppc__ || __powerpc__ ) @@ -290,116 +114,60 @@ ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, #define NGX_HAVE_ATOMIC_OPS 1 #if (NGX_PTR_SIZE == 8) -typedef int64_t ngx_atomic_int_t; -typedef uint64_t ngx_atomic_uint_t; -#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 -#else -typedef int32_t ngx_atomic_int_t; -typedef uint32_t ngx_atomic_uint_t; -#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 -#endif - -typedef volatile ngx_atomic_uint_t ngx_atomic_t; +typedef int64_t ngx_atomic_int_t; +typedef uint64_t ngx_atomic_uint_t; +#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1 -/* - * the ppc assembler treats ";" as comment, so we have to use "\n". - * the minus in "bne-" is a hint for the branch prediction unit that - * this branch is unlikely to be taken. - * - * the "=&r" means that no input registers can be used. - * the "=&b" means that the base registers can be used only, i.e. - * any register except r0. the r0 register always has a zero value and - * could not be used in "addi r0, r0, 1". - * the "1b" means the nearest backward label "1" and the "1f" means - * the nearest forward label "1". - */ +#else -static ngx_inline ngx_atomic_uint_t -ngx_atomic_inc(ngx_atomic_t *value) -{ - ngx_atomic_uint_t res; +typedef int32_t ngx_atomic_int_t; +typedef uint32_t ngx_atomic_uint_t; +#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 - __asm__ volatile ( +#endif - "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ - /* and store reservation */ - " addi %0, %0, 1 \n" /* add "1" to "res" */ - " stwcx. %0, 0, %1 \n" /* store "res" into [value] if reservation */ - /* is not cleared */ - " bne- 1b \n" /* try again if reservation was cleared */ +typedef volatile ngx_atomic_uint_t ngx_atomic_t; - : "=&b" (res) : "r" (value) : "cc", "memory"); - return res; -} +#include "ngx_gcc_atomic_ppc.h" -static ngx_inline ngx_atomic_uint_t -ngx_atomic_dec(ngx_atomic_t *value) -{ - ngx_atomic_uint_t res; +#endif - __asm__ volatile ( - "1: lwarx %0, 0, %1 \n" /* load from [value] into "res" */ - /* and store reservation */ - " addi %0, %0, -1 \n" /* sub "1" from "res" */ - " stwcx. %0, 0, %1 \n" /* store "res" into [value] if reservation */ - /* is not cleared */ - " bne- 1b \n" /* try again if reservation was cleared */ +#if !(NGX_HAVE_ATOMIC_OPS) - : "=&b" (res) : "r" (value) : "cc", "memory"); +#define NGX_HAVE_ATOMIC_OPS 0 - return res; -} +typedef int32_t ngx_atomic_int_t; +typedef uint32_t ngx_atomic_uint_t; +typedef volatile ngx_atomic_uint_t ngx_atomic_t; +#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 static ngx_inline ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, - ngx_atomic_uint_t set) + ngx_atomic_uint_t set) { - ngx_atomic_uint_t res, temp; - - __asm__ volatile ( - - " li %0, 0 \n" /* preset "0" to "res" */ - " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ - /* and store reservation */ - " cmpw %1, %3 \n" /* compare "temp" and "old" */ - " bne- 1f \n" /* not equal */ - " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ - /* is not cleared */ - " bne- 1f \n" /* the reservation was cleared */ - " li %0, 1 \n" /* set "1" to "res" */ - "1: \n" - - : "=&r" (res), "=&r" (temp) - : "r" (lock), "r" (old), "r" (set) - : "cc", "memory"); - - return res; -} + if (*lock == old { + *lock = set; + return 1; + } + return 0; +} -#else -#define NGX_HAVE_ATOMIC_OPS 0 - -typedef int32_t ngx_atomic_int_t; -typedef uint32_t ngx_atomic_uint_t; -typedef volatile ngx_atomic_uint_t ngx_atomic_t; -#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_int_t old; -#define ngx_atomic_inc(x) ++(*(x)) -#define ngx_atomic_dec(x) --(*(x)) + old = *value; + *value += add; -static ngx_inline ngx_atomic_uint_t -ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, - ngx_atomic_uint_t set) -{ - *lock = set; - return 1; + return old; } #endif diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c index 01a0514b5..051f466fd 100644 --- a/src/os/unix/ngx_channel.c +++ b/src/os/unix/ngx_channel.c @@ -192,30 +192,14 @@ ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event, return NGX_ERROR; } - rev = c->read; - wev = c->write; - - ngx_memzero(c, sizeof(ngx_connection_t)); - - c->read = rev; - c->write = wev; - c->fd = fd; - c->log = cycle->log; - c->pool = cycle->pool; - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); + rev = c->read; + wev = c->write; rev->log = cycle->log; wev->log = cycle->log; - rev->index = NGX_INVALID_INDEX; - wev->index = NGX_INVALID_INDEX; - - rev->data = c; - wev->data = c; - #if (NGX_THREADS) rev->lock = &c->lock; wev->lock = &c->lock; diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c index f8f98c7fe..67cad1a69 100644 --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -8,9 +8,10 @@ #include <ngx_core.h> -ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) +ssize_t +ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { - ssize_t n; + ssize_t n; ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, "read: %d, %p, %uz, %O", file->fd, buf, size, offset); @@ -53,9 +54,10 @@ ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) } -ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) +ssize_t +ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { - ssize_t n; + ssize_t n; ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, "write: %d, %p, %uz, %O", file->fd, buf, size, offset); @@ -109,7 +111,8 @@ ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) } -ngx_fd_t ngx_open_tempfile(u_char *name, ngx_uint_t persistent) +ngx_fd_t +ngx_open_tempfile(u_char *name, ngx_uint_t persistent) { ngx_fd_t fd; @@ -125,8 +128,9 @@ ngx_fd_t ngx_open_tempfile(u_char *name, ngx_uint_t persistent) #define NGX_IOVS 8 -ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, - off_t offset, ngx_pool_t *pool) +ssize_t +ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset, + ngx_pool_t *pool) { u_char *prev; size_t size; @@ -216,7 +220,8 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, } -ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) +ngx_int_t +ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) { dir->dir = opendir((const char *) name->data); @@ -228,3 +233,61 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) return NGX_OK; } + + +ngx_int_t +ngx_lock_file(ngx_file_t *file) +{ + ngx_err_t err; + struct flock fl; + + fl.l_whence = SEEK_SET; + fl.l_len = 0; + fl.l_pid = 0; + fl.l_type = F_WRLCK; + fl.l_start = 0; + + if (fcntl(file->fd, F_SETLK, &fl) == -1) { + err = ngx_errno; + + if (err == NGX_EAGAIN) { + return NGX_BUSY; + } + + ngx_log_error(NGX_LOG_ALERT, file->log, err, + "fcntl(%s, F_SETLK, F_WRLCK) failed", file->name.data); + + return NGX_ERROR; + } + + return NGX_OK; +} + + +ngx_int_t +ngx_unlock_file(ngx_file_t *file) +{ + ngx_err_t err; + struct flock fl; + + fl.l_whence = SEEK_SET; + fl.l_len = 0; + fl.l_pid = 0; + fl.l_type = F_UNLCK; + fl.l_start = 0; + + if (fcntl(file->fd, F_SETLK, &fl) == -1) { + err = ngx_errno; + + if (err == NGX_EAGAIN) { + return NGX_BUSY; + } + + ngx_log_error(NGX_LOG_ALERT, file->log, err, + "fcntl(%s, F_SETLK, F_UNLCK) failed", file->name.data); + + return NGX_ERROR; + } + + return NGX_OK; +} diff --git a/src/os/unix/ngx_gcc_atomic_amd64.h b/src/os/unix/ngx_gcc_atomic_amd64.h new file mode 100644 index 000000000..07b2d50b5 --- /dev/null +++ b/src/os/unix/ngx_gcc_atomic_amd64.h @@ -0,0 +1,74 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#if (NGX_SMP) +#define NGX_SMP_LOCK "lock;" +#else +#define NGX_SMP_LOCK +#endif + + +/* + * "cmpxchgq r, [m]": + * + * if (rax == [m]) { + * zf = 1; + * [m] = r; + * } else { + * zf = 0; + * rax = [m]; + * } + * + * + * The "r" is any register, %rax (%r0) - %r16. + * The "=a" and "a" are the %rax register. Although we can return result + * in any register, we use %rax because it is used in cmpxchgq anyway. + * The "cc" means that flags were changed. + */ + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + ngx_atomic_uint_t res; + + __asm__ volatile ( + + NGX_SMP_LOCK + " cmpxchgq %3, %1; " + " setz %b0; " + " movzbq %b0, %0; " + + : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory"); + + return res; +} + + +/* + * "xaddq r, [m]": + * + * temp = [m]; + * [m] += r; + * r = temp; + * + * + * The "+r" is any register, %rax (%r0) - %r16. + * The "cc" means that flags were changed. + */ + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + __asm__ volatile ( + + NGX_SMP_LOCK + " xaddq %0, %1; " + + : "+q" (add) : "m" (*value) : "cc", "memory"); + + return add; +} diff --git a/src/os/unix/ngx_gcc_atomic_ppc.h b/src/os/unix/ngx_gcc_atomic_ppc.h new file mode 100644 index 000000000..8fc3bc041 --- /dev/null +++ b/src/os/unix/ngx_gcc_atomic_ppc.h @@ -0,0 +1,66 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +/* + * The ppc assembler treats ";" as comment, so we have to use "\n". + * The minus in "bne-" is a hint for the branch prediction unit that + * this branch is unlikely to be taken. + * The "1b" means the nearest backward label "1" and the "1f" means + * the nearest forward label "1". + * + * The "b" means that the base registers can be used only, i.e. + * any register except r0. The r0 register always has a zero value and + * could not be used in "addi r0, r0, 1". + * The "=&b" means that no input registers can be used. + */ + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + ngx_atomic_uint_t res, temp; + + __asm__ volatile ( + + " li %0, 0 \n" /* preset "0" to "res" */ + " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ + /* and store reservation */ + " cmpw %1, %3 \n" /* compare "temp" and "old" */ + " bne- 1f \n" /* not equal */ + " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ + /* is not cleared */ + " bne- 1f \n" /* the reservation was cleared */ + " li %0, 1 \n" /* set "1" to "res" */ + "1: \n" + + : "=&b" (res), "=&b" (temp) + : "b" (lock), "b" (old), "b" (set) + : "cc", "memory"); + + return res; +} + + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_uint_t res, temp; + + __asm__ volatile ( + + "1: lwarx %0, 0, %2 \n" /* load from [value] into "res" */ + /* and store reservation */ + " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */ + " stwcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ + /* is not cleared */ + " bne- 1b \n" /* try again if reservation was cleared */ + + : "=&b" (res), "=&b" (temp) + : "b" (value), "b" (add) + : "cc", "memory"); + + return res; +} diff --git a/src/os/unix/ngx_gcc_atomic_sparc64.h b/src/os/unix/ngx_gcc_atomic_sparc64.h new file mode 100644 index 000000000..c7022a930 --- /dev/null +++ b/src/os/unix/ngx_gcc_atomic_sparc64.h @@ -0,0 +1,69 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +/* + * "casa [r1] 0x80, r2, r0" and + * "casxa [r1] 0x80, r2, r0" do the following: + * + * if ([r1] == r2) { + * swap(r0, [r1]); + * } else { + * r0 = [r1]; + * } + * + * so "r0 == r2" means that the operation was successfull. + * + * + * The "r" means the general register. + * The "+r" means the general register used for both input and output. + */ + + +#if (NGX_PTR_SIZE == 4) +#define NGX_CASA "casa" +#else +#define NGX_CASA "casxa" +#endif + + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + __asm__ volatile ( + + NGX_CASA " [%1] 0x80, %2, %0" + + : "+r" (set) : "r" (lock), "r" (old) : "memory"); + + return (set == old); +} + + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_uint_t old, res; + + old = *value; + + for ( ;; ) { + + res = old + add; + + __asm__ volatile ( + + NGX_CASA " [%1] 0x80, %2, %0" + + : "+r" (res) : "r" (value), "r" (old) : "memory"); + + if (res == old) { + return res; + } + + old = res; + } +} diff --git a/src/os/unix/ngx_gcc_atomic_x86.h b/src/os/unix/ngx_gcc_atomic_x86.h new file mode 100644 index 000000000..e3c0c9379 --- /dev/null +++ b/src/os/unix/ngx_gcc_atomic_x86.h @@ -0,0 +1,103 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#if (NGX_SMP) +#define NGX_SMP_LOCK "lock;" +#else +#define NGX_SMP_LOCK +#endif + + +/* + * "cmpxchgl r, [m]": + * + * if (eax == [m]) { + * zf = 1; + * [m] = r; + * } else { + * zf = 0; + * eax = [m]; + * } + * + * + * The "q" is any of the %eax, %ebx, %ecx, or %edx registers. + * The "=a" and "a" are the %eax register. Although we can return result + * in any register, we use %eax because it is used in cmpxchgl anyway. + * The "cc" means that flags were changed. + */ + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + ngx_atomic_uint_t res; + + __asm__ volatile ( + + NGX_SMP_LOCK + " cmpxchgl %3, %1; " + " setz %b0; " + " movzbl %b0, %0; " + + : "=a" (res) : "m" (*lock), "a" (old), "q" (set) : "cc", "memory"); + + return res; +} + + +/* + * "xaddl r, [m]": + * + * temp = [m]; + * [m] += r; + * r = temp; + * + * + * The "+q" is any of the %eax, %ebx, %ecx, or %edx registers. + * The "cc" means that flags were changed. + */ + + +#if !(__GNUC__ == 2 && __GNUC_MINOR__ <= 7) + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + __asm__ volatile ( + + NGX_SMP_LOCK + " xaddl %0, %1; " + + : "+q" (add) : "m" (*value) : "cc", "memory"); + + return add; +} + + +#else /* (__GNUC__ == 2 && __GNUC_MINOR__ <= 7) */ + +/* + * gcc 2.7 does not support "+q", so we have to use the fixed %eax ("=a" and + * "a") and this adds two superfluous instructions in the end of code, + * something like this: "mov %eax, %edx / mov %edx, %eax". + */ + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_uint_t old; + + __asm__ volatile ( + + NGX_SMP_LOCK + " xaddl %2, %1; " + + : "=a" (old) : "m" (*value), "a" (add) : "cc", "memory"); + + return old; +} + +#endif diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c index 47d8f3b7c..08b5cc033 100644 --- a/src/os/unix/ngx_readv_chain.c +++ b/src/os/unix/ngx_readv_chain.c @@ -182,7 +182,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain) return NGX_ERROR; } - iov->iov_base = chain->buf->last; + iov->iov_base = (void *) chain->buf->last; iov->iov_len = chain->buf->end - chain->buf->last; } diff --git a/src/os/unix/ngx_sunpro_amd64.il b/src/os/unix/ngx_sunpro_amd64.il new file mode 100644 index 000000000..0cd94b023 --- /dev/null +++ b/src/os/unix/ngx_sunpro_amd64.il @@ -0,0 +1,30 @@ +/ +/ Copyright (C) Igor Sysoev +/ + +/ ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, +/ ngx_atomic_uint_t old, ngx_atomic_uint_t set); +/ +/ the arguments are passed in %rdi, %rsi, %rdx +/ the result is returned in the %rax + + .inline ngx_atomic_cmp_set,0 + movq %rsi, %rax + lock + cmpxchgq %rdx, (%rdi) + setz %al + movzbq %al, %rax + .end + + +/ ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value, +/ ngx_atomic_int_t add); +/ +/ the arguments are passed in %rdi, %rsi +/ the result is returned in the %rax + + .inline ngx_atomic_fetch_add,0 + movq %rsi, %rax + lock + xaddq %rax, (%rdi) + .end diff --git a/src/os/unix/ngx_sunpro_atomic_sparc64.h b/src/os/unix/ngx_sunpro_atomic_sparc64.h new file mode 100644 index 000000000..e634416ab --- /dev/null +++ b/src/os/unix/ngx_sunpro_atomic_sparc64.h @@ -0,0 +1,52 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#if (NGX_PTR_SIZE == 4) +#define NGX_CASA ngx_casa +#else +#define NGX_CASA ngx_casxa +#endif + + +ngx_atomic_uint_t +ngx_casa(ngx_atomic_uint_t set, ngx_atomic_uint_t old, ngx_atomic_t *lock); + +ngx_atomic_uint_t +ngx_casxa(ngx_atomic_uint_t set, ngx_atomic_uint_t old, ngx_atomic_t *lock); + +/* the code in src/os/unix/ngx_sunpro_sparc64.il */ + + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + NGX_CASA(set, old, lock); + + return (set == old); +} + + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_uint_t old, res; + + old = *value; + + for ( ;; ) { + + res = old + add; + + NGX_CASA(res, old, value); + + if (res == old) { + return res; + } + + old = res; + } +} diff --git a/src/os/unix/ngx_sunpro_sparc64.il b/src/os/unix/ngx_sunpro_sparc64.il new file mode 100644 index 000000000..d2708ed9d --- /dev/null +++ b/src/os/unix/ngx_sunpro_sparc64.il @@ -0,0 +1,35 @@ +/ +/ Copyright (C) Igor Sysoev +/ + + +/ "casa [%o2] 0x80, %o1, %o0" and +/ "casxa [%o2] 0x80, %o1, %o0" do the following: +/ +/ if ([%o2] == %o1) { +/ swap(%o0, [%o2]); +/ } else { +/ %o0 = [%o2]; +/ } + + +/ ngx_atomic_uint_t ngx_casa(ngx_atomic_uint_t set, ngx_atomic_uint_t old, +/ ngx_atomic_t *lock); +/ +/ the arguments are passed in the %o0, %o1, %o2 +/ the result is returned in the %o0 + + .inline ngx_casa,0 + casa [%o2] 0x80, %o1, %o0 + .end + + +/ ngx_atomic_uint_t ngx_casxa(ngx_atomic_uint_t set, ngx_atomic_uint_t old, +/ ngx_atomic_t *lock); +/ +/ the arguments are passed in the %o0, %o1, %o2 +/ the result is returned in the %o0 + + .inline ngx_casxa,0 + casxa [%o2] 0x80, %o1, %o0 + .end diff --git a/src/os/unix/ngx_sunpro_x86.il b/src/os/unix/ngx_sunpro_x86.il new file mode 100644 index 000000000..a16568ac8 --- /dev/null +++ b/src/os/unix/ngx_sunpro_x86.il @@ -0,0 +1,31 @@ +/ +/ Copyright (C) Igor Sysoev +/ + +/ ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, +/ ngx_atomic_uint_t old, ngx_atomic_uint_t set); +/ +/ the arguments are passed on the stack (%esp), 4(%esp), 8(%esp) + + .inline ngx_atomic_cmp_set,0 + movl (%esp), %ecx + movl 4(%esp), %eax + movl 8(%esp), %edx + lock + cmpxchgl %edx, (%ecx) + setz %al + movzbl %al, %eax + .end + + +/ ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value, +/ ngx_atomic_int_t add); +/ +/ the arguments are passed on the stack (%esp), 4(%esp) + + .inline ngx_atomic_fetch_add,0 + movl (%esp), %ecx + movl 4(%esp), %eax + lock + xaddl %eax, (%ecx) + .end diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h index 63a0ad9f7..f9fe3c52f 100644 --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -12,31 +12,32 @@ #include <ngx_core.h> -typedef ngx_rbtree_key_t ngx_msec_t; +typedef ngx_rbtree_key_t ngx_msec_t; +typedef ngx_rbtree_key_int_t ngx_msec_int_t; -typedef struct tm ngx_tm_t; +typedef struct tm ngx_tm_t; -#define ngx_tm_sec tm_sec -#define ngx_tm_min tm_min -#define ngx_tm_hour tm_hour -#define ngx_tm_mday tm_mday -#define ngx_tm_mon tm_mon -#define ngx_tm_year tm_year -#define ngx_tm_wday tm_wday -#define ngx_tm_isdst tm_isdst +#define ngx_tm_sec tm_sec +#define ngx_tm_min tm_min +#define ngx_tm_hour tm_hour +#define ngx_tm_mday tm_mday +#define ngx_tm_mon tm_mon +#define ngx_tm_year tm_year +#define ngx_tm_wday tm_wday +#define ngx_tm_isdst tm_isdst -#define ngx_tm_sec_t int -#define ngx_tm_min_t int -#define ngx_tm_hour_t int -#define ngx_tm_mday_t int -#define ngx_tm_mon_t int -#define ngx_tm_year_t int -#define ngx_tm_wday_t int +#define ngx_tm_sec_t int +#define ngx_tm_min_t int +#define ngx_tm_hour_t int +#define ngx_tm_mday_t int +#define ngx_tm_mon_t int +#define ngx_tm_year_t int +#define ngx_tm_wday_t int #if (NGX_HAVE_GMTOFF) -#define ngx_tm_gmtoff tm_gmtoff -#define ngx_tm_zone tm_zone +#define ngx_tm_gmtoff tm_gmtoff +#define ngx_tm_zone tm_zone #endif diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c index 9baeb1f3c..f95c2cad8 100644 --- a/src/os/unix/ngx_writev_chain.c +++ b/src/os/unix/ngx_writev_chain.c @@ -81,7 +81,7 @@ ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) size = cl->buf->last - cl->buf->pos; if (send + size > limit) { - size = (ssize_t) limit - send; + size = (ssize_t) (limit - send); } if (prev == cl->buf->pos) { diff --git a/src/os/win32/ngx_atomic.h b/src/os/win32/ngx_atomic.h index 01ef98e97..87de57dd1 100644 --- a/src/os/win32/ngx_atomic.h +++ b/src/os/win32/ngx_atomic.h @@ -14,14 +14,10 @@ #define NGX_HAVE_ATOMIC_OPS 1 -typedef int32_t ngx_atomic_int_t; -typedef uint32_t ngx_atomic_uint_t; +typedef int32_t ngx_atomic_int_t; +typedef uint32_t ngx_atomic_uint_t; typedef volatile ngx_atomic_uint_t ngx_atomic_t; -#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 - - -#define ngx_atomic_inc(p) InterlockedIncrement((long *) p) -#define ngx_atomic_dec(p) InterlockedDecrement((long *) p) +#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1 #if defined( __WATCOMC__ ) || defined( __BORLANDC__ ) || ( _MSC_VER >= 1300 ) @@ -42,6 +38,9 @@ typedef volatile ngx_atomic_uint_t ngx_atomic_t; #endif +#define ngx_atomic_fetch_add(p, add) InterlockedExchangeAdd((long *) p, add) + + void ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin); #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c index bea580b24..78b7f957d 100644 --- a/src/os/win32/ngx_files.c +++ b/src/os/win32/ngx_files.c @@ -8,7 +8,8 @@ #include <ngx_core.h> -ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) +ssize_t +ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { long high_offset; u_long n; @@ -72,7 +73,8 @@ ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) } -ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) +ssize_t +ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { long high_offset; u_long n; @@ -135,8 +137,9 @@ ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) } -ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, - off_t offset, ngx_pool_t *pool) +ssize_t +ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset, + ngx_pool_t *pool) { u_char *buf, *prev; size_t size; @@ -171,8 +174,8 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, } -ngx_int_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, - ngx_pool_t *pool) +ngx_int_t +ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool) { u_char *name; ngx_int_t rc; @@ -233,7 +236,8 @@ ngx_int_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, #if 0 -ngx_int_t ngx_file_info(char *file, ngx_file_info_t *sb) +ngx_int_t +ngx_file_info(char *file, ngx_file_info_t *sb) { WIN32_FILE_ATTRIBUTE_DATA fa; @@ -256,7 +260,8 @@ ngx_int_t ngx_file_info(char *file, ngx_file_info_t *sb) #endif -ngx_int_t ngx_file_info(u_char *file, ngx_file_info_t *sb) +ngx_int_t +ngx_file_info(u_char *file, ngx_file_info_t *sb) { /* Win95 */ @@ -270,7 +275,8 @@ ngx_int_t ngx_file_info(u_char *file, ngx_file_info_t *sb) } -ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) +ngx_int_t +ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) { ngx_cpystrn(name->data + name->len, NGX_DIR_MASK, NGX_DIR_MASK_LEN + 1); @@ -287,7 +293,8 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) } -ngx_int_t ngx_read_dir(ngx_dir_t *dir) +ngx_int_t +ngx_read_dir(ngx_dir_t *dir) { if (dir->ready) { dir->ready = 0; @@ -316,7 +323,8 @@ ngx_de_link_info(u_char *name, ngx_dir_t *dir) } -ngx_int_t ngx_file_append_mode(ngx_fd_t fd) +ngx_int_t +ngx_file_append_mode(ngx_fd_t fd) { #if 0 if (LockFile(fd, 0, 0, 0xffffffff, 0xffffffff) == 0) { diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h index 3ac40b43f..4c1498407 100644 --- a/src/os/win32/ngx_time.h +++ b/src/os/win32/ngx_time.h @@ -12,29 +12,30 @@ #include <ngx_core.h> -typedef ngx_rbtree_key_t ngx_msec_t; - -typedef SYSTEMTIME ngx_tm_t; -typedef FILETIME ngx_mtime_t; - -#define ngx_tm_sec wSecond -#define ngx_tm_min wMinute -#define ngx_tm_hour wHour -#define ngx_tm_mday wDay -#define ngx_tm_mon wMonth -#define ngx_tm_year wYear -#define ngx_tm_wday wDayOfWeek - -#define ngx_tm_sec_t u_short -#define ngx_tm_min_t u_short -#define ngx_tm_hour_t u_short -#define ngx_tm_mday_t u_short -#define ngx_tm_mon_t u_short -#define ngx_tm_year_t u_short -#define ngx_tm_wday_t u_short - - -#define ngx_msleep Sleep +typedef ngx_rbtree_key_t ngx_msec_t; +typedef ngx_rbtree_key_int_t ngx_msec_int_t; + +typedef SYSTEMTIME ngx_tm_t; +typedef FILETIME ngx_mtime_t; + +#define ngx_tm_sec wSecond +#define ngx_tm_min wMinute +#define ngx_tm_hour wHour +#define ngx_tm_mday wDay +#define ngx_tm_mon wMonth +#define ngx_tm_year wYear +#define ngx_tm_wday wDayOfWeek + +#define ngx_tm_sec_t u_short +#define ngx_tm_min_t u_short +#define ngx_tm_hour_t u_short +#define ngx_tm_mday_t u_short +#define ngx_tm_mon_t u_short +#define ngx_tm_year_t u_short +#define ngx_tm_wday_t u_short + + +#define ngx_msleep Sleep #define NGX_HAVE_GETTIMEZONE 1 |