nginx-0.3.1-RELEASE import

    *) Bugfix: the segmentation fault occurred when the signal queue
       overflowed if the "rtsig" method was used; the bug had appeared in
       0.2.0.

    *) Change: correct handling of the "\\", "\"", "\'", and "\$" pairs in
       SSI.
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 177c05d..a53b8eb 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -405,7 +405,6 @@
 
     if (timer == NGX_TIMER_INFINITE || timer > 500) {
         timer = 500;
-        break;
     }
 
 #endif
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index ee55915..99342ab 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -462,7 +462,6 @@
 
     if (timer == NGX_TIMER_INFINITE || timer > 500) {
         timer = 500;
-        break;
     }
 
 #endif
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index fdbbb2f..f88dd5d 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -307,7 +307,6 @@
 
         if (timer == NGX_TIMER_INFINITE || timer > 500) {
             timer = 500;
-            break;
         }
 
 #endif
@@ -578,7 +577,7 @@
 
             c = cycle->files[overflow_current++];
 
-            if (c->fd == -1) {
+            if (c == NULL || c->fd == -1) {
                 continue;
             }
 
@@ -634,6 +633,10 @@
         for (i = 0; i < n; i++) {
             c = cycle->files[overflow_list[i].fd];
 
+            if (c == NULL) {
+                continue;
+            }
+
             rev = c->read;
 
             if (rev->active
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 308d460..9d917ea 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -130,18 +130,7 @@
 
     ngx_log_t       *log;
 
-    /* TODO: threads: padding to cache line */
-
-    /*
-     * STUB: The inline of "ngx_rbtree_t  rbtree;"
-     */
-
-    ngx_rbtree_key_t   rbtree_key;
-    void              *rbtree_left;
-    void              *rbtree_right;
-    void              *rbtree_parent;
-    char               rbtree_color;
-
+    ngx_rbtree_node_t   timer;
 
     unsigned         closed:1;
 
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 49640fa..48a03a1 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -144,6 +144,10 @@
 ngx_int_t
 ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl)
 {
+    if (SSL_CTX_need_tmp_RSA(ssl->ctx) == 0) {
+        return NGX_OK;
+    }
+
     ssl->rsa512_key = RSA_generate_key(512, RSA_F4, NULL, NULL);
 
     if (ssl->rsa512_key) {
@@ -851,7 +855,10 @@
 {
    ngx_ssl_t  *ssl = data;
 
-   RSA_free(ssl->rsa512_key);
+   if (ssl->rsa512_key) {
+       RSA_free(ssl->rsa512_key);
+   }
+
    SSL_CTX_free(ssl->ctx);
 }
 
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index c3d3c7e..656f62b 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -14,27 +14,28 @@
 #endif
 
 
-ngx_thread_volatile ngx_rbtree_t  *ngx_event_timer_rbtree;
-ngx_rbtree_t                       ngx_event_timer_sentinel;
+ngx_thread_volatile ngx_rbtree_t  ngx_event_timer_rbtree;
+static ngx_rbtree_node_t          ngx_event_timer_sentinel;
 
 
 ngx_int_t
 ngx_event_timer_init(ngx_log_t *log)
 {
-    if (ngx_event_timer_rbtree) {
+    ngx_event_timer_rbtree.root = &ngx_event_timer_sentinel;
+    ngx_event_timer_rbtree.sentinel = &ngx_event_timer_sentinel;
+
 #if (NGX_THREADS)
+
+    if (ngx_event_timer_mutex) {
         ngx_event_timer_mutex->log = log;
-#endif
         return NGX_OK;
     }
 
-    ngx_event_timer_rbtree = &ngx_event_timer_sentinel;
-
-#if (NGX_THREADS)
     ngx_event_timer_mutex = ngx_mutex_init(log, 0);
     if (ngx_event_timer_mutex == NULL) {
         return NGX_ERROR;
     }
+
 #endif
 
     return NGX_OK;
@@ -44,10 +45,10 @@
 ngx_msec_t
 ngx_event_find_timer(void)
 {
-    ngx_msec_t     timer;
-    ngx_rbtree_t  *node;
+    ngx_rbtree_key_int_t   timer;
+    ngx_rbtree_node_t     *node, *root, *sentinel;
 
-    if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
+    if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) {
         return NGX_TIMER_INFINITE;
     }
 
@@ -55,35 +56,41 @@
         return NGX_TIMER_ERROR;
     }
 
-    node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
-                          &ngx_event_timer_sentinel);
+    root = ngx_event_timer_rbtree.root;
+    sentinel = ngx_event_timer_rbtree.sentinel;
+
+    node = ngx_rbtree_min(root, sentinel);
 
     ngx_mutex_unlock(ngx_event_timer_mutex);
 
-    timer = (ngx_msec_t) node->key - ngx_current_time;
+    timer = (ngx_rbtree_key_int_t) node->key
+                                     - (ngx_rbtree_key_int_t) ngx_current_time;
 
-    return timer > 0 ? timer : 0 ;
+    return (ngx_msec_t) (timer > 0 ? timer : 0);
 }
 
 
 void
 ngx_event_expire_timers(void)
 {
-    ngx_event_t   *ev;
-    ngx_rbtree_t  *node;
+    ngx_event_t        *ev;
+    ngx_rbtree_node_t  *node, *root, *sentinel;
+
+    sentinel = ngx_event_timer_rbtree.sentinel;
 
     for ( ;; ) {
 
-        if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
-            return;
-        }
-
         if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
             return;
         }
 
-        node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
-                              &ngx_event_timer_sentinel);
+        root = ngx_event_timer_rbtree.root;
+
+        if (root == sentinel) {
+            return;
+        }
+
+        node = ngx_rbtree_min(root, sentinel);
 
         /* node->key <= ngx_current_time */
 
@@ -91,8 +98,7 @@
                                       - (ngx_rbtree_key_int_t) ngx_current_time
             <= 0)
         {
-            ev = (ngx_event_t *)
-                           ((char *) node - offsetof(ngx_event_t, rbtree_key));
+            ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
 
 #if (NGX_THREADS)
 
@@ -114,18 +120,16 @@
 
             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                            "event timer del: %d: %M",
-                           ngx_event_ident(ev->data), ev->rbtree_key);
+                           ngx_event_ident(ev->data), ev->timer.key);
 
