00001
00002
00003
00004
00005
00006 #include <pthread.h>
00007 #include <errno.h>
00008 #include <signal.h>
00009 #include <stdlib.h>
00010 #include <time.h>
00011
00012 #include "common.h"
00013 #include "libjio.h"
00014 #include "compat.h"
00015
00016
00018 struct autosync_cfg {
00020 struct jfs *fs;
00021
00023 pthread_t tid;
00024
00026 time_t max_sec;
00027
00029 size_t max_bytes;
00030
00032 sig_atomic_t must_die;
00033
00035 pthread_cond_t cond;
00036
00038 pthread_mutex_t mutex;
00039 };
00040
00042 static void *autosync_thread(void *arg)
00043 {
00044 int rv;
00045 void *had_errors;
00046 struct timespec ts;
00047 struct autosync_cfg *cfg;
00048
00049 cfg = (struct autosync_cfg *) arg;
00050
00051
00052
00053 had_errors = (void *) 0;
00054
00055 pthread_mutex_lock(&cfg->mutex);
00056 for (;;) {
00057 clock_gettime(CLOCK_REALTIME, &ts);
00058 ts.tv_sec += cfg->max_sec;
00059
00060 rv = pthread_cond_timedwait(&cfg->cond, &cfg->mutex, &ts);
00061 if (rv != 0 && rv != ETIMEDOUT)
00062 break;
00063
00064 if (cfg->must_die)
00065 break;
00066
00067
00068 if (rv != ETIMEDOUT && cfg->fs->ltrans_len < cfg->max_bytes)
00069 continue;
00070
00071 rv = jsync(cfg->fs);
00072 if (rv != 0)
00073 had_errors = (void *) 1;
00074
00075 }
00076 pthread_mutex_unlock(&cfg->mutex);
00077
00078 pthread_exit(had_errors);
00079 return NULL;
00080 }
00081
00082
00083
00084 int jfs_autosync_start(struct jfs *fs, time_t max_sec, size_t max_bytes)
00085 {
00086 struct autosync_cfg *cfg;
00087
00088 if (fs->as_cfg != NULL)
00089 return -1;
00090
00091 cfg = malloc(sizeof(struct autosync_cfg));
00092 if (cfg == NULL)
00093 return -1;
00094
00095 cfg->fs = fs;
00096 cfg->max_sec = max_sec;
00097 cfg->max_bytes = max_bytes;
00098 cfg->must_die = 0;
00099 pthread_cond_init(&cfg->cond, NULL);
00100 pthread_mutex_init(&cfg->mutex, NULL);
00101
00102 fs->as_cfg = cfg;
00103
00104 return pthread_create(&cfg->tid, NULL, &autosync_thread, cfg);
00105 }
00106
00107
00108
00109 int jfs_autosync_stop(struct jfs *fs)
00110 {
00111 int rv = 0;
00112 void *had_errors;
00113
00114 if (fs->as_cfg == NULL)
00115 return 0;
00116
00117 fs->as_cfg->must_die = 1;
00118 pthread_cond_signal(&fs->as_cfg->cond);
00119 pthread_join(fs->as_cfg->tid, &had_errors);
00120
00121 if (had_errors)
00122 rv = -1;
00123
00124 pthread_cond_destroy(&fs->as_cfg->cond);
00125 pthread_mutex_destroy(&fs->as_cfg->mutex);
00126 free(fs->as_cfg);
00127 fs->as_cfg = NULL;
00128
00129 return rv;
00130 }
00131
00134 void autosync_check(struct jfs *fs)
00135 {
00136 if (fs->as_cfg == NULL)
00137 return;
00138
00139 if (fs->ltrans_len > fs->as_cfg->max_bytes)
00140 pthread_cond_signal(&fs->as_cfg->cond);
00141 }
00142