# HG changeset patch # User Maxim Dounin # Date 1333755969 0 # Node ID 876e6b0814a5f0c83e2f157685b8701d937ddd71 # Parent 709d7d24239dbaae4641a0959b815b9606811725 Fixed signed integer overflows in timer code (ticket #145). Integer overflow is undefined behaviour in C and this indeed caused problems on Solaris/SPARC (at least in some cases). Fix is to subtract unsigned integers instead, and then cast result to a signed one, which is implementation-defined behaviour and used to work. Strictly speaking, we should compare (unsigned) result with the maximum value of the corresponding signed integer type instead, this will be defined behaviour. This will require much more changes though, and considered to be overkill for now. diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c --- a/src/core/ngx_rbtree.c +++ b/src/core/ngx_rbtree.c @@ -136,8 +136,7 @@ ngx_rbtree_insert_timer_value(ngx_rbtree /* node->key < temp->key */ - p = ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key - < 0) + p = ((ngx_rbtree_key_int_t) (node->key - temp->key) < 0) ? &temp->left : &temp->right; if (*p == sentinel) { diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -67,7 +67,7 @@ ngx_event_find_timer(void) ngx_mutex_unlock(ngx_event_timer_mutex); - timer = (ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec; + timer = (ngx_msec_int_t) (node->key - ngx_current_msec); return (ngx_msec_t) (timer > 0 ? timer : 0); } @@ -95,8 +95,7 @@ ngx_event_expire_timers(void) /* node->key <= ngx_current_time */ - if ((ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec <= 0) - { + if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) { ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); #if (NGX_THREADS)