Kouhei Sutou
null+****@clear*****
Wed Apr 12 11:43:18 JST 2017
Kouhei Sutou 2017-04-12 11:43:18 +0900 (Wed, 12 Apr 2017) New Revision: 9e7db4374d2b0bec27d443cdca8d35ceb86d23ad https://github.com/groonga/groonga/commit/9e7db4374d2b0bec27d443cdca8d35ceb86d23ad Message: cache persistent: support opening from multi processes TODO: * Support Windows Added files: lib/file_lock.c lib/grn_file_lock.h Modified files: lib/cache.c lib/sources.am Modified: lib/cache.c (+27 -6) =================================================================== --- lib/cache.c 2017-04-12 11:43:18 +0900 (2f9d5c5) +++ lib/cache.c 2017-04-12 11:43:18 +0900 (2f38995) @@ -23,6 +23,7 @@ #include "grn_pat.h" #include "grn_store.h" #include "grn_db.h" +#include "grn_file_lock.h" #include <sys/stat.h> @@ -140,11 +141,22 @@ grn_cache_open_persistent(grn_ctx *ctx, grn_cache *cache, const char *base_path) { + grn_file_lock file_lock; char *keys_path = NULL; char *values_path = NULL; + char lock_path_buffer[PATH_MAX]; char keys_path_buffer[PATH_MAX]; char values_path_buffer[PATH_MAX]; + cache->impl.persistent.timeout = 1000; + + if (base_path) { + grn_snprintf(lock_path_buffer, PATH_MAX, PATH_MAX, "%s.lock", base_path); + grn_file_lock_init(ctx, &file_lock, lock_path_buffer); + } else { + grn_file_lock_init(ctx, &file_lock, NULL); + } + if (base_path) { struct stat stat_buffer; @@ -153,6 +165,13 @@ grn_cache_open_persistent(grn_ctx *ctx, keys_path = keys_path_buffer; values_path = values_path_buffer; + if (!grn_file_lock_acquire(ctx, + &file_lock, + cache->impl.persistent.timeout, + "[cache][persistent][open]")) { + goto exit; + } + if (stat(keys_path, &stat_buffer) == 0) { cache->impl.persistent.keys = grn_hash_open(ctx, keys_path); if (cache->impl.persistent.keys) { @@ -169,7 +188,7 @@ grn_cache_open_persistent(grn_ctx *ctx, ERRNO_ERR("[cache][persistent] " "failed to remove path for cache keys: <%s>", keys_path); - return; + goto exit; } } if (stat(values_path, &stat_buffer) == 0) { @@ -177,7 +196,7 @@ grn_cache_open_persistent(grn_ctx *ctx, ERRNO_ERR("[cache][persistent] " "failed to remove path for cache values: <%s>", values_path); - return; + goto exit; } } } @@ -194,7 +213,7 @@ grn_cache_open_persistent(grn_ctx *ctx, ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc, "[cache][persistent] failed to create cache keys storage: <%s>", keys_path ? keys_path : "(memory)"); - return; + goto exit; } cache->impl.persistent.values = grn_ja_create(ctx, @@ -206,7 +225,7 @@ grn_cache_open_persistent(grn_ctx *ctx, ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc, "[cache][persistent] failed to create cache values storage: <%s>", values_path ? values_path : "(memory)"); - return; + goto exit; } } @@ -267,7 +286,7 @@ grn_cache_open_persistent(grn_ctx *ctx, ERR(ctx->rc == GRN_SUCCESS ? GRN_FILE_CORRUPT : ctx->rc, "[cache][persistent] broken cache keys storage: broken metadata: <%s>", keys_path ? keys_path : "(memory)"); - return; + goto exit; } if (added) { @@ -277,7 +296,9 @@ grn_cache_open_persistent(grn_ctx *ctx, } } - cache->impl.persistent.timeout = 1000; +exit : + grn_file_lock_release(ctx, &file_lock); + grn_file_lock_fin(ctx, &file_lock); } static grn_cache * Added: lib/file_lock.c (+83 -0) 100644 =================================================================== --- /dev/null +++ lib/file_lock.c 2017-04-12 11:43:18 +0900 (3e4d486) @@ -0,0 +1,83 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2017 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "grn_file_lock.h" +#include "grn_ctx.h" + +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> + +void +grn_file_lock_init(grn_ctx *ctx, + grn_file_lock *file_lock, + const char *path) +{ + file_lock->path = path; + file_lock->fd = -1; +} + +grn_bool +grn_file_lock_acquire(grn_ctx *ctx, + grn_file_lock *file_lock, + int timeout, + const char *error_message_tag) +{ + int i; + int n_lock_tries = timeout; + + if (!file_lock->path) { + return GRN_TRUE; + } + + for (i = 0; i < n_lock_tries; i++) { + file_lock->fd = open(file_lock->path, O_CREAT | O_EXCL); + if (file_lock->fd != -1) { + break; + } + grn_nanosleep(GRN_LOCK_WAIT_TIME_NANOSECOND); + } + + if (file_lock->fd == -1) { + ERR(GRN_NO_LOCKS_AVAILABLE, + "%s failed to acquire lock: <%s>", + error_message_tag, file_lock->path); + return GRN_FALSE; + } else { + return GRN_TRUE; + } +} + +void +grn_file_lock_release(grn_ctx *ctx, grn_file_lock *file_lock) +{ + if (file_lock->fd == -1) { + return; + } + + close(file_lock->fd); + unlink(file_lock->path); +} + +void +grn_file_lock_fin(grn_ctx *ctx, grn_file_lock *file_lock) +{ + if (file_lock->fd != -1) { + grn_file_lock_release(ctx, file_lock); + } +} Added: lib/grn_file_lock.h (+44 -0) 100644 =================================================================== --- /dev/null +++ lib/grn_file_lock.h 2017-04-12 11:43:18 +0900 (c99876f) @@ -0,0 +1,44 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2017 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include "grn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + const char *path; + int fd; +} grn_file_lock; + +void grn_file_lock_init(grn_ctx *ctx, + grn_file_lock *file_lock, + const char *path); +grn_bool grn_file_lock_acquire(grn_ctx *ctx, + grn_file_lock *file_lock, + int timeout, + const char *error_message_tag); +void grn_file_lock_release(grn_ctx *ctx, grn_file_lock *file_lock); +void grn_file_lock_fin(grn_ctx *ctx, grn_file_lock *file_lock); + +#ifdef __cplusplus +} +#endif Modified: lib/sources.am (+2 -0) =================================================================== --- lib/sources.am 2017-04-12 11:43:18 +0900 (bd3710e) +++ lib/sources.am 2017-04-12 11:43:18 +0900 (02868a0) @@ -30,6 +30,8 @@ libgroonga_la_SOURCES = \ grn_expr_code.h \ expr_executor.c \ grn_expr_executor.h \ + file_lock.c \ + grn_file_lock.h \ geo.c \ grn_geo.h \ grn.h \ -------------- next part -------------- HTML����������������������������...Télécharger