Re: Menu items won't open and close after a while



On 01/01/2010 05:51:23 PM, Mike Witt wrote:
Hi Mike,

I do not recall a problem like this. It looks like a file descriptor leak to me. Maybe the output of 'lsof' will reveal more information?

I'm not exactly sure what to look for. My current balsa has been
running for a couple of days ...

lsof | grep balsa | wc -l

  appears to show 232 open files.

Of which 42 are something like: "/tmp/pop-HT3P5U (deleted)", so I assume
those are hanging around from my POP connections to gmail.

Mike,

I think you hit the spot! The pop3 handling code could leak the file descriptors when the network connection was broken while downloading the message. I attach the patch that fixes the problem for me. I have commited it also to git repository.

Pawel
diff --git a/libbalsa/imap/pop3.c b/libbalsa/imap/pop3.c
index 8eb5237..dbe5222 100644
--- a/libbalsa/imap/pop3.c
+++ b/libbalsa/imap/pop3.c
@@ -177,7 +177,7 @@ pop_check_status(PopHandle *pop, GError **err)
     pop->state = IMHS_DISCONNECTED;
     sio_detach(pop->sio); pop->sio = NULL; close(pop->sd);
     g_set_error(err, IMAP_ERROR, IMAP_POP_SEVERED_ERROR,
-                "POP3 Connection severed");
+                "POP3 connection severed");
     return FALSE;
   }
      
@@ -726,7 +726,8 @@ pop_complete_retr(PopHandle *pop, PopAsyncCb cb, void *arg)
   if(cb)
     cb(rc, arg, &err);
   if(resp) { /* same code as in fetch_message() */
-    while( sio_gets(pop->sio, line, sizeof(line)) &&
+    char * str;
+    while( (str = sio_gets(pop->sio, line, sizeof(line))) &&
            strcmp(line, ".\r\n") ) {
       char *buf = line[0] == '.' ? line+1 : line;
       unsigned len = strlen(buf);
@@ -735,8 +736,18 @@ pop_complete_retr(PopHandle *pop, PopAsyncCb cb, void *arg)
       if(cb) 
         cb(POP_REQ_DATA, arg, len, buf);
     }
-    if(cb)
-      cb(POP_REQ_DONE, arg, err);
+    if(!str) {/* Unexpected end of data */
+      pop->state = IMHS_DISCONNECTED;
+      sio_detach(pop->sio); pop->sio = NULL; close(pop->sd);
+      g_set_error(&err, IMAP_ERROR, IMAP_POP_SEVERED_ERROR,
+                "POP3 connection severed");
+      
+      if(cb)
+        cb(POP_REQ_ERR, arg, &err);
+    } else {
+      if(cb)
+        cb(POP_REQ_DONE, arg);
+    }
   }
 
   g_clear_error(&err);
diff --git a/libbalsa/mailbox_pop3.c b/libbalsa/mailbox_pop3.c
index 8d5652d..69f66b8 100644
--- a/libbalsa/mailbox_pop3.c
+++ b/libbalsa/mailbox_pop3.c
@@ -389,18 +389,18 @@ fetch_async_cb(PopReqCode prc, void *arg, ...)
 	}
 	break;
     case POP_REQ_DONE:
-            if(fd->dm->close(fd->f) != 0) {
-                if(!*fd->err)
-                    g_set_error(fd->err, IMAP_ERROR, IMAP_POP_SAVE_ERROR,
-                                _("Transferring POP message to %s failed."),
-                                fd->dest_path);
-            } else if(!fd->error_occured &&
-                      move_from_msgdrop
-                      (fd->tmp_path,
-                       LIBBALSA_MAILBOX_POP3(fd->mailbox)->inbox,
-                       fd->mailbox->name, fd->msgno) &&
-                      fd->delete_on_server)
-                pop_delete_message(fd->pop, fd->msgno, NULL, NULL, NULL);
+        if(fd->dm->close(fd->f) != 0) {
+            if(!*fd->err)
+                g_set_error(fd->err, IMAP_ERROR, IMAP_POP_SAVE_ERROR,
+                            _("Transferring POP message to %s failed."),
+                            fd->dest_path);
+        } else if(!fd->error_occured &&
+                  move_from_msgdrop
+                  (fd->tmp_path,
+                   LIBBALSA_MAILBOX_POP3(fd->mailbox)->inbox,
+                   fd->mailbox->name, fd->msgno) &&
+                  fd->delete_on_server)
+            pop_delete_message(fd->pop, fd->msgno, NULL, NULL, NULL);
 	fd->f = NULL;
 	break;
     }
@@ -410,6 +410,12 @@ fetch_async_cb(PopReqCode prc, void *arg, ...)
 static void
 async_notify(struct fetch_data *fd)
 {
+    /* We need to close the file here only when POP_REQ_ERR
+       arrived. */
+    if (fd->f) {
+        fd->dm->close(fd->f);
+        fd->f = NULL;
+    }
     g_free(fd);
 }
 
@@ -517,6 +523,7 @@ libbalsa_mailbox_pop3_check(LibBalsaMailbox * mailbox)
         unsigned msg_size = pop_get_msg_size(pop, i);
 #if POP_SYNC
         FILE *f;
+        gboolean retval;
 #endif
         if(!m->delete_from_server) {
             const char *uid = pop_get_uid(pop, i, NULL);
@@ -546,14 +553,16 @@ libbalsa_mailbox_pop3_check(LibBalsaMailbox * mailbox)
 			     dest_path);
             break;
         }
-        if(!pop_fetch_message_s(pop, i, dump_cb, f, &err)) 
-            break;
+        retval = pop_fetch_message_s(pop, i, dump_cb, f, &err);
+
         if(mode->close(f) != 0) {
             libbalsa_information(LIBBALSA_INFORMATION_ERROR,
 			     _("POP3 error: cannot close %s."), 
 			     dest_path);
             break;
         }
+        if (!retval)
+            break;
         if(move_from_msgdrop(tmp_path, m->inbox,
                              mailbox->name, i) &&
            m->delete_from_server)



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