gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r21754 - in gnunet-fuse: . src/fuse


From: gnunet
Subject: [GNUnet-SVN] r21754 - in gnunet-fuse: . src/fuse
Date: Mon, 4 Jun 2012 14:13:15 +0200

Author: grothoff
Date: 2012-06-04 14:13:15 +0200 (Mon, 04 Jun 2012)
New Revision: 21754

Added:
   gnunet-fuse/src/fuse/mutex.c
   gnunet-fuse/src/fuse/mutex.h
Modified:
   gnunet-fuse/INSTALL
   gnunet-fuse/src/fuse/Makefile.am
   gnunet-fuse/src/fuse/gnunet-fuse.c
   gnunet-fuse/src/fuse/gnunet-fuse.h
   gnunet-fuse/src/fuse/readdir.c
Log:
-locking

Modified: gnunet-fuse/INSTALL
===================================================================
--- gnunet-fuse/INSTALL 2012-06-04 11:09:46 UTC (rev 21753)
+++ gnunet-fuse/INSTALL 2012-06-04 12:13:15 UTC (rev 21754)
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
+Inc.
 
    Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
@@ -226,6 +226,11 @@
 
 and if that doesn't work, install pre-built binaries of GCC for HP-UX.
 
+   HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved.  Use GNU `make'
+instead.
+
    On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
 parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
 a workaround.  If GNU CC is not installed, it is therefore recommended

Modified: gnunet-fuse/src/fuse/Makefile.am
===================================================================
--- gnunet-fuse/src/fuse/Makefile.am    2012-06-04 11:09:46 UTC (rev 21753)
+++ gnunet-fuse/src/fuse/Makefile.am    2012-06-04 12:13:15 UTC (rev 21754)
@@ -9,8 +9,9 @@
 bin_PROGRAMS = gnunet-fuse
 
 gnunet_fuse_SOURCES = \
+  gnunet-fuse.c \
+  mutex.c mutex.h \
        mkdir.c \
-       gnunet-fuse.c \
        mknod.c \
        release.c \
        rename.c \

Modified: gnunet-fuse/src/fuse/gnunet-fuse.c
===================================================================
--- gnunet-fuse/src/fuse/gnunet-fuse.c  2012-06-04 11:09:46 UTC (rev 21753)
+++ gnunet-fuse/src/fuse/gnunet-fuse.c  2012-06-04 12:13:15 UTC (rev 21754)
@@ -51,22 +51,64 @@
  * Global mapping of paths to GNUnet URIs (and file names) for
  * the respective entries.
  */
-struct GNUNET_CONTAINER_MultiHashMap *map;
+static struct GNUNET_CONTAINER_MultiHashMap *map;
 
+/**
+ * Mutex for synchronizing access to 'map'.
+ */
+static struct GNUNET_Mutex *map_mutex;
 
+
+/**
+ * Obtain an existing path info entry from the global map.
+ *
+ * @param path path the entry represents
+ * @return NULL if no such path entry exists
+ */
 struct GNUNET_FUSE_PathInfo *
-create_path_info (const char *path, const struct GNUNET_FS_Uri *uri)
+GNUNET_FUSE_get_path_info (const char *path)
 {
   struct GNUNET_FUSE_PathInfo *pi;
   GNUNET_HashCode path_hash;
 
   GNUNET_CRYPTO_hash (path, strlen (path), &path_hash);
+  GNUNET_mutex_lock (map_mutex);
   pi = GNUNET_CONTAINER_multihashmap_get (map, &path_hash);
+  ++pi->rc;
+  GNUNET_mutex_unlock (map_mutex);
+  return pi;  
+}
+
+
+/**
+ * Create a new path info entry in the global map.
+ *
+ * @param path path the entry represents
+ * @param uri URI to use for the path
+ * @return existing path entry if one already exists, otherwise
+ *         new path entry with the desired URI
+ */
+struct GNUNET_FUSE_PathInfo *
+GNUNET_FUSE_path_info_create (const char *path, 
+                             const struct GNUNET_FS_Uri *uri,
+                             int is_directory)
+{
+  struct GNUNET_FUSE_PathInfo *pi;
+  GNUNET_HashCode path_hash;
+
+  GNUNET_CRYPTO_hash (path, strlen (path), &path_hash);
+  GNUNET_mutex_lock (map_mutex);
+  pi = GNUNET_CONTAINER_multihashmap_get (map, &path_hash);
   if (NULL != pi)
+  {
+    GNUNET_mutex_unlock (map_mutex);
     return pi;
+  }
   pi = GNUNET_malloc (sizeof (struct GNUNET_FUSE_PathInfo));
   pi->path = GNUNET_strdup (path);
   pi->uri = GNUNET_FS_uri_dup (uri);
+  pi->lock = GNUNET_mutex_create (GNUNET_YES);
+  pi->rc = 1;
   GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map,
                                                                 &path_hash,
                                                                 pi,
@@ -75,25 +117,71 @@
   pi->stbuf.st_blocks = 1 + ((pi->stbuf.st_size) / 512);
   pi->stbuf.st_blksize = 32 * 1024;
   pi->stbuf.st_mode = (S_IRUSR | S_IRGRP | S_IROTH); /* read-only */
-  if (0) /* FIXME: test for directory... */
+  if (GNUNET_YES == is_directory)
     pi->stbuf.st_mode |= (S_IXUSR | S_IXGRP | S_IXOTH); /* allow traversal */
   pi->stbuf.st_mode |= S_IFREG; /* regular file */
+  GNUNET_mutex_unlock (map_mutex);
   return pi;
 }
 
 
+/**
+ * Reduce the reference counter of a path info entry.
+ *
+ * @param pi entry to decrement the RC of
+ */
 void
-delete_path_info (struct GNUNET_FUSE_PathInfo *pi)
+GNUNET_FUSE_path_info_done (struct GNUNET_FUSE_PathInfo *pi)
 {
-  if (NULL != pi->tmpfile)
+  if (GNUNET_YES == pi->delete_later)
   {
-    GNUNET_break (0 == UNLINK (pi->tmpfile));
-    GNUNET_free (pi->tmpfile);
+    (void) GNUNET_FUSE_path_info_delete (pi);
+    return;
   }
-  GNUNET_free (pi->path);
-  GNUNET_FS_uri_destroy (pi->uri);
-  GNUNET_free (pi);
+  GNUNET_mutex_lock (map_mutex);
+  --pi->rc;
+  GNUNET_mutex_unlock (map_mutex);  
+}
 
+
+/**
+ * Delete a path info entry from the global map (does not actually
+ * remove anything from the file system).  Also decrements the RC.
+ *
+ * @param pi entry to remove
+ * @return - ENOENT if the file was already deleted, 0 on success
+ */
+int
+GNUNET_FUSE_path_info_delete (struct GNUNET_FUSE_PathInfo *pi)
+{
+  GNUNET_HashCode path_hash;
+  int ret;
+  int rc;
+
+  GNUNET_CRYPTO_hash (pi->path, strlen (pi->path), &path_hash);
+  GNUNET_mutex_lock (map_mutex);
+  ret = GNUNET_CONTAINER_multihashmap_remove (map, &path_hash, pi);
+  rc = --pi->rc;
+  GNUNET_mutex_unlock (map_mutex);
+  if (0 != rc)
+  {
+    pi->delete_later = GNUNET_YES;
+  }
+  else
+  {
+    if (NULL != pi->tmpfile)
+    {
+      GNUNET_break (0 == UNLINK (pi->tmpfile));
+      GNUNET_free (pi->tmpfile);
+    }
+    GNUNET_free (pi->path);
+    GNUNET_FS_uri_destroy (pi->uri);
+    GNUNET_mutex_destroy (pi->lock);
+    GNUNET_free (pi);
+  }
+  if (GNUNET_YES == ret)
+    return 0;
+  return - ENOENT;
 }
 
 
@@ -110,7 +198,8 @@
 {
   struct GNUNET_FUSE_PathInfo *pi = value;
 
-  delete_path_info (pi);
+  ++pi->rc;
+  (void) GNUNET_FUSE_path_info_delete (pi);
   return GNUNET_YES;
 }
 
@@ -148,6 +237,7 @@
   struct GNUNET_FS_Uri *uri;
   char *emsg;
   const char *path = "/";
+  struct GNUNET_FUSE_PathInfo *pi;
 
   ret = 0;
   if (NULL == source)
@@ -172,8 +262,9 @@
       return;
     }
 
+  map_mutex = GNUNET_mutex_create (GNUNET_NO);
   map = GNUNET_CONTAINER_multihashmap_create (1024);
-  (void) create_path_info (path, uri);
+  pi = GNUNET_FUSE_path_info_create (path, uri, GNUNET_YES);
 
   if (GNUNET_YES == single_threaded)
     argc = 5;
@@ -192,8 +283,12 @@
     a[argc] = NULL;
     fuse_main (argc, a, &fops, NULL);
   }
+  GNUNET_FUSE_path_info_done (pi);
   GNUNET_CONTAINER_multihashmap_iterate (map, &cleanup_path_info, NULL);
   GNUNET_CONTAINER_multihashmap_destroy (map);
+  map = NULL;
+  GNUNET_mutex_destroy (map_mutex);
+  map_mutex = NULL;
   GNUNET_FS_uri_destroy (uri);
 }
 

Modified: gnunet-fuse/src/fuse/gnunet-fuse.h
===================================================================
--- gnunet-fuse/src/fuse/gnunet-fuse.h  2012-06-04 11:09:46 UTC (rev 21753)
+++ gnunet-fuse/src/fuse/gnunet-fuse.h  2012-06-04 12:13:15 UTC (rev 21754)
@@ -33,16 +33,10 @@
 
 #define FUSE_USE_VERSION 26
 #include <fuse.h>
+#include "mutex.h"
 
 
 /**
- * Global mapping of paths to GNUnet URIs (and file names) for
- * the respective entries.
- */
-extern struct GNUNET_CONTAINER_MultiHashMap *map;
-
-
-/**
  * struct containing mapped Path, with URI and other Information like 
Attributes etc. 
  */
 struct GNUNET_FUSE_PathInfo
@@ -66,17 +60,71 @@
    * file attributes
    */
   struct stat stbuf;
+  
+  /**
+   * Lock for exclusive access to this struct.
+   */ 
+  struct GNUNET_Mutex *lock;
+
+  /**
+   * Reference counter.
+   */
+  unsigned int rc;
+
+  /**
+   * Should the file be deleted after the RC hits zero?
+   */
+  int delete_later;
 };
 
 
+/**
+ * Create a new path info entry in the global map.
+ *
+ * @param path path the entry represents
+ * @param uri URI to use for the path
+ * @param is_directory GNUNET_YES if this entry is for a directory
+ * @return existing path entry if one already exists, otherwise
+ *         new path entry with the desired URI; in both cases
+ *         the reference counter has been incremented by 1
+ */
 struct GNUNET_FUSE_PathInfo *
-create_path_info (const char *path, const struct GNUNET_FS_Uri *uri);
+GNUNET_FUSE_path_info_create (const char *path,
+                             const struct GNUNET_FS_Uri *uri,
+                             int is_directory);
 
 
+/**
+ * Obtain an existing path info entry from the global map.
+ *
+ * @param path path the entry represents
+ * @return NULL if no such path entry exists, otherwise
+ *  an entry with incremented reference counter (!)
+ */
+struct GNUNET_FUSE_PathInfo *
+GNUNET_FUSE_path_info_get (const char *path);
+
+
+/**
+ * Reduce the reference counter of a path info entry.
+ *
+ * @param pi entry to decrement the RC of
+ */
 void
-delete_path_info (struct GNUNET_FUSE_PathInfo *pi);
+GNUNET_FUSE_path_info_done (struct GNUNET_FUSE_PathInfo *pi);
 
 
+/**
+ * Delete a path info entry from the global map (does not actually
+ * remove anything from the file system).  Also decrements the RC.
+ *
+ * @param pi entry to remove
+ * @return - ENOENT if the file was already deleted, 0 on success
+ */
+int
+GNUNET_FUSE_path_info_delete (struct GNUNET_FUSE_PathInfo *pi);
+
+
 /* FUSE function files */
 int gn_getattr(const char *path, struct stat *stbuf);
 

Added: gnunet-fuse/src/fuse/mutex.c
===================================================================
--- gnunet-fuse/src/fuse/mutex.c                                (rev 0)
+++ gnunet-fuse/src/fuse/mutex.c        2012-06-04 12:13:15 UTC (rev 21754)
@@ -0,0 +1,130 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004, 2012 Christian Grothoff (and other 
contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet 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
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file src/fuse/mutex.c
+ * @brief implementation of mutual exclusion
+ */
+#include "gnunet-fuse.h"
+#include "mutex.h"
+
+#include <pthread.h>
+#if SOMEBSD
+# include <pthread_np.h>
+#endif
+
+#ifndef PTHREAD_MUTEX_NORMAL
+#ifdef PTHREAD_MUTEX_TIMED_NP
+#define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
+#else
+#define PTHREAD_MUTEX_NORMAL NULL
+#endif
+#endif
+
+/**
+ * This prototype is somehow missing in various Linux pthread
+ * include files. But we need it and it seems to be available
+ * on all pthread-systems so far. Odd.
+ */
+#ifndef _MSC_VER
+extern int pthread_mutexattr_setkind_np (pthread_mutexattr_t * attr,
+                                         int kind);
+#endif
+
+
+/**
+ * @brief Structure for MUTual EXclusion (Mutex).
+ */
+struct GNUNET_Mutex
+{
+  pthread_mutex_t pt;
+};
+
+
+struct GNUNET_Mutex *
+GNUNET_mutex_create (int isRecursive)
+{
+  pthread_mutexattr_t attr;
+  struct GNUNET_Mutex *mut;
+#if WINDOWS
+  attr = NULL;
+#endif
+
+  pthread_mutexattr_init (&attr);
+  if (isRecursive)
+    {
+#if LINUX
+      GNUNET_assert (0 == pthread_mutexattr_setkind_np
+                    (&attr, PTHREAD_MUTEX_RECURSIVE_NP));
+#elif SOMEBSD || GNUNET_freeBSD || GNUNET_freeBSD5
+      GNUNET_assert (0 == pthread_mutexattr_setkind_np
+                    (&attr, PTHREAD_MUTEX_RECURSIVE));
+#elif SOLARIS || OSX || WINDOWS
+      GNUNET_assert (0 == pthread_mutexattr_settype
+                    (&attr, PTHREAD_MUTEX_RECURSIVE));
+#endif
+    }
+  else
+    {
+#if LINUX
+      GNUNET_assert (0 == pthread_mutexattr_setkind_np
+                    (&attr, PTHREAD_MUTEX_ERRORCHECK_NP));
+#else
+      GNUNET_assert (0 == pthread_mutexattr_settype
+                    (&attr, PTHREAD_MUTEX_ERRORCHECK));
+#endif
+    }
+  mut = GNUNET_malloc (sizeof (struct GNUNET_Mutex));
+  GNUNET_assert (0 == pthread_mutex_init (&mut->pt, &attr));
+  return mut;
+}
+
+
+void
+GNUNET_mutex_destroy (struct GNUNET_Mutex * mutex)
+{
+  GNUNET_assert (0 == pthread_mutex_destroy (&mutex->pt));
+  GNUNET_free (mutex);
+}
+
+
+void
+GNUNET_mutex_lock (struct GNUNET_Mutex * mutex)
+{
+  if (0 != (errno = pthread_mutex_lock (&mutex->pt)))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pthread_mutex_unlock");  
+    GNUNET_assert (0);
+  }
+}
+
+
+void
+GNUNET_mutex_unlock (struct GNUNET_Mutex * mutex)
+{
+  if (0 != (errno = pthread_mutex_unlock (&mutex->pt)))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pthread_mutex_unlock");  
+    GNUNET_assert (0);
+  }
+}
+
+
+/* end of mutex.c */

Added: gnunet-fuse/src/fuse/mutex.h
===================================================================
--- gnunet-fuse/src/fuse/mutex.h                                (rev 0)
+++ gnunet-fuse/src/fuse/mutex.h        2012-06-04 12:13:15 UTC (rev 21754)
@@ -0,0 +1,75 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2012 Christian Grothoff 
(and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet 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
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file src/fuse/mutex.h
+ * @brief pthreads wapper and thread related services
+ *
+ * @author Christian Grothoff
+ * @author Krista Bennett
+ * @author Gerd Knorr <address@hidden>
+ * @author Ioana Patrascu
+ * @author Tzvetan Horozov
+ */
+
+#ifndef MUTEX_H
+#define MUTEX_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0                           /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+
+/**
+ * @brief Structure for MUTual EXclusion (Mutex).
+ */
+struct GNUNET_Mutex;
+
+
+struct GNUNET_Mutex *
+GNUNET_mutex_create (int isRecursive);
+
+
+void 
+GNUNET_mutex_destroy (struct GNUNET_Mutex *mutex);
+
+
+void 
+GNUNET_mutex_lock (struct GNUNET_Mutex *mutex);
+
+
+void 
+GNUNET_mutex_unlock (struct GNUNET_Mutex *mutex);
+
+
+#if 0                           /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* ifndef MUTEX_H */
+#endif
+/* end of mutex.h */

Modified: gnunet-fuse/src/fuse/readdir.c
===================================================================
--- gnunet-fuse/src/fuse/readdir.c      2012-06-04 11:09:46 UTC (rev 21753)
+++ gnunet-fuse/src/fuse/readdir.c      2012-06-04 12:13:15 UTC (rev 21754)
@@ -296,12 +296,16 @@
   struct DepContext *dc = cls;
   struct GNUNET_FUSE_PathInfo *pi;
   char *path;
+  int is_directory;
 
   GNUNET_asprintf (&path,
                   "%s/%s",
                   dc->path,
                   filename);
-  pi = create_path_info (path, uri);  
+  is_directory = GNUNET_FS_meta_data_test_for_directory (meta);
+  if (GNUNET_SYSERR == is_directory)
+    is_directory = GNUNET_NO; /* if in doubt, say no */
+  pi = GNUNET_FUSE_path_info_create (path, uri, is_directory);  
   dc->filler (dc->buf,
              filename, 
              &pi->stbuf,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]