diff --git a/lib/modules/SSL.pmod/sslfile.pike b/lib/modules/SSL.pmod/sslfile.pike
index b3e8d9599f071c92c5a370694f1b025862c8f71b..fc0072c53dc030e24dc6dc475b16021c3ae02198 100644
--- a/lib/modules/SSL.pmod/sslfile.pike
+++ b/lib/modules/SSL.pmod/sslfile.pike
@@ -1,6 +1,6 @@
 #pike __REAL_VERSION__
 
-/* $Id: sslfile.pike,v 1.98 2006/08/17 14:04:10 mast Exp $
+/* $Id: sslfile.pike,v 1.99 2006/11/16 12:49:40 mast Exp $
  */
 
 #if constant(SSL.Cipher.CipherAlgorithm)
@@ -31,6 +31,11 @@
 //!   @[is_open], connection init (@[create]) and close (@[close]) can
 //!   do both reading and writing.
 //! @item
+//!   @[destroy] attempts to close the stream properly by sending the
+//!   close packet, but since it can't do blocking I/O it's not
+//!   certain that will succeed. The stream should therefore always be
+//!   closed with an explicit @[close] call.
+//! @item
 //!   Abrupt remote close without the proper handshake gets the errno
 //!   @[System.EPIPE].
 //! @item
@@ -209,11 +214,15 @@ static constant epipe_errnos = (<
 static void thread_error (string msg, THREAD_T other_thread)
 {
   error ("%s"
+	 "%s\n"
 	 "User callbacks: a=%O r=%O w=%O c=%O\n"
 	 "Internal callbacks: r=%O w=%O c=%O\n"
 	 "Backend: %O  This thread: %O  Other thread: %O\n"
 	 "Other thread backtrace:\n%s----------\n",
 	 msg,
+	 !stream ? "Got no stream" :
+	 stream->is_open() ? "Stream is open" :
+	 "Stream is closed",
 	 accept_callback, read_callback, write_callback, close_callback,
 	 stream && stream->query_read_callback(),
 	 stream && stream->query_write_callback(),
@@ -231,10 +240,14 @@ static void thread_error (string msg, THREAD_T other_thread)
 static void thread_error (string msg, THREAD_T other_thread)
 {
   error ("%s"
+	 "%s\n"
 	 "User callbacks: a=%O r=%O w=%O c=%O\n"
 	 "Internal callbacks: r=%O w=%O c=%O\n"
 	 "Backend: %O\n",
 	 msg,
+	 !stream ? "Got no stream" :
+	 stream->is_open() ? "Stream is open" :
+	 "Stream is closed",
 	 accept_callback, read_callback, write_callback, close_callback,
 	 stream && stream->query_read_callback(),
 	 stream && stream->query_write_callback(),
@@ -639,25 +652,23 @@ Stdio.File shutdown()
 }
 
 static void destroy()
-// Try to close down the connection properly in blocking mode since
-// it's customary to close files just by dropping them.
+//! Try to close down the connection properly since it's customary to
+//! close files just by dropping them. No guarantee can be made that
+//! the close packet gets sent successfully though, because we can't
+//! risk blocking I/O here. You should call @[close] explicitly.
 {
   SSL3_DEBUG_MSG ("SSL.sslfile->destroy()\n");
 
-  // Note that we don't know which thread this will be called in
-  // (could be anyone if the gc got here), so there might be a race
-  // problem with a backend in another thread. That would only
-  // happen if somebody has destructed this object explicitly
-  // though, and in that case he can have all that's coming.
+  // We don't know which thread this will be called in if the refcount
+  // garb or the gc got here. That's not a race problem since it won't
+  // be registered in a backend in that case.
   ENTER (0, 0) {
     if (stream) {
       if (close_state <= STREAM_OPEN &&
 	  // Don't bother with closing nicely if there's an error from
 	  // an earlier operation. close() will throw an error for it.
 	  !cb_errno) {
-	// Have to do the close in blocking mode since this object will
-	// go away as soon as we return.
-	set_blocking();
+	set_nonblocking_keep_callbacks();
 	close (0, 0, 1);
       }
       else
@@ -1354,10 +1365,6 @@ static int direct_write()
   return 1;
 }
 
-private int call_close_callback()
-{
-}
-
 static int ssl_read_callback (int called_from_real_backend, string input)
 {
   SSL3_DEBUG_MSG ("ssl_read_callback (%O, %s): "