-            ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree,
-                              &ngx_event_timer_sentinel,
-                              (ngx_rbtree_t *) &ev->rbtree_key);
+            ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
 
             ngx_mutex_unlock(ngx_event_timer_mutex);
 
 #if (NGX_DEBUG)
-            ev->rbtree_left = NULL;
-            ev->rbtree_right = NULL;
-            ev->rbtree_parent = NULL;
+            ev->timer.left = NULL;
+            ev->timer.right = NULL;
+            ev->timer.parent = NULL;
 #endif
 
             ev->timer_set = 0;
diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h
index a9d3176..13b5c0a 100644
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -29,8 +29,7 @@
 #endif
 
 
-extern ngx_thread_volatile ngx_rbtree_t  *ngx_event_timer_rbtree;
-extern ngx_rbtree_t                       ngx_event_timer_sentinel;
+extern ngx_thread_volatile ngx_rbtree_t  ngx_event_timer_rbtree;
 
 
 static ngx_inline void
@@ -38,22 +37,20 @@
 {
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                    "event timer del: %d: %M",
-                    ngx_event_ident(ev->data), ev->rbtree_key);
+                    ngx_event_ident(ev->data), ev->timer.key);
 
     if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
         return;
     }
 
-    ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree,
-                      &ngx_event_timer_sentinel,
-                      (ngx_rbtree_t *) &ev->rbtree_key);
+    ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
 
     ngx_mutex_unlock(ngx_event_timer_mutex);
 
 #if (NGX_DEBUG)
-    ev->rbtree_left = NULL;
-    ev->rbtree_right = NULL;
-    ev->rbtree_parent = NULL;
+    ev->timer.left = NULL;
+    ev->timer.right = NULL;
+    ev->timer.parent = NULL;
 #endif
 
     ev->timer_set = 0;
@@ -76,31 +73,29 @@
          * the rbtree operations for the fast connections.
          */
 
-        diff = (ngx_rbtree_key_int_t) (key - ev->rbtree_key);
+        diff = (ngx_rbtree_key_int_t) (key - ev->timer.key);
 
         if (ngx_abs(diff) < NGX_TIMER_LAZY_DELAY) {
             ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                            "event timer: %d, old: %M, new: %M",
-                            ngx_event_ident(ev->data), ev->rbtree_key, key);
+                            ngx_event_ident(ev->data), ev->timer.key, key);
             return;
         }
 
         ngx_del_timer(ev);
     }
 
-    ev->rbtree_key = key;
+    ev->timer.key = key;
 
     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                    "event timer add: %d: %M:%M",
-                    ngx_event_ident(ev->data), timer, ev->rbtree_key);
+                    ngx_event_ident(ev->data), timer, ev->timer.key);
 
     if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
         return;
     }
 
-    ngx_rbtree_insert((ngx_rbtree_t **) &ngx_event_timer_rbtree,
-                      &ngx_event_timer_sentinel,
-                      (ngx_rbtree_t *) &ev->rbtree_key);
+    ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer);
 
     ngx_mutex_unlock(ngx_event_timer_mutex);