pan-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pan-users] 0.14 - attempted fix of the "freeze when connection is lost


From: Alberto BARSELLA
Subject: [Pan-users] 0.14 - attempted fix of the "freeze when connection is lost
Date: Sat, 10 May 2003 10:03:03 +0200
User-agent: Mutt/1.4.1i

Hi all,
        again on the problem of pan not being able to resume downloads
in case the ADSL (or whatever) link to the server is lost.  I've made a
fix in sockets.c (diff patch appended).

Changes are:
- the io_channel is made non-blocking, so that EAGAIN can actually be a
 return value for read/write operations.
- after each EAGAIN, we sleep one second and increment a counter.  When
 the counter hits PAN_SOCK_FAILED_OP_THRESHOLD the connection is
 dropped as in the case of an error.  Pan will then reattempt to
 connect as normal.

Caveats:
- it SEEMS to be working, this does not mean it's perfect or 100%
 reliable, please test and report.  I'm not certain of the way
 the code handles EAGAIN in read mode.
- the value of PAN_SOCK_FAILED_OP_THRESHOLD has a default of 60.  If you
 are on a 56K modem and you use a ton of connections this may be too low.
Bye,
Alberto

--

diff -ur pan-0.14.0.original/pan/sockets.c pan-0.14.0/pan/sockets.c
--- pan-0.14.0.original/pan/sockets.c   2003-04-08 22:13:33.000000000 +0200
+++ pan-0.14.0/pan/sockets.c    2003-05-10 09:44:27.000000000 +0200
@@ -69,8 +69,13 @@
        guint bytes_read;
        guint bytes_written;
        time_t byte_count_start_time;
+
+       gint failed_operations;
};

+
+#define PAN_SOCK_FAILED_OP_THRESHOLD 60
+
/*********************
**********************  Variables
*********************/
@@ -126,6 +131,7 @@
        sock->bytes_read = 0u;
        sock->bytes_written = 0u;
        sock->byte_count_start_time = time(NULL);
+       sock->failed_operations = 0;
        sock->line_buffer = g_string_sized_new (512);
        sock->error = FALSE;
        sock->need_auth = FALSE;
@@ -142,6 +148,7 @@
                sock->gio_channel = gnet_tcp_socket_get_iochannel 
(sock->gnet_socket);
                if (g_io_channel_get_encoding (sock->gio_channel) != NULL)
                        g_io_channel_set_encoding (sock->gio_channel, NULL, 
NULL);
+               g_io_channel_set_flags(sock->gio_channel, G_IO_FLAG_NONBLOCK, 
NULL);
                g_io_channel_set_buffered (sock->gio_channel, TRUE);
                g_io_channel_set_line_term (sock->gio_channel, "\n", 1);
                log_add_va (LOG_INFO, _("New connection %p for %s, port %d"), 
sock, server_address, port);
@@ -221,6 +228,12 @@
                        case G_IO_STATUS_AGAIN:
                                if (err != NULL)
                                        g_error_free (err);
+                               sock->failed_operations++;
+
+                               if (sock->failed_operations > 
PAN_SOCK_FAILED_OP_THRESHOLD) {
+                                       pan_socket_set_error_flag (sock, TRUE);
+                                       return -1;
+                               }
                                g_usleep (G_USEC_PER_SEC);
                                continue;
                        case G_IO_STATUS_ERROR:
@@ -232,6 +245,7 @@
                                pan_socket_set_error_flag (sock, TRUE);
                                return -1;
                        case G_IO_STATUS_NORMAL:
+                               sock->failed_operations = 0;
                                done = TRUE;
                                break;
                }
@@ -280,11 +294,21 @@
                        case G_IO_STATUS_AGAIN:
                                if (err != NULL)
                                        g_error_free (err);
+                               sock->failed_operations++;
+
+                               if (sock->failed_operations > 
PAN_SOCK_FAILED_OP_THRESHOLD) {
+                                       pan_socket_set_error_flag (sock, TRUE);
+                                       return -1;
+                               }
                                g_usleep (G_USEC_PER_SEC);
-                               /* fall through */
+                               nleft -= bytes_written;
+                               line += bytes_written;
+                               continue;
+
                        case G_IO_STATUS_NORMAL:
                                nleft -= bytes_written;
                                line += bytes_written;
+                               sock->failed_operations = 0;
                                continue;
                        case G_IO_STATUS_EOF:
                        case G_IO_STATUS_ERROR:

--
Alberto BARSELLA
** Beliefs are dangerous. Beliefs allow the mind to stop functioning.
A non-functioning mind is clinically dead.  Believe in nothing... **




reply via email to

[Prev in Thread] Current Thread [Next in Thread]