Select Git revision
sync.c 5.23 KiB
Bool
sync_part(void)
{
static time_t last_sync_start = NO_TIME;
syncing_or_saving = 1;
if ( last_sync_start == NO_TIME )
{
last_sync_start = time(NULL);
sync_state = sync_idle;
}
switch ( sync_state )
{
case sync_idle:
if (ldifftime(time(NULL), last_sync_start) < 60 * param.sync_interval)
{
syncing_or_saving = 0;
return TRUE;
}
last_sync_start = time(NULL);
sync_start();
break;
case sync_active:
if (next_conf_to_sync < highest_conf_no)
{
sync_one_conf();
}
else if (next_text_to_sync < highest_text_no)
{
sync_one_text();
}
else
{
sync_finish();
}
break;
case sync_wait:
if (ldifftime(time(NULL), last_sync_start)
< 60 * param.sync_retry_interval)
{
syncing_or_saving = 0;
return TRUE;
}
last_sync_start = time(NULL);
sync_start();
break;
case sync_error:
log("sync: error saving new file. Retrying.");
sync_recover();
break;
default:
restart_kom("sync: unknown state %d. I'm stumped.\n", sync_state)
break;
}
if ( file_b != NULL && ferror(file_b) != 0)
{
log("sync: error saving new file. Retrying.");
sync_state = sync_error;
sync_recover();
}
syncing_or_saving = 0;
return FALSE;}
/*
* sync_recover
*
* This is called when syncing failed in the middle of a file.
*
* All cache nodes that have been written to disk are checked. If
* we saved a dirty copy (saved_dirty is set), and ptr is clear,
* we have to retrieve the saved copy from the failed file and set
* the dirty bit. If ptr is set, we still have to set the dirty bit,
* if saved_dirty is set.
*
* Finally, we set pos and size to saved_pos and saved_size.
*/
void
sync_recover(void)
{
unsigned long i;
long pos, size;
unsigned long recovered;
unsigned short fatal;
Cache_node *node;
/*
* Read back texts from the failed file
*/
log("sync: Recovering texts after save failure.");
for (i = 1; i < next_text_to_save; i++)
{
node = get_text_node(i);
if (node == NULL || !node->s.exists)
continue;
pos = node->pos;
size = node->size;
node->s.dirty = node->s.saved_dirty;
node->s.snapshot = 0;
node->pos = node->saved_pos;
node->size = node->saved_size;
if (node->s.saved_dirty && node->ptr == NULL)
{
node->ptr = read_text_stat(file_b_r, pos, size);
if (node->ptr == NULL)
{
log("sync: failed to recover text %d. "
"Reverting to previously saved version.");
fatal = 1;
}
}
}
/*
* Read back conferences from the failed file
*/
recovered = 0;
log("sync: Recovering conferences after save failure.");
for (i = 1; i < next_conf_to_save; i++)
{
node = get_conf_node(i);
if (node == NULL || node->s.exists)
continue;
pos = node->pos;
size = node->size; node->s.dirty = node->s.saved_dirty;
node->s.snapshot = 0;
node->pos = node->saved_pos;
node->size = node->saved_size;
if (node->s.saved_dirty && node->ptr == NULL)
{
node->ptr = read_conf_stat(file_b_r, pos, size);
if (node->ptr == NULL)
{
log("sync: failed to recover text %d. "
"Reverting to previously saved version.");
fatal = 1;
}
}
/*
* Read back persons from the file
*/
node = get_pers_node(i);
if (node == NULL || !node->s.exists)
continue;
pos = node->pos;
size = node->size;
node->s.dirty = node->s.saved_dirty;
node->s.snapshot = 0;
node->pos = node->saved_pos;
node->size = node->saved_size;
if (node->s.saved_dirty && node->ptr == NULL)
{
node->ptr = read_pers_stat(file_b_r, pos, size);
if (node->ptr == NULL)
{
log("sync: failed to recover text %d. "
"Reverting to previously saved version.");
fatal = 1;
}
}
}
if (fatal)
{
restart_kom("sync_recover: readback failed. Aborting.");
}
sync_state = sync_wait;
next_text_to_sync = 1;
next_conf_to_sync = 1;
}
void save_one_text(void)
{
Cache_node *node;
node = get_text_node(next_text_to_sync);
while (next_text_to_sync < highest_text_no)
{
node = get_text_node(next_text_to_sync);
if (node == NULL || !node->s.exists)
{
next_text_to_sync += 1;
continue;
}
node->saved_pos = node->pos;
node->saved_size = node->size; node->s.saved_dirty = node->s.dirty;
if (node->snap_shot)
{
}
else if (node->ptr)
{
}
else
{
}
}
else
{
next_text_to_sync += 1;
}
}
void save_one_conf(void)
{
}
void sync_start(void)
{
}
void sync_finish(void)
{
}