[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r19148 - gnunet/src/fs
From: |
gnunet |
Subject: |
[GNUnet-SVN] r19148 - gnunet/src/fs |
Date: |
Sun, 15 Jan 2012 00:18:52 +0100 |
Author: grothoff
Date: 2012-01-15 00:18:52 +0100 (Sun, 15 Jan 2012)
New Revision: 19148
Modified:
gnunet/src/fs/fs_dirmetascan.c
Log:
-LRN: use signal pipe instead of a semaphore
Modified: gnunet/src/fs/fs_dirmetascan.c
===================================================================
--- gnunet/src/fs/fs_dirmetascan.c 2012-01-14 23:18:23 UTC (rev 19147)
+++ gnunet/src/fs/fs_dirmetascan.c 2012-01-14 23:18:52 UTC (rev 19148)
@@ -102,20 +102,38 @@
struct MetaCounter *next;
};
+struct AddDirContext;
+
/**
+ * A structure used to hold a pointer to the tree item that is being
+ * processed.
+ * Needed to avoid changing the context for every recursive call.
+ */
+struct AddDirStack
+{
+ /**
+ * Context pointer
+ */
+ struct AddDirContext *adc;
+
+ /**
+ * Parent directory
+ */
+ struct ShareTreeItem *parent;
+};
+
+/**
* Execution context for 'add_dir'
* Owned by the initiator thread.
*/
struct AddDirContext
{
/**
- * Parent directory (used to access keyword and metadata counters,
- * and the like).
* After the scan is finished, it will contain a pointer to the
* top-level directory entry in the directory tree built by the
* scanner.
*/
- struct ShareTreeItem *parent;
+ struct ShareTreeItem *toplevel;
/**
* Expanded filename (as given by the scan initiator).
@@ -124,15 +142,10 @@
char *filename_expanded;
/**
- * A synchronization privitive. Whenever its state is altered,
- * it means that the initiator wants the scanner to wrap up.
- * It is owned by the initiator thread.
+ * A pipe end to read signals from.
+ * Owned by the initiator thread.
*/
-#if WINDOWS
- HANDLE stop;
-#else
- sem_t *stop;
-#endif
+ const struct GNUNET_DISK_FileHandle *stop_read;
/**
* 1 if the scanner should stop, 0 otherwise. Set in response
@@ -164,15 +177,17 @@
*/
struct GNUNET_FS_DirScanner
{
- /**
- * A synchronization privitive that is used to signal the scanner to stop.
- * Owned by the initiator thread.
- */
-#if WINDOWS
- HANDLE stop;
-#else
- sem_t *stop;
-#endif
+ /**
+ * A pipe end to read signals from.
+ * Owned by the initiator thread.
+ */
+ const struct GNUNET_DISK_FileHandle *stop_write;
+
+ /**
+ * A pipe transfer signals to the scanner.
+ * Owned by the initiator thread.
+ */
+ struct GNUNET_DISK_PipeHandle *stop_pipe;
/**
* A thread object for the scanner thread.
@@ -312,21 +327,14 @@
static int
should_stop (struct AddDirContext *adc)
{
-#if WINDOWS
- if (WaitForSingleObject (adc->stop, 0) == WAIT_TIMEOUT)
- return 0;
- adc->do_stop = 1;
- return 1;
-#else
- int value;
- sem_getvalue(adc->stop, &value);
- if (value > 0)
+ errno = 0;
+ char c;
+ if (GNUNET_DISK_file_read_non_blocking (adc->stop_read, &c, 1) == 1
+ || errno != EAGAIN)
{
adc->do_stop = 1;
- return 1;
}
- return 0;
-#endif
+ return adc->do_stop;
}
/**
@@ -535,19 +543,19 @@
* @param filename name of the file to process
*/
static void
-extract_file (struct AddDirContext *adc, const char *filename)
+extract_file (struct AddDirStack *ads, const char *filename)
{
struct ShareTreeItem *item;
const char *short_fn;
- item = make_item (adc->parent);
+ item = make_item (ads->parent);
GNUNET_DISK_file_size (filename, &item->file_size, GNUNET_YES);
item->is_directory = GNUNET_NO;
item->meta = GNUNET_CONTAINER_meta_data_create ();
GNUNET_FS_meta_data_extract_from_file (item->meta, filename,
- adc->plugins);
+ ads->adc->plugins);
GNUNET_CONTAINER_meta_data_delete (item->meta, EXTRACTOR_METATYPE_FILENAME,
NULL, 0);
short_fn = GNUNET_STRINGS_get_short_name (filename);
@@ -725,13 +733,14 @@
* scan.
* TODO: find a way to make it non-recursive.
*
- * @param cls the 'struct AddDirContext*' we're in
+ * @param cls the 'struct AddDirStack *' we're in
* @param filename file or directory to scan
*/
static int
scan_directory (void *cls, const char *filename)
{
- struct AddDirContext *adc = cls, recurse_adc;
+ struct AddDirStack *ads = cls, recurse_ads;
+ struct AddDirContext *adc = ads->adc;
struct stat sbuf;
struct ShareTreeItem *item;
const char *short_fn;
@@ -763,33 +772,31 @@
}
if (!S_ISDIR (sbuf.st_mode))
- extract_file (adc, filename);
+ extract_file (ads, filename);
else
{
- item = make_item (adc->parent);
+ item = make_item (ads->parent);
item->meta = GNUNET_CONTAINER_meta_data_create ();
item->is_directory = GNUNET_YES;
- /* copy fields from adc */
- recurse_adc = *adc;
- /* replace recurse_adc contents with the ones for this directory */
- recurse_adc.parent = item;
+ recurse_ads.adc = adc;
+ recurse_ads.parent = item;
/* recurse into directory */
- GNUNET_DISK_directory_scan (filename, &scan_directory, &recurse_adc);
+ GNUNET_DISK_directory_scan (filename, &scan_directory, &recurse_ads);
short_fn = GNUNET_STRINGS_get_short_name (filename);
item->filename = GNUNET_strdup (filename);
item->short_filename = GNUNET_strdup (short_fn);
- if (adc->parent == NULL)
+ if (ads->parent == NULL)
{
/* we're finished with the scan, make sure caller gets the top-level
* directory pointer
*/
- adc->parent = item;
+ adc->toplevel = item;
}
}
return GNUNET_OK;
@@ -809,11 +816,9 @@
GNUNET_FS_directory_scan_finish (struct GNUNET_FS_DirScanner *ds,
int close_pipe)
{
-#if WINDOWS
- SetEvent (ds->stop);
-#else
- sem_post (&ds->stop);
-#endif
+ char c = 1;
+ GNUNET_DISK_file_write (ds->stop_write, &c, 1);
+
if (close_pipe)
{
if (ds->progress_read_task != GNUNET_SCHEDULER_NO_TASK)
@@ -845,16 +850,15 @@
GNUNET_FS_directory_scan_finish (ds, GNUNET_YES);
#if WINDOWS
WaitForSingleObject (ds->thread, INFINITE);
- CloseHandle (ds->stop);
CloseHandle (ds->thread);
#else
pthread_join (ds->thread, NULL);
- sem_destroy (&ds->stop);
pthread_detach (ds->thread);
#endif
+ GNUNET_DISK_pipe_close (ds->stop_pipe);
GNUNET_DISK_pipe_close (ds->progress_pipe);
- result = ds->adc->parent;
+ result = ds->adc->toplevel;
GNUNET_free (ds->adc);
GNUNET_free (ds);
return result;
@@ -870,7 +874,10 @@
#endif
run_directory_scan_thread (struct AddDirContext *adc)
{
- scan_directory (adc, adc->filename_expanded);
+ struct AddDirStack ads;
+ ads.adc = adc;
+ ads.parent = NULL;
+ scan_directory (&ads, adc->filename_expanded);
GNUNET_free (adc->filename_expanded);
if (adc->plugins != NULL)
EXTRACTOR_plugin_remove_all (adc->plugins);
@@ -1060,15 +1067,8 @@
ds->adc = adc;
-#if WINDOWS
- ds->stop = CreateEvent (NULL, TRUE, FALSE, NULL);
- adc->stop = ds->stop;
- ok = ds->stop != INVALID_HANDLE_VALUE;
-#else
- ok = !sem_init (&ds->stop, 0, 0);
- adc = &ds->stop;
-#endif
- if (!ok)
+ ds->stop_pipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO,
GNUNET_NO);
+ if (ds->stop_pipe == NULL)
{
GNUNET_free (adc);
GNUNET_free (ds);
@@ -1076,6 +1076,10 @@
GNUNET_DISK_pipe_close (progress_pipe);
return NULL;
}
+ ds->stop_write = GNUNET_DISK_pipe_handle (ds->stop_pipe,
+ GNUNET_DISK_PIPE_END_WRITE);
+ adc->stop_read = GNUNET_DISK_pipe_handle (ds->stop_pipe,
+ GNUNET_DISK_PIPE_END_READ);
adc->plugins = NULL;
if (!disable_extractor)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r19148 - gnunet/src/fs,
gnunet <=