Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface

  essentially convolver-filesystem.h ad provide class ConvolverFilesystem.
o Start status server. Needs to be filled.
  • Loading branch information...
commit 8d1fbe7c330b5d505e7996d44d2704c4f8735a0a 1 parent 680f590
@hzeller authored
View
6 Makefile
@@ -1,10 +1,10 @@
CC=gcc
CXX=g++
-CFLAGS=-D_FILE_OFFSET_BITS=64 -Wall -g -O2
+CFLAGS=-D_FILE_OFFSET_BITS=64 -Wall -g -O0
CXXFLAGS=$(CFLAGS)
-LDFLAGS=-lfuse -lsndfile -lzita-convolver
+LDFLAGS=-lfuse -lsndfile -lzita-convolver -lmicrohttpd
-fuse-convolve: fuse-convolve.o convolver.o conversion-buffer.o zita-audiofile.o zita-config.o zita-fconfig.o zita-sstring.o file-handler-cache.o
+fuse-convolve: fuse-convolve.o convolver.o conversion-buffer.o zita-audiofile.o zita-config.o zita-fconfig.o zita-sstring.o file-handler-cache.o status-server.o
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
clean:
View
2  README
@@ -4,7 +4,7 @@ and provides these files that are convolved on the fly using the zita convolver
=== To compile on Ubuntu ===
- $ sudo aptitude install libsndfile-dev libflac-dev libzita-convolver-dev libfuse-dev fftw3-dev libboost-dev
+ $ sudo aptitude install libsndfile-dev libflac-dev libzita-convolver-dev libfuse-dev fftw3-dev libboost-dev libmicrohttpd-dev
$ make
=== Run ===
View
48 convolver-filesystem.h
@@ -0,0 +1,48 @@
+// -*- c++ -*-
+// Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef _FUSE_CONVOLVER_FILESYSTEM_H
+#define _FUSE_CONVOLVER_FILESYSTEM_H
+
+#include <unistd.h>
+
+#include "file-handler.h"
+#include "file-handler-cache.h"
+
+class ConvolverFilesystem {
+public:
+ ConvolverFilesystem(const char *zita_config_dir,
+ int cache_size);
+
+ FileHandlerCache *handler_cache() { return &open_files_; }
+
+ // Create a new filter given the open filedescriptor and the path.
+ // Returns NULL, if it cannot be created.
+ FileHandler *CreateHandler(const char *fs_path,
+ const char *underlying_path);
+
+ // Return dynamic size of file.
+ int StatByFilename(const char *fs_path, struct stat *st);
+
+ // At the end of the operation, close filter. Return 0 on success or negative
+ // errno value on failure.
+ void Close(const char *fs_path);
+
+private:
+ FileHandlerCache open_files_;
+};
+
+#endif // _FUSE_CONVOLVER_FILESYSTEM_H
View
26 convolver.cc
@@ -29,7 +29,7 @@
#include "file-handler.h"
#include "file-handler-cache.h"
-#include "filter-interface.h"
+#include "convolver-filesystem.h"
#include "conversion-buffer.h"
#include "zita-config.h"
@@ -404,7 +404,7 @@ class SndFileHandler :
static FileHandlerCache open_files_(1);
static FileHandler *CreateFilterFromFileType(int filedes,
- const char *underlying_file) {
+ const char *underlying_file) {
FileHandler *filter = SndFileHandler::Create(filedes, underlying_file);
if (filter != NULL) return filter;
@@ -414,8 +414,8 @@ static FileHandler *CreateFilterFromFileType(int filedes,
}
// Implementation of the C functions in filter-interface.h
-struct filter_object_t *create_filter(const char *fs_path,
- const char *underlying_path) {
+FileHandler *ConvolverFilesystem::CreateHandler(const char *fs_path,
+ const char *underlying_path) {
FileHandler *handler = open_files_.FindAndPin(fs_path);
if (handler == NULL) {
int filedes = open(underlying_path, O_RDONLY);
@@ -427,12 +427,7 @@ struct filter_object_t *create_filter(const char *fs_path,
return handler;
}
-int read_from_filter(struct filter_object_t *filter,
- char *buf, size_t size, off_t offset) {
- return reinterpret_cast<FileHandler*>(filter)->Read(buf, size, offset);
-}
-
-int fill_stat_by_filename(const char *fs_path, struct stat *st) {
+int ConvolverFilesystem::StatByFilename(const char *fs_path, struct stat *st) {
FileHandler *handler = open_files_.FindAndPin(fs_path);
if (handler == 0)
return -1;
@@ -440,16 +435,13 @@ int fill_stat_by_filename(const char *fs_path, struct stat *st) {
open_files_.Unpin(fs_path);
return result;
}
-int fill_fstat_file(struct filter_object_t *filter, struct stat *st) {
- return reinterpret_cast<FileHandler*>(filter)->Stat(st);
-}
-int close_filter(const char *fs_path, struct filter_object_t *filter) {
+void ConvolverFilesystem::Close(const char *fs_path) {
open_files_.Unpin(fs_path);
- // TODO close file.
- return 0;
}
-void initialize_convolver_filter(const char *zita_config_dir) {
+ConvolverFilesystem::ConvolverFilesystem(const char *zita_config_dir,
+ int cache_size)
+ : open_files_(cache_size) {
global_zita_config_dir = zita_config_dir;
}
View
20 file-handler-cache.cc
@@ -23,13 +23,8 @@
#include "file-handler.h"
#include "file-handler-cache.h"
-struct FileHandlerCache::Entry {
- Entry(FileHandler *h) : handler(h), references(0) {}
- ~Entry() { delete handler; }
-
- FileHandler *const handler;
- int references;
-};
+FileHandlerCache::Entry::Entry(const std::string &k, FileHandler *h)
+ : key(k), handler(h) {}
FileHandler *FileHandlerCache::InsertPinned(const std::string &key,
FileHandler *handler) {
@@ -37,7 +32,7 @@ FileHandler *FileHandlerCache::InsertPinned(const std::string &key,
CacheMap::iterator ins
= cache_.insert(std::make_pair(key, (Entry*)NULL)).first;
if (ins->second == NULL) { // new entry
- ins->second = new Entry(handler);
+ ins->second = new Entry(key, handler);
} else {
delete handler;
}
@@ -64,10 +59,19 @@ void FileHandlerCache::Unpin(const std::string &key) {
--found->second->references;
}
+void FileHandlerCache::GetStats(std::vector<const Entry *> *entries) {
+ boost::lock_guard<boost::mutex> l(mutex_);
+ for (CacheMap::iterator it = cache_.begin(); it != cache_.end(); ++it) {
+ ++it->second->references;
+ entries->push_back(it->second);
+ }
+}
+
void FileHandlerCache::CleanupUnreferenced() {
for (CacheMap::iterator it = cache_.begin(); it != cache_.end(); ++it) {
if (it->second->references == 0) {
fprintf(stderr, "cleanup %s\n", it->first.c_str());
+ delete it->second->handler;
delete it->second;
cache_.erase(it);
}
View
17 file-handler-cache.h
@@ -18,6 +18,7 @@
#define _FUSE_CONVOLVER_FILE_HANDLER_CACHE_
#include <map>
+#include <vector>
#include <string>
#include <boost/thread/mutex.hpp>
@@ -31,6 +32,14 @@ class FileHandler;
// This container is thread-safe.
class FileHandlerCache {
public:
+ // Cache entry.
+ struct Entry {
+ Entry(const std::string &, FileHandler *);
+ const std::string key;
+ FileHandler *const handler;
+ int references;
+ time_t last_used;
+ };
FileHandlerCache(int max_size) : max_size_(max_size) {}
// Insert a new object under the given key.
@@ -46,9 +55,13 @@ class FileHandlerCache {
// Unpin object. If the last object is unpinned, the PinnedMap may decide
// to delete it later (though typically will keep it around for a while).
void Unpin(const std::string &key);
-
+
+ // Get a vector of the current entries in this cache. All entries are
+ // pinned and need to be Unpin()-ed by the user.
+ typedef std::vector<const Entry *> EntryList;
+ void GetStats(EntryList *entries);
+
private:
- struct Entry;
typedef std::map<std::string, Entry*> CacheMap;
void CleanupUnreferenced();
View
7 file-handler.h
@@ -14,12 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "filter-interface.h"
+#ifndef _FUSE_CONVOLVER_FILE_HANDLER_H
+#define _FUSE_CONVOLVER_FILE_HANDLER_H
-class FileHandler : public filter_object_t {
+class FileHandler {
public:
// Returns bytes read or a negative value indicating a negative errno.
virtual int Read(char *buf, size_t size, off_t offset) = 0;
virtual int Stat(struct stat *st) = 0;
virtual ~FileHandler() {}
};
+
+#endif // _FUSE_CONVOLVER_FILE_HANDLER_H
View
55 filter-interface.h
@@ -1,55 +0,0 @@
-// -*- c++ -*-
-// Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
-//
-// This program 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 of the License, or
-// (at your option) any later version.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-// Simple interface to hook the (pure C) fuse-convolve code into some
-// implementation of the filter (which we choose to do with C++).
-
-#ifndef _FUSE_CONVOLVER_FILTER_INTERFACE_H
-#define _FUSE_CONVOLVER_FILTER_INTERFACE_H
-#include <unistd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct filter_object_t {};
-
-// Initialize convolver filters
-void initialize_convolver_filter(const char *zita_config);
-
-// Create a new filter given the open filedescriptor and the path. Returns
-// that filter in an opaque filter_object_t*
-struct filter_object_t *create_filter(const char *fs_path,
- const char *underlying_path);
-
-// Read from the given filter at the file-offset "offset, up to "size" bytes
-// into "buffer". Returns number of bytes read or a negative errno value.
-int read_from_filter(struct filter_object_t *filter,
- char *buffer, size_t size, off_t offset);
-
-// Return dynamic size of file.
-int fill_fstat_file(struct filter_object_t *filter, struct stat *st);
-int fill_stat_by_filename(const char *fs_path, struct stat *st);
-
-// At the end of the operation, close filter. Return 0 on success or negative
-// errno value on failure.
-int close_filter(const char *path, struct filter_object_t *filter);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif /* __cplusplus */
-
-#endif // _FUSE_CONVOLVER_FILTER_INTERFACE_H
View
65 fuse-convolve.c → fuse-convolve.cc
@@ -34,13 +34,11 @@
#include <limits.h>
#include <stdlib.h>
-#include "filter-interface.h"
+#include "convolver-filesystem.h"
+#include "status-server.h"
-// Configuration for fuse convolver filesystem.
-static struct {
- const char *config_dir;
- const char *orig_dir;
-} context;
+ConvolverFilesystem *convolver_fs = NULL;
+const char *orig_dir;
static int has_suffix_string (const char *str, const char *suffix) {
if (!str || !suffix)
@@ -61,7 +59,7 @@ static char *concat_path(char *buf, const char *a, const char *b) {
// Given a relative path from the root of the mounted file-system, get the
// original file from the source filesystem.
static const char *assemble_orig_path(char *buf, const char *path) {
- char *result = concat_path(buf, context.orig_dir, path);
+ char *result = concat_path(buf, orig_dir, path);
static const char magic_ogg_rewrite[] = ".ogg.fuse.flac";
if (has_suffix_string(result, magic_ogg_rewrite)) {
*(result + strlen(result) - strlen(".fuse.flac")) = '\0';
@@ -74,7 +72,7 @@ static const char *assemble_orig_path(char *buf, const char *path) {
static int fuseconv_getattr(const char *path, struct stat *stbuf) {
// If this is a currently open filename, we might be able to output a better
// estimate.
- int result = fill_stat_by_filename(path, stbuf);
+ int result = convolver_fs->StatByFilename(path, stbuf);
if (result == 0) return result;
char path_buf[PATH_MAX];
@@ -138,11 +136,11 @@ static int fuseconv_open(const char *path, struct fuse_file_info *fi) {
fi->direct_io = 1;
// The file-handle has the neat property to be 64 bit - so we can actually
- // store a pointer to our filter object in there :)
+ // store a pointer to our filte robject in there :)
// (Yay, someone was thinking while developing that API).
char path_buf[PATH_MAX];
const char *orig_path = assemble_orig_path(path_buf, path);
- struct filter_object_t* handler = create_filter(path, orig_path);
+ FileHandler * handler = convolver_fs->CreateHandler(path, orig_path);
if (handler == NULL)
return -errno;
fi->fh = (uint64_t) handler;
@@ -151,34 +149,20 @@ static int fuseconv_open(const char *path, struct fuse_file_info *fi) {
static int fuseconv_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
- return read_from_filter((struct filter_object_t*)fi->fh,
- buf, size, offset);
+ return reinterpret_cast<FileHandler *>(fi->fh)->Read(buf, size, offset);
}
static int fuseconv_release(const char *path, struct fuse_file_info *fi) {
fprintf(stderr, "===== close('%s') ==]\n", path);
- return close_filter(path, (struct filter_object_t*) fi->fh);
+ convolver_fs->Close(path);
+ return 0;
}
static int fuseconv_fgetattr(const char *path, struct stat *result,
struct fuse_file_info *fi) {
- return fill_fstat_file((struct filter_object_t*) fi->fh, result);
+ return reinterpret_cast<FileHandler *>(fi->fh)->Stat(result);
}
-static struct fuse_operations fuseconv_operations = {
- // Basic operations to make navigation work.
- .readdir = fuseconv_readdir,
- .readlink = fuseconv_readlink,
-
- // open() and close() file.
- .open = fuseconv_open,
- .release = fuseconv_release,
-
- // Actual workhorse: reading a file and returning predicted file-size
- .read = fuseconv_read,
- .fgetattr = fuseconv_fgetattr,
- .getattr = fuseconv_getattr,
-};
static int usage(const char *prog) {
fprintf(stderr, "usage: %s <config-dir> <original-dir> <mount-point>\n",
@@ -192,11 +176,30 @@ int main(int argc, char *argv[]) {
}
// First, let's extract our configuration.
- context.config_dir = argv[1];
- context.orig_dir = argv[2];
+ const char *config_dir = argv[1];
+ orig_dir = argv[2];
argc -=2;
argv += 2;
- initialize_convolver_filter(context.config_dir);
+ convolver_fs = new ConvolverFilesystem(config_dir, 5);
+
+ StatusServer *statusz = new StatusServer(convolver_fs->handler_cache());
+ statusz->Start(9999);
+
+ struct fuse_operations fuseconv_operations;
+ memset(&fuseconv_operations, 0, sizeof(fuseconv_operations));
+
+ // Basic operations to make navigation work.
+ fuseconv_operations.readdir = fuseconv_readdir;
+ fuseconv_operations.readlink = fuseconv_readlink;
+
+ // open() and close() file.
+ fuseconv_operations.open = fuseconv_open;
+ fuseconv_operations.release = fuseconv_release;
+
+ // Actual workhorse: reading a file and returning predicted file-size
+ fuseconv_operations.read = fuseconv_read;
+ fuseconv_operations.fgetattr = fuseconv_fgetattr;
+ fuseconv_operations.getattr = fuseconv_getattr;
// Lazy: let the rest handle by fuse provided main.
return fuse_main(argc, argv, &fuseconv_operations, NULL);
View
70 status-server.cc
@@ -0,0 +1,70 @@
+// Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdarg.h>
+
+#include <microhttpd.h>
+
+#include "status-server.h"
+#include "file-handler-cache.h"
+
+int StatusServer::HandleHttp(void* user_argument,
+ struct MHD_Connection *connection,
+ const char *url, const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_size,
+ void**) {
+ StatusServer* server = (StatusServer*) user_argument;
+ struct MHD_Response *response;
+ int ret;
+ const char *buffer;
+ size_t size;
+ server->CreatePage(&buffer, &size);
+ response = MHD_create_response_from_data(size, (void*) buffer,
+ MHD_NO, MHD_NO);
+ ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+ MHD_destroy_response(response);
+ return ret;
+}
+
+StatusServer::StatusServer(FileHandlerCache *cache)
+ : cache_(cache), daemon_(NULL) {
+}
+
+bool StatusServer::Start(int port) {
+ daemon_ = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL,
+ &HandleHttp, this,
+ MHD_OPTION_END);
+ return daemon_ != NULL;
+}
+
+StatusServer::~StatusServer() {
+ if (daemon_)
+ MHD_stop_daemon(daemon_);
+}
+
+
+void StatusServer::CreatePage(const char **buffer, size_t *size) {
+ current_page_ = "Hello World";
+ *buffer = current_page_.data();
+ *size = current_page_.size();
+}
View
42 status-server.h
@@ -0,0 +1,42 @@
+// -*- c++ -*-
+// Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <string>
+
+class FileHandlerCache;
+struct MHD_Daemon;
+struct MHD_Connection;
+
+class StatusServer {
+public:
+ // Does not take over ownership of cache.
+ StatusServer(FileHandlerCache *cache);
+ bool Start(int port);
+
+ ~StatusServer();
+
+private:
+ static int HandleHttp(void* user_argument,
+ struct MHD_Connection *,
+ const char *, const char *, const char *,
+ const char *, size_t *, void **);
+
+ void CreatePage(const char **buffer, size_t *size);
+
+ FileHandlerCache *const cache_;
+ struct MHD_Daemon *daemon_;
+ std::string current_page_;
+};
Please sign in to comment.
Something went wrong with that request. Please try again.