[Top][All Lists]
[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,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r21754 - in gnunet-fuse: . src/fuse,
gnunet <=