ngx_rbtree_node_t sentinel_expire;
ngx_msec_t last_write;
- ngx_uint_t dirty;
+ ngx_uint_t write_id;
ngx_uint_t writing;
} ngx_js_dict_sh_t;
ngx_event_t save_event;
ngx_str_t state_file;
ngx_str_t state_temp_file;
+ ngx_uint_t write_id;
ngx_js_dict_t *next;
};
done:
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
}
}
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
ngx_js_dict_node_free(dict, node);
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
}
}
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
u_char *name;
ngx_int_t rc;
ngx_log_t *log;
+ ngx_uint_t write_id;
ngx_msec_t now;
njs_chb_t chain;
ngx_file_t file;
ngx_rwlock_wlock(&dict->sh->rwlock);
- if (!dict->sh->dirty) {
+ if (dict->write_id < dict->sh->write_id) {
ngx_rwlock_unlock(&dict->sh->rwlock);
ngx_destroy_pool(pool);
return NGX_OK;
}
dict->sh->writing = 1;
- dict->sh->dirty = 0;
+ dict->sh->write_id++;
dict->sh->last_write = now;
+ write_id = dict->sh->write_id;
+
ngx_rwlock_unlock(&dict->sh->rwlock);
name = dict->state_temp_file.data;
ngx_destroy_pool(pool);
- dict->sh->dirty = 1;
-
- ngx_memory_barrier();
+ dict->write_id = write_id;
/* no lock required */
dict->sh->writing = 0;
expire = entries[i].expire;
if (expire && now >= expire) {
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
continue;
}
if (expire == 0) {
/* treat state without expire as new */
expire = now + dict->timeout;
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
}
} else {
for (dict = jmcf->dicts; dict != NULL; dict = dict->next) {
- if (!dict->sh->dirty || !dict->state_file.data) {
+ if (!dict->state_file.data) {
continue;
}
+ ngx_rwlock_rlock(&dict->sh->rwlock);
+
+ if (dict->write_id < dict->sh->write_id) {
+ ngx_rwlock_unlock(&dict->sh->rwlock);
+ continue;
+ }
+
+ ngx_rwlock_unlock(&dict->sh->rwlock);
+
ngx_add_timer(&dict->save_event, 1000);
}
dict->shpool->data = dict->sh;
dict->sh->last_write = ngx_current_msec;
+ dict->sh->write_id = 1;
ngx_rbtree_init(&dict->sh->rbtree, &dict->sh->sentinel,
ngx_str_rbtree_insert_value);
done:
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
ngx_js_dict_node_free(dict, node);
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
}
}
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);
}
}
- dict->sh->dirty = 1;
+ dict->write_id = dict->sh->write_id;
ngx_rwlock_unlock(&dict->sh->rwlock);