Я хочу записать ключ-значение в постоянном режиме, но когда я хочу использовать 2 или более разных хранилища, это не работает.
Вот мой сценарий:
...
typedef struct{
kv_t *kv;
char *name;
} kv_data;
int main(int argc, char *argv[])
{
kv_data **data = (kv_data**)get_env(argv, US_SERVER_DATA);
if(!data[0]){
data[0] = (kv_data*)calloc(1, sizeof(kv_data));
if(!data[0]){
return 500;
}
kv_t users;
kv_init(&users, "users", 10, 0, 0, 0);
data[0]->kv = &users;
kv_item item;
item.key = "pierre";
item.klen = sizeof("pierre") - 1;
item.val = "[email protected]";
item.flags = 0;
kv_add(data[0]->kv, &item);
data[0]->name = strdup("users");
}
...
Эта ошибка находится в строке 15 с функцией kv_init ().
Я хотел бы, например, использовать data [0] -> kv для чтения и записи значения в магазине "users" и использовать data [1] -> kv для чтения и записи значения в другом хранилище ...
Ответ 1 · рейтинг 1 · Nagi
Я просто присоединяю хранилище kv, которое содержит все необходимые мне хранилища kv, к указателю постоянства. G-WAN kv работает быстро, к тому же количество записей невелико, это не должно сказываться на производительности.
xbuf_t *reply = get_reply(argv);
kv_t **kv_db = (kv_t **)get_env(argv, US_VHOST_DATA);
if (!kv_db[0])
{
kv_db[0] = (kv_t*) malloc(sizeof(kv_t));
if (!kv_db[0])
{
puts("Could not allocate memory for the v-host kv store");
return 500;
}
kv_init(kv_db[0], "kv_db", 10, 0, 0, 0);
}
kv_t *blog_db = (kv_t *) kv_get(kv_db[0], "blog_db", 7);
if (blog_db)
{
xbuf_cat(reply, "Blog already installed. GTFO.");
return 200;
}
blog_db = (kv_t *) malloc(sizeof(kv_t));
kv_init(blog_db, "blog_db", 0, 0, 0, 0);
if (!blog_db)
{
puts("Could not allocate memory for the blog kv store");
return 500;
}
_KV_ADD(kv_db[0], item, blog_db->name, blog_db, 0);
(_KV_ADD - настраиваемый макрос)
Ответ 2 · рейтинг 1 · Gil
Джон,
Ваша проблема связана с трудностью играть с указателями на указатели. Мы могли бы исправить этот код, но он, вероятно, сломается позже в ваших скриптах из-за своей сложности.
В долгосрочной перспективе следует использовать более простое решение, чтобы избежать ошибок.
Структуру, прикрепленную к US_SERVER_DATA, можно сделать проще:
typedef struct
{
char *name;
kv_t *kv_1;
kv_t *kv_2;
void *callback;
u32 current_time;
}
Это правильный путь: выделите память с помощью calloc(sizeof(my_struct)); и прикрепите эту структуру к вашему указателю US_SERVER_DATA.
Затем, если вы делаете все это в вызове init() обработчика G-WAN (или в gwan/main.c сценарии обслуживания, или даже в недавно добавленном gwan/init.c сценарии), у вас будет монопольный доступ (инициализация выполняется одним потоком), и вы получите иметь возможность атаковать магазины G-WAN KV (и другие объекты) по мере необходимости.
Если позже сервлеты или обработчики G-WAN изменяют эти указатели на структуру, вам придется использовать блокировку, спин-блокировку и т. Д. Или атомарные переменные для самих указателей.
Надеюсь это поможет.