Fixed SIGSEGV during close of GnomeVFSHandle reopened due to its timeout.
authorshort <>
Wed, 12 Nov 2003 06:26:40 +0000 (06:26 +0000)
committershort <>
Wed, 12 Nov 2003 06:26:40 +0000 (06:26 +0000)
Implemented Inet socket read() interrupter for responsible GMainLoop.

src/install/acquire/cabinet.c

index 71170ab..95465a3 100644 (file)
@@ -31,6 +31,7 @@
 #include "main.h"
 #include <signal.h>
 #include <setjmp.h>
+#include <sys/time.h>
 
 #include <captive/macros.h>
 
 /* Config: */
 #define ACQUIRE_CABINET_READ_RAW_READ_TRY_MAX 5
 #define ACQUIRE_CABINET_READ_RAW_READ_TIMEOUT 20
+#define ACQUIRE_CABINET_READ_RAW_READ_ITER_SEC 0
+#define ACQUIRE_CABINET_READ_RAW_READ_ITER_USEC 100000
+
+
+#define ACQUIRE_CABINET_READ_RAW_READ_TIMEOUT_ITERS \
+               ((ACQUIRE_CABINET_READ_RAW_READ_TIMEOUT *1000000LL) \
+               /(ACQUIRE_CABINET_READ_RAW_READ_ITER_SEC*1000000LL+ACQUIRE_CABINET_READ_RAW_READ_ITER_USEC))
 
 
 void acquire_cabinet_seek(struct acquire_cabinet *acquire_cabinet,GnomeVFSFileOffset offset)
@@ -70,7 +78,7 @@ GnomeVFSFileOffset acquire_cabinet_tell(struct acquire_cabinet *acquire_cabinet)
        return acquire_cabinet->offset;
 }
 
-static gboolean handler_SIGALRM_hit;
+static guint handler_SIGALRM_hits;
 static sigjmp_buf handler_SIGALRM_sigjmp_buf;
 
 static void handler_SIGALRM(int signo)
@@ -83,11 +91,9 @@ static void handler_SIGALRM(int signo)
         * and we will abort it after 1 second. OK, some data may be read that time
         * but who cares.
         */
-       if (!handler_SIGALRM_hit) {
-               handler_SIGALRM_hit=TRUE;
-               alarm(1);
+       if (handler_SIGALRM_hits++<ACQUIRE_CABINET_READ_RAW_READ_TIMEOUT_ITERS
+                       && !(*ui_progress)(NULL))
                return;
-               }
 
        siglongjmp(handler_SIGALRM_sigjmp_buf,1);       /* 1; meaning: !=0 */
 }
