#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)
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)
* 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 */
}
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;
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 */
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;
}
}
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;
}
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);
}
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;