[Groonga-commit] groonga/groonga at 9e7db43 [master] cache persistent: support opening from multi processes

Back to archive index

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����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index