@@ -116,10 +122,10 @@ gint try=0;
 
        while (try++<=ACQUIRE_CABINET_READ_RAW_READ_TRY_MAX) {
 GnomeVFSResult errvfsresult;
-unsigned erruint;
 GnomeVFSHandle *handle_new;
 struct sigaction oldact;
 int errint;
+struct itimerval itimerval;
 
                if ((*ui_progress)(NULL))
                        return GNOME_VFS_ERROR_INTERRUPTED;
@@ -127,22 +133,35 @@ int errint;
                if (!sigsetjmp(
                                handler_SIGALRM_sigjmp_buf,     /* env */
                                TRUE)) {        /* savesigs */
-                       handler_SIGALRM_hit=FALSE;
+                       handler_SIGALRM_hits=0;
                        errint=sigaction(
                                        SIGALRM,        /* signum */
                                        NULL,   /* act */
                                        &oldact);       /* oldact */
                        g_assert(errint==0);
                        signal(SIGALRM,handler_SIGALRM);
-                       erruint=alarm(ACQUIRE_CABINET_READ_RAW_READ_TIMEOUT);
-                       g_assert(erruint==0);
-                       errvfsresult=gnome_vfs_seek(acquire_cabinet->handle,GNOME_VFS_SEEK_START,offset);
+                       itimerval.it_interval.tv_sec=ACQUIRE_CABINET_READ_RAW_READ_ITER_SEC;
+                       itimerval.it_interval.tv_usec=ACQUIRE_CABINET_READ_RAW_READ_ITER_USEC;
+                       itimerval.it_value=itimerval.it_interval;
+                       errint=setitimer(
+                                       ITIMER_REAL,    /* which */
+                                       &itimerval,     /* value */
+                                       NULL);  /* ovalue */
+                       g_assert(errint==0);
+                       errvfsresult=gnome_vfs_seek(*acquire_cabinet->handlep,GNOME_VFS_SEEK_START,offset);
                        if (GNOME_VFS_OK==errvfsresult)
-                               errvfsresult=gnome_vfs_read(acquire_cabinet->handle,buffer,bytes,bytes_read);
+                               errvfsresult=gnome_vfs_read(*acquire_cabinet->handlep,buffer,bytes,bytes_read);
                        }
                else
                        errvfsresult=GNOME_VFS_ERROR_INTERRUPTED;
-               alarm(0);
+               itimerval.it_interval.tv_sec=0;
+               itimerval.it_interval.tv_usec=0;
+               itimerval.it_value=itimerval.it_interval;
+               errint=setitimer(
+                               ITIMER_REAL,    /* which */
+                               &itimerval,     /* value */
+                               NULL);  /* ovalue */
+               g_assert(errint==0);
                errint=sigaction(
                                SIGALRM,        /* signum */
                                &oldact,        /* act */
@@ -153,12 +172,11 @@ int errint;
                        return GNOME_VFS_OK;
                        }
 
-               /* Reopen 'acquire_cabinet->handle' */
-
+               /* Reopen '*acquire_cabinet->handlep' */
                g_assert(acquire_cabinet->handle_uri!=NULL);
                if (GNOME_VFS_OK==(errvfsresult=gnome_vfs_open_uri(&handle_new,acquire_cabinet->handle_uri,GNOME_VFS_OPEN_READ))) {
-                       gnome_vfs_close(acquire_cabinet->handle);       /* errors ignored */
-                       acquire_cabinet->handle=handle_new;
+                       gnome_vfs_close(*acquire_cabinet->handlep);     /* errors ignored */
+                       *acquire_cabinet->handlep=handle_new;
                        }
                }
 
@@ -264,7 +282,7 @@ struct acquire_cabinet *r;
        r->base=(/* de-const */ gpointer)file_base;
        r->base_cached=NULL;
        r->offset=0;
-       r->handle=NULL;
+       r->handlep=NULL;
        r->size=file_length;
        acquire_cabinet_set_uri(r,uri);
        r->cabinet_done=0;
@@ -274,11 +292,12 @@ struct acquire_cabinet *r;
 }
 
 struct acquire_cabinet *acquire_cabinet_new_from_handle
-               (GnomeVFSHandle *handle,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri,gint cabinet_used)
+               (GnomeVFSHandle **handlep,GnomeVFSFileInfo *file_info,GnomeVFSURI *uri,gint cabinet_used)
 {
 struct acquire_cabinet *r;
 
-       g_return_val_if_fail(handle!=NULL,NULL);
+       g_return_val_if_fail(handlep!=NULL,NULL);
+       g_return_val_if_fail(*handlep!=NULL,NULL);
        g_return_val_if_fail(file_info!=NULL,NULL);
        g_return_val_if_fail(uri!=NULL,NULL);
        
@@ -296,7 +315,7 @@ struct acquire_cabinet *r;
                }
        captive_new0n(r->base_cached,CAPTIVE_ROUND_UP64(file_info->size,8)/8);
        r->offset=0;
-       r->handle=handle;
+       r->handlep=handlep;
        r->size=file_info->size;
        acquire_cabinet_set_uri(r,uri);
        r->cabinet_done=